15

クラスとオブジェクトを構築するための適切な構造を考え出すのにいくつか問題があります。以下のコードでは、インターフェイスを使用してクラス メソッドを定義していますが、コンストラクターにデータベース接続を渡して、クラスがこの接続を使用できるようにしたいと考えています。以下にコーディングしたように、コンストラクターがクラス内に配置され、メソッドがインターフェイス内に配置されていることは正しいですか?

interface IDataItem
{
    public function saveItem(Item $theItem);
}

class DataItem implements IDataItem
{
    public function __construct(Database $database) 
    { 
        $this->database = $database;
    }

    public function saveItem(Item $item) 
    {       
        //save the item
    }
}

$db = new Database(); //from a database class
$dataItem = new DataItem($db);          
$dataItem->saveItem($anItem);
4

6 に答える 6

22

コンストラクターをインターフェイスに追加することは技術的には可能ですが、コンストラクターは実装クラスの実装の詳細になるため、インターフェイスはコンストラクターを定義しないでください。インターフェイスは、他の共同作業者が呼び出すことができるパブリックAPIを定義するだけです。つまり、特定の実装を強制するべきではありません。

インターフェースにデータベース接続を要求するコンストラクターを配置する場合は、具象クラスをコンストラクター署名の依存関係に制限します。インターフェイスを実装する具体的なクラスが異なる(Webサービスに保存されているため)または追加の(おそらくロガー)依存関係を必要とする場合、インターフェイスでそれを機能させることはできません。

于 2012-11-07T14:06:35.757 に答える
12

個人的には、コンストラクターをインターフェイスに配置する必要はないと思います。使用している実装を認識せずにコンストラクターを呼び出して新しいオブジェクトを作成することは決してないからです。

コードに間違いがあります。インターフェースのメソッドは実装を持つことができません。次のように宣言する必要があります。

interface IDataItem
{
    public function saveItem($theItem);
}
于 2012-11-07T13:50:29.937 に答える
7

これはトピックから少し外れていますが、インターフェイスでコンストラクターを定義すると便利な場合があることを強調していると思います。

クラスを知らなくても、オブジェクトをインスタンス化することができます。以下に簡単な例を示します。

interface Animal
{
    public function __construct($name);
    public function speak();
    public function getName();
}

class Cat implements Animal
{
    protected $name=null;
    public function __construct($name){ $this->name=$name; }
    public function speak(){ echo 'meow'; }
    public function getName(){ return $this->name;}
}

class Dog implements Animal
{
    protected $name=null;
    public function __construct($name){ $this->name=$name; }
    public function speak(){ echo 'woof'; }
    public function getName(){ return $this->name;}
}

$animals=Array(array('name'=>'Felix','type'=>'Cat'),array('name'=>'Fido','type'=>'Dog'));

foreach($animals as $a)
{
    $theAnimal=new $a['type']($a['name']);
    echo '<p>speak, '.$theAnimal->getName().'</p><p>';
    $theAnimal->speak();
    echo '</p>';
}

URLルーティングにこのようなものを使用して、URLをトップレベルのコントローラーに一致させました。

于 2016-06-15T00:36:25.927 に答える
2

インターフェイスは、無関係なクラスがすべて同じメソッドを実装することを強制するための単なる契約です。

クラスを構築するときにクラスを明示的に知る必要があるため、コンストラクターをインターフェースに配置しても意味がありません。インターフェイスを介してコンストラクターを呼び出すことはありません。あなたの現在の解決策は正しいです。

于 2012-11-07T13:49:00.720 に答える
-3

クラスで db ハンドルを保持する変数を作成します。

于 2012-11-07T13:48:32.720 に答える