Chris
Chris

Reputation: 1078

Trying to avoid multiple sub-types in a class structure

I have two abstract classes Business & Person. The problem is that I have a customer type that can be either a Business or a Person. Is there a way to model this so that I don't have both CustomerBusiness and CustomerPerson classes? Multiple inheritance isn't an option as this is C#. I've been looking at this so long I can't see the forest for the trees.

public abstract class Business {
  public string Name { get; set; }
}

public abstract class Person {
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public string MiddleName { get; set; }
  public DateTime? BirthDate { get; set; }
  public string Comments { get; set; }
}

public class CustomerBusiness : Business, CustomerRoles {
  public bool BillTo { get; set; }
  public bool ShipTo { get; set; }
  public bool DeliverTo { get; set; }
  public EntityType Type { get; set; }
}

public class CustomerPerson : Person, CustomerRoles {
  public bool BillTo { get; set; }
  public bool ShipTo { get; set; }
  public bool DeliverTo { get; set; }
  public EntityType Type { get; set; }
} 

public interface CustomerRoles {
  bool BillTo { get; set; }
  bool ShipTo { get; set; }
  bool DeliverTo { get; set; }
}

Upvotes: 1

Views: 83

Answers (2)

Ed Chapel
Ed Chapel

Reputation: 6932

You could prefer composition over inheritance having the Business and Person classes "have a" ICustomerRoles instead of "is a" ICustomerRoles.

public class Business
{
    public string Name { get; set; }

    public ICustomerRoles CustomerRoles { get; set; }
}

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string MiddleName { get; set; }
    public DateTime? BirthDate { get; set; }
    public string Comments { get; set; }

    public ICustomerRoles CustomerRoles { get; set; }
}

Upvotes: 2

Tobsey
Tobsey

Reputation: 3400

I would say that you have your heirarchy in the wrong order. Customer should be a base class and then Business and Person should be implementations of the Customer class. I'm sure there are more attributes of a Customer that are common to all types of Customer other than those in the CustomerRoles interface.

I would have thought there would be things like CustomerCode etc. Also you could state that all customers have a Name property, and it's up to the getter in each sub class to return the appropriate value. As in a Business would have a single property called Name, whereas a person would have each of FirstName, MiddleName, Surname and also a Name property that would concatenate these in some way.

Upvotes: 1

Related Questions