"Является ли" против "Имеет": какой из них лучше? - PullRequest
8 голосов
/ 04 ноября 2008

Портфолио А → Фонд 1

Портфель А → Фонд 2

Портфель А → Фонд 3

Я не могу сформулировать свое предложение, не используя is / has. Но между 1 и 2

1) имеет:

class PortfolioA
{
    List<Fund> obj;
}

2) является:

class PortfolioA : List<Fund>
{

}

Какой из них, по вашему мнению, лучше с точки зрения расширяемости, удобства использования? Я все еще могу получить доступ к своим средствам в любом случае, хотя и с небольшим синтаксическим изменением.

Ответы [ 8 ]

17 голосов
/ 05 ноября 2008

Я голосую с другими людьми, которые говорят, что HAS-A лучше в этом случае. Вы спрашиваете в комментарии:

когда я говорю, что портфолио это просто сбор средств, с несколькими атрибуты своего собственного, как TotalPortfolio и т. Д., Делает это принципиально не стать "is-a"?

Я так не думаю. Если вы скажете Portfolio IS-A List<Fund>, как насчет других свойств Портфеля? Конечно, вы можете добавить свойства в этот класс, но точно ли моделировать эти свойства как свойства Списка? Потому что это в основном то, что ты делаешь.

А что, если требуется, чтобы портфолио поддерживало более одного List<Fund>? Например, у вас может быть один Список, который показывает текущий баланс инвестиций, но другой Список, который показывает, как инвестируются новые вклады. А как насчет того, когда средства прекращаются, и для их замены используется новый набор средств? Историческую информацию полезно отслеживать, а также текущее распределение средств.

Дело в том, что все эти свойства не являются правильно свойствами Списка, хотя они могут быть свойствами Портфеля.

8 голосов
/ 04 ноября 2008

не «всегда» одобряют композицию или наследование или наоборот; они имеют различную семантику (значения); внимательно посмотрите на значения, а затем решите - не имеет значения, является ли одно «легче», чем другое, для долговечности важно, чтобы вы правильно поняли семантику

помните: is-a = тип, has-a = сдерживание

поэтому в данном случае портфель логически представляет собой совокупность средств; портфель сам по себе является , а не типом фонда , поэтому состав является правильным соотношением

РЕДАКТИРОВАТЬ: Первоначально я неправильно понял вопрос, но ответ остается тем же. Портфолио - это не тип списка, это отдельная сущность со своими собственными свойствами. Например, портфель - это совокупность финансовых инструментов с первоначальными инвестиционными затратами, общей текущей стоимостью, историей значений во времени и т. Д., В то время как список представляет собой простую коллекцию объектов. Портфель - это «тип списка» только в самом абстрактном смысле.

РЕДАКТИРОВАТЬ 2: подумайте об определении портфеля - он, без исключения, характеризуется как набор вещей. Портфолио художника - это коллекция его произведений, портфолио веб-дизайнера - это коллекция их веб-сайтов, портфолио инвестора состоит из всех принадлежащих им финансовых инструментов и так далее. Очевидно, что нам нужен список (или какой-то другой) для представления портфеля, но это никоим образом не означает, что портфель - это тип списка!

предположим, что мы решили позволить Портфолио наследовать от List. Это работает до тех пор, пока мы не добавим Запас, Связку или Драгоценный Металл в Портфолио, а затем неожиданно неправильное наследование больше не будет работать. Или предположим, что нас просят смоделировать, скажем, портфель Билла Гейтса и найти, что List не хватит памяти ;-) Более реалистично, после будущего рефакторинга мы, вероятно, обнаружим, что мы должны наследовать от базового класса, такого как Asset, но если мы уже унаследовали от List, тогда мы не можем.

Резюме: различайте структуры данных, которые мы выбираем для представления концепции, и семантику (иерархию типов) самой концепции.

7 голосов
/ 04 ноября 2008

Первый, потому что вы должны стараться отдавать предпочтение композиции, а не наследованию.

4 голосов
/ 04 ноября 2008

Это зависит от того, определяет ли бизнес Портфолио как группу (и только группу) фондов. Если есть даже отдаленная вероятность того, что он может содержать другие объекты, например, «свойство», то перейдите к варианту 1. Перейдите к варианту 2, если существует тесная связь между группой фондов и концепцией портфеля.

Поскольку расширяемость и полезность 1 имеет небольшое преимущество перед 2. Я действительно не согласен с концепцией, что вы всегда должны отдавать предпочтение одному над другим. Это действительно зависит от того, что представляют собой реальные концепции реальной жизни. Помните, вы всегда можете ^ рефакторировать.

^ Для большинства случаев всегда. Если оно открыто, то, очевидно, нет.

2 голосов
/ 04 ноября 2008

Первый, потому что он "состоит из" . => Композиция

2 голосов
/ 04 ноября 2008

Я бы выбрал вариант (1) - состав, поскольку у вас могут появиться атрибуты, специфичные для портфеля, а не для фондов.

1 голос
/ 05 ноября 2008

Я буду отличаться от того, что кажется общим мнением. В этом случае я думаю, что портфель - это всего лишь набор средств ... Используя наследование, вы разрешаете использовать несколько конструкторов, как в

public Portfolio(CLient client) {};
public Portfolio(Branch branch, bool Active, decimal valueThreshold)
{
    // code to populate collection with all active portfolios at the specified branch whose total vlaue exceeds specified threshold 
}

и индексаторы как в:

public Fund this[int fundId] { get { return this.fundList[fundId]; } }

и т.д.. и т.д.

если вы хотите иметь возможность обрабатывать переменные типа Portfolio как совокупность средств со связанным синтаксисом, то это лучший подход.

Portfolio BobsPortfolio = new Portfolio(Bob); 

foreach (Fund fund in BobsPortfolio)
{
    fund.SendStatement();
}

или тому подобное

0 голосов
/ 08 августа 2017

корабль связи IS-A представляет наследования, а корабль связи HAS-A представляет композицию. Для вышеупомянутого сценария мы предпочитаем композицию, поскольку у PortfolioA есть список, а это не тип списка. Наследование используется, когда Портфолио A является типом Списка, но здесь это не так. Следовательно, для этого сценария мы должны предпочесть композицию.

...