Агрегация против наследования в C # или альтернативы - PullRequest
2 голосов
/ 25 августа 2010

Допустим, у меня есть следующие два класса:

public class Person
{
    public string Name { get; set; }
    public string Address { get; set; }
}
public class Customer: Person
{
    public string CustomerNumber { get; set; }
    public string PaymentTerms { get; set; }
}

Теперь, если у меня есть человек, которого я хочу сделать клиентом, у меня, насколько мне известно, есть три варианта, и я надеюсь на совет, который является лучшим и по любым другим вариантам, возможно, используя новый динамический материал в C # 4.

Я могу добавить конструктор или свойство в Customer, которое принимает Person и присваивает значения базовому классу, например,

public Customer(Person person)
{
    base.Name = person.Name;
    base.Address = person.Address;
}

или я могу реализовать неупорядоченный набор средств доступа следующим образом:

public Person Person
{
    set
    {
        Name = value.Name;
        Address = value.Address;
    }
}

или я могу объединить Person в Customer следующим образом:

public class Customer
{
    public Person Person { get; set; }
    public string CustomerNumber { get; set; }
    public string PaymentTerms { get; set; }
}

Последнее для меня самое лучшее, за исключением того, что всегда приходится, например, доступ Customer.Person.Name, а не просто Customer.Name.

Ответы [ 2 ]

5 голосов
/ 25 августа 2010

Я бы лично пошел на композицию, да (ваш последний вариант). Обратите внимание, что вы всегда можете предоставить «вспомогательные свойства»:

public string Name { get { return Person.Name; } }

Действительно, вы можете сделать это для всех свойств, которые вам нужны, и никогда не открывать свойство Person для внешнего мира.

С другой стороны, наследование является полезным, если вы хотите иметь возможность обрабатывать Customer как Person - передавая его, например, методам с параметром Person. Хотя я обычно выполняю такие вещи с помощью интерфейсов; вы можете иметь интерфейс IPerson, реализованный как Customer, так и Person. Наследование представляет все виды проектных решений, которые просто не приходят (или намного проще), когда вы не получаете наследство.

4 голосов
/ 25 августа 2010

Я бы либо использовал конструктор, либо, может быть, фабричный метод, например

public static Customer CreateFromPerson(Person person)
{
    return new Customer(){ Name = person.Name }//etc...
}

Мне не нравится сеттер, так как вы на самом деле не устанавливаете «Персона» для клиента, иМне не нравится последний вариант, потому что он приводит к нарушению Закона Деметры (LOD) при доступе к человеку через клиента (customer.person.name и т. Д.).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...