Craig Larman は、UML とパターンをオブジェクト指向分析と設計と反復開発に適用する (2004) で GRASP を紹介したときに、これについて説明しました。
場合によっては、Expert によって提案された解決策が望ましくないことがあります。通常は、結合と結束の問題が原因です (これらの原則については、この章の後半で説明します)。
たとえば、Sale をデータベースに保存する責任は誰にあるでしょうか。確かに、保存する情報の多くは Sale オブジェクトにあるため、Expert は責任は Sale クラスにあると主張できます。そして、この決定の論理的な拡張により、各クラスはデータベースに自身を保存するための独自のサービスを持つことになります。しかし、その推論に基づいて行動すると、結束、結合、および重複の問題が発生します。たとえば、Sale クラスには、SQL や JDBC (Java Database Connectivity) に関連するものなど、データベース処理に関連するロジックを含める必要があります。このクラスは、もはや「販売であること」という純粋なアプリケーション ロジックだけに焦点を当てているわけではありません。現在、他の種類の責任はその結束を低下させます。クラスは、JDBC サービスなど、別のサブシステムの技術データベース サービスに結合する必要があります。ソフトウェアオブジェクトのドメイン層で他のオブジェクトに結合されるだけでなく、その結合が増加します。また、同様のデータベース ロジックが多くの永続クラスで複製される可能性があります。
これらの問題はすべて、基本的なアーキテクチャの原則、つまり主要なシステムの問題を分離するための設計に違反していることを示しています。アプリケーション ロジックを 1 つの場所 (ドメイン ソフトウェア オブジェクトなど) に保持し、データベース ロジックを別の場所 (別の永続化サービス サブシステムなど) に保持するなどして、同じコンポーネント内で異なるシステムの問題を混在させるのではなく、[11]
主要な関心事の分離をサポートすることで、設計における結合と結束が向上します。したがって、Expert によって、データベース サービスの責任を Sale クラスに置く正当な理由を見つけることができたとしても、他の理由 (通常は結束と結合) により、設計がうまくいかないことになります。
したがって、SRP は一般的に Information Expert に勝ります。
ただし、依存性逆転の原則はエキスパートとうまく組み合わせることができます。ここでの議論は、Customer が CustomerDTO (一般から詳細へ) に依存するべきではなく、その逆であるということです。これは、CustomerDTO が Expert であり、Customer を指定してそれ自体を構築する方法を知っている必要があることを意味します。
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);
}
}