集約ルート内のエンティティを集約ルートを経由せずに変更できないようにする必要がある場合、制御する必要がある唯一の手段は、エンティティをプライベートまたは保護されたメンバーにして、エンティティへのすべての変更が集約を経由するようにすることです。
class RootEntity {
private $_otherEntity;
public function DoSomething() {
$this->_otherEntity->DoSomething();
}
public function setOtherEntity( OtherEntity $entity ) {
$this->_otherEntity = $entity;
}
}
誰かがいつでもできる:
$otherEntity = new OtherEntity();
$otherEntity->DoSomethingElse();
$rootEntity->setOtherEntity($otherEntity);
ただし、魔法の __call() メソッドを使用して、構築中以外の場所で _otherEntity の設定を禁止できると思います。これはトータルハックのカテゴリに分類されます:)
class RootEntity {
private $_otherEntity;
private $_isLoaded = false;
public function __call( $method, $args ) {
$factoryMethod = 'FactoryOnly_'.$method;
if( !$this->_isLoaded && method_exists($this,$factoryMethod) {
call_user_func_array(array($this,$factoryMethod),$args
}
}
public function IsLoaded() {
$this->_isLoaded = true;
}
protected function FactoryOnly_setOtherEntity( OtherEntity $otherEntity ) {
$this->_otherEntity = $otherEntity;
}
}
したがって、そこからオブジェクトをビルドするときに、ファクトリまたはリポジトリから $agg->setOtherEntity($otherEntity) を呼び出すことができます。オブジェクトの作成が完了したら、IsLoaded() を呼び出します。そこから、誰も新しい OtherEntity をクラスに導入できなくなり、集計で公開されているメソッドを使用する必要があります。
それを「良い」答えと言えるかどうかはわかりませんが、集約内のエンティティへのアクセスを本当に制限するために私が考えることができる唯一のことです。
[編集]: また、言及するのを忘れていました...ドキュメントに最も近いのは、phpdoc の @internal があることです:
http://www.phpdoc.org/docs/latest/for-users/tags/internal.html
ただし、IDE のコード補完が変更されるとは思えません。ただし、おそらくパブリック関数/プロパティを作成し、それを phpdoc で「@access private」としてラベル付けして、コード補完に含まれないようにすることができます。