質問: 下記の質問に関連します。 特定のパッケージやjarに対してのみ公開する可視性設定は可能か? DDDにおける集約は、その内部状態(集約に含まれるエンティティやEnum型フィールド等)は公開せず、ユースケース上必要となるメソッドのみを外部に公開します。 しかし、永続化層ではその内部状態を調べてデータベースのテーブルにマッピングしなければなりません。 永続化のために全ての内部状態を`public`メソッドで公開するのは避けたいので、何らかの制約のもとで内部状態を取得する仕組みを求めています。 目標とする隠蔽のレベルですが、最低限、「うっかり呼んでしまった」を防げれば良いと考えています。 `public`メソッドになっていると、その集約オブジェクトの設計(どの`public`メソッドが“真の”`public`なのか)に関する知識が無ければ、「うっかり」呼んでしまいますが、何か特別な手続きを踏む必要性を取り入れれば、「うっかり」は防げます。 この条件下では、どのようなクラス設計が良いでしょうか。 何か応用可能なデザインパターンなどありませんか?
回答: クラス設計の問題ではなくって、一般的に java のコードに置いてどうやって spec (仕様) プロジェクトと impl プロジェクトを分離・ビルドするべきなのか問題なのではないか、と考えています。 一般的に、 spec プロジェクトと impl プロジェクトを分離して、各 impl プロジェクトはその他の spec プロジェクトにのみ依存するようにします。すると、 spec クラスのもののみがその他の場所から利用されます。そして、各 impl クラスは別々にビルドします。C言語で言う所のヘッダとソースの関係が近いと思います。 実際に動作するもの (war とか) を作る時には、別々にビルドしていたこいつらをおまとめするようなビルドを用意します。 (2016/10/22) 説明が色々と足りていなかったようなので、追記します。 @tag1216 さんの回答のように、この回答でのべたプロジェクトの分割は、「インターフェースクラスと実装クラスの分離」を想定しています。ただ、これだけだと今回問題になっている、「開発者が不用意に実装クラスを触らない」は実げんできないと思っています。 具体例を挙げます。永続層用のプロジェクトがあったとして、それが`dao.jar`でビルドされているとします。そして、この dao プロジェクトの中で、例えばインターフェースと実装クラスを分離したとします。 `dao.jar` の中には両方が入っている状態になります。 アプリケーションロジックを記述するプロジェクトを `application.jar` だとします。 `dao.jar` の中のインターフェースを利用する必要があるので、 application プロジェクトは、 dao プロジェクトを依存関係に持つ必要があります。すると、欲しくなかった実装クラスまでついてきます。開発者が、ついうっかり実装ロジックでしか使われる想定しかしていない実装クラスを使ってしまう懸念点は払拭できません。 なので、 dao プロジェクトを分割します。インターフェースのみを持つようなプロジェクト (これを自分は spec と言っていました)と、 spec に依存を持つような実装プロジェクト(これを自分は impl と言っていました)です。 そして、 application プロジェクトからは dao-spec プロジェクトのみを依存関係に追加します。