Крейг Ларман обсуждал это, когда представил GRASP в разделе «Применение UML и шаблонов для объектно-ориентированного анализа, проектирования и итеративной разработки» (2004):
В некоторых ситуациях решение, предложенное экспертом, нежелательно, как правило, из-за проблем сцепления и сплоченности (эти принципы обсуждаются далее в этой главе).
Например, кто должен нести ответственность за сохранение продажи в базе данных? Конечно, большая часть информации, которая будет сохранена, находится в объекте Sale, и, таким образом, эксперт может утверждать, что ответственность лежит на классе Sale. И, благодаря логическому расширению этого решения, каждый класс будет иметь свои собственные службы для сохранения себя в базе данных. Но действия по этим причинам приводят к проблемам сплоченности, связи и дублирования. Например, класс Sale теперь должен содержать логику, связанную с обработкой базы данных, например, связанную с SQL и JDBC (Java Database Connectivity). Класс больше не фокусируется только на чистой логике приложения «быть продажей». Теперь другие виды ответственности снижают его сплоченность. Этот класс должен быть связан со службами технической базы данных другой подсистемы, такими как службы JDBC, а не просто связан с другими объектами на уровне домена программных объектов, поэтому его связь увеличивается. И вполне вероятно, что подобная логика базы данных будет дублирована во многих постоянных классах.
Все эти проблемы указывают на нарушение основного архитектурного принципа: дизайн для разделения основных системных проблем. Храните логику приложения в одном месте (например, объекты программного обеспечения домена), сохраняйте логику базы данных в другом месте (например, в отдельной подсистеме служб персистентности) и т. Д., А не смешивайте различные системные проблемы в одном и том же компоненте. [11]
Поддержка разделения основных проблем улучшает сцепление и сплоченность конструкции. Таким образом, даже несмотря на то, что с помощью Expert мы могли найти какое-то оправдание для того, чтобы возложить ответственность за службы баз данных на класс Sale, по другим причинам (обычно сплоченности и связности) у нас получился бы плохой дизайн.
Таким образом, ПСП, как правило, превосходит Информационного Эксперта.
Однако принцип инверсии зависимости может хорошо сочетаться с экспертом. Аргументом здесь будет то, что у Клиента не должно быть зависимости CustomerDTO (от общего к подробному), а наоборот. Это будет означать, что CustomerDTO является экспертом и должен знать, как построить себя, учитывая клиента:
CustomerDTO dto = new CustomerDTO(bob);
Если у вас аллергия на новые, вы можете зайти в состояние покоя:
CustomerDTO dto = CustomerDTO.buildFor(bob);
Или, если вы ненавидите оба, мы возвращаемся к AbstractFactory:
public abstract class DTOFactory<D, E> {
public abstract D createDTO(E entity);
}
public class CustomerDTOFactory extends DTOFactory<CustomerDTO, Customer> {
@Override
public CustomerDTO createDTO(Customer entity) {
return new CustomerDTO(entity);
}
}