Каковы преимущества использования композиции перед наследованием, когда нам нужно добавить поведение в List <>? - PullRequest
5 голосов
/ 06 апреля 2010

Каковы преимущества / недостатки варианта 2 над 1 в этом примере?

Вариант 1 (Наследование):

public class SalesList : List<Sales>
{
    //methods that add extra behavior List<Sales>
}

Вариант 2 (Композиция):

public class SalesList 
{
    private List<Sales> _list;
    //methods that add extra behavior to List<Sales>
}

Ответы [ 5 ]

2 голосов
/ 12 октября 2012

Наследование позволяет нам сформировать иерархию классов, такую, что родительский набор * super * и все его дочерние элементы * sub * set, что позволяет обобщать, специализовать применить принцип замещения

2 голосов
/ 06 апреля 2010

Основным недостатком Composition является то, что вам нужно обернуть (продублировать) все открытые методы частного списка, если вам нужно представить один и тот же интерфейс, в Inheritance у вас есть все они уже доступны, но вы не можете переопределить любой из них, который был сделан не перезаписываемым (в C # это означает, что метод должен быть помечен как «виртуальный», в Java его нельзя пометить как «окончательный»).

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

2 голосов
/ 06 апреля 2010

Преимущество варианта 2 - ловкость. Используя композицию, вы можете выбрать, какие части интерфейса списка вы открываете.

Представьте себе, что позже вы решите больше не выходить из другого класса. К настоящему времени некоторые пользователи вашей библиотеки будут использовать методы, предоставляемые List, поэтому вам нужно реализовать все методы list самостоятельно: add / addAll / Содержит / retainAll. Это целый ряд методов для простого списка продаж.

По сути, это сводится к тому, что «когда сомневаешься, оставь это», о чем говорит Джошуа Блох в Дизайн API Bumper-Sticker . Каждый аспект API должен быть как можно меньше, но не меньше. Вы всегда можете добавить вещи позже, но вы не можете их убрать.

1 голос
/ 06 апреля 2010

Вариант 1
- Преимущества - все преимущества наследования и повторного использования
- Недостатки - код теперь сигнализирует потребителям, что он взят из Списка. Если это необходимо изменить позднее, это повлияет на всех связанных потребителей.

Вариант 2
- Преимущества - детали реализации о хранении данных о продажах абстрагированы от потребителя. Таким образом, если реализация должна измениться (например, словарь), потребитель класса будет защищен от этих изменений.
- Недостатки - класс SalesList теперь должен будет предоставить дополнительные методы для получения и / или установки внутреннего объекта _list. это дополнительный код, который необходимо сохранить. Кроме того, если внутренняя реализация изменяется, вам нужно позаботиться о том, чтобы поддерживать прежнее поведение ...

Просто несколько мыслей, которые приходят на ум.

НТН.

0 голосов
/ 16 апреля 2011

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

В композиции это зависит от того, какой тип объекта вы передаете в сеттер, и будет вести себя в соответствии с этим. Это даст больше гибкости при реализации

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