(たとえば、循環参照が含まれている場合)[...]これを行うために、複数のオブジェクトを作成できるコンストラクターを持つことができます。次に、プログラマーは単一のコンストラクターにすべてのコードを配置して、オブジェクトo1、...、onが作成されたら、
オブジェクト間の循環依存関係?次に、答えは「コンストラクタを(ただ)使用しないでください」です。これは、循環メソッド呼び出しは意味をなさないためです。代わりに、これは一部のFactoryメソッドの古典的なシナリオです。
これは、(PHPでの)ばかげているが一般的な考え方を示す例です。Sprocket
関連付けられたなしではを作成できませんWidget
。各オブジェクトは、使用可能になったときに他のオブジェクトへの参照を持っています。
class Widget {
protected $sprocket = null;
public function getSprocket(){ return $this->sprocket; }
protected function __construct(){
// Constructor cannot be called from outside, not public
// Initialize self, to a limited degree
}
public static function create(Sprocket $partner=null){
$me = new Widget(); // Can call constructor from same class
// Here we can make all sorts of changes and additions and other
// objects, wiring them all together, before revealing the result
// to the outside world.
if($partner !== null){
$me->sprocket = $partner;
}else{
$me->sprocket = Sprocket::create($me);
}
return $me;
}
}
/*
* Practically identical to Widget, just with some renaming
*/
class Sprocket {
protected $widget = null;
public function getWidget(){ return $this->widget; }
protected function __construct(){ }
public static function create(Widget $partner=null){
$me = new Sprocket();
if($partner !== null){
$me->widget = $partner;
}else{
$me->widget = Widget::create($me);
}
return $me;
}
}
/*
$mw = new Widget(); // NOT ALLOWED! Constructor not public
*/
$w = Widget::create(); // OK to call
$s = $w->getSprocket();
$w2 = $s->getWidget();
assert($w == $w2);
PHP 5.2でこれを実際に行う必要がある場合は、単にコンストラクターを公開したままにし、使用しないように伝えます。代わりに私はmakeWidgetWithSprocket()
関数を持っているでしょう。言語がJavaの場合、パッケージレベルの可視性コントロールを使用して、間違いをさらに防ぎます。
追加の読み:
factory
パターンです。