Reputation: 1346
Lets say I have a Customer type, and there's certain information I want to store for all customers. However a customer can be either a Person and an Organisation. In each case I would want to store different types of information on them, and have the ability to act on them in different ways.
I would normally want to deal with just the Customer object, but at certain times depending on situation deal with the more specific type differently (an example might be that when creating an address I want to use Surname and GivenNames from a Person, but the TradingName (but it not populated then OrgName instead) for an Organisation.
I'm torn on how to handle this. The examples/questions I find while searching assume the more specific types have the same properties/methods so can be treated generically.
Do I just have a field for either type in my Customer object and a flag to indicate which has a value (i.e., isPerson()) and check that in my code when I need to. Do I use inheritance and when needed use IsType() type of logic? Or is there some design pattern I'm missing that helps with this type of scenario?
Upvotes: 2
Views: 69
Reputation: 150108
Do I just have a field for either type in my Customer object and a flag to indicate which has a value (i.e., isPerson()) and check that in my code when I need to. Do I use inheritance and when needed use IsType() type of logic?
No, that defeats the purpose of polymorphism.
Define an interface that captures what the two classes have in common, so you can treat them in the same manner when appropriate. There's a good chance that you will also want to create a common base class that implements at least some of that interface, providing for common behavior. You may end up leaving some of the implementation of the interface as abstract methods, that get their concrete implementations from the Person and Organization subclasses.
Bad design
public class Customer
{
public void DoSomethingCustomersDo()
{
if (isPerson())
{
/* Person implementation */
}
else
{
/* Organization implementation */
}
}
}
Better Design
public interface ICustomer
{
void DoSomethingCustomersDo();
}
public abstract class Customer : ICustomer
{
public string SomeSharedProperty { get; set; }
public abstract void DoSomethingCustomersDo();
}
public class Person : Customer
{
public override void DoSomethingCustomersDo()
{
/* Person implementation */
}
}
public class Organization : Customer
{
public override void DoSomethingCustomersDo()
{
/* Organization implementation */
}
}
Upvotes: 5