"Является ли" против "Имеет": какой из них лучше?

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

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

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

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

1) имеет:

class PortfolioA
{
    List<Fund> obj;
}

2) является:

class PortfolioA : List<Fund>
{

}

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

8 ответов

Решение

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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();
}

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

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

Другие вопросы по тегам