Примером класса реализации, приведенного в статье, является ArrayList. Это не часть кода, описывающего бизнес-сущности, это просто широко используемый класс общего назначения.
Это контрастирует с классом Customer, которого они упоминают. Клиент будет классом, который является частью домена, где он описывает сущность, специфичную для бизнеса.
В статье говорится, что вам не следует расширяться от таких служебных классов при создании классов доменов.
Как неправильно использовать наследование - пример 2
Создание класса концепции домена путем наследования от класса реализации является распространенным неправильным использованием наследования. Например, предположим, что мы хотим что-то сделать с определенным сегментом наших клиентов. Легкая и очевидная вещь - это создать подкласс ArrayList, назвать его CustomerGroup и начать кодирование, верно?
Неправильно. Это будут междоменные отношения наследования, и их следует избегать:
1) ArrayList уже является подклассом списка, набор утилит - классом реализации.
2) CustomerGroup - это еще один подкласс - класс домена.
3) Доменные классы должны использовать классы реализации, а не наследовать от них.
Если вам нужно реализовать класс CustomerGroup, он может иметь ArrayList в качестве члена экземпляра, например:
public class CustomerGroup {
private List<Customer> customers = new ArrayList<>();
public List<Customer> getCustomers() {return customers;}
}
но вы бы не сделали сам класс подклассом ArrayList.
Причина в том, что когда вы что-то делаете подклассом, пользователи вашего класса получают всю функциональность суперкласса, даже если это не подходит. Вам на самом деле не нужен класс домена, чтобы увидеть это в действии, просто проверьте исходный код java.util.Properties, который плохо спроектирован и расширяет java.util.Hashtable. Когда вы используете объект Properties, вам доступны методы из Hashtable, даже если они совершенно не нужны и сбивают с толку, а использование методов суперкласса не работает или вызывает проблемы.