7

ウィキペディアから引用されたDIの定義は次のように述べています。

A.高レベルのモジュールは低レベルのモジュールに依存するべきではありません。どちらも抽象化に依存する必要があります。B.抽象化は詳細に依存するべきではありません。詳細は抽象化に依存する必要があります。

私はその原則を私のコードに適用しようとしています:

class Printer{
        private $logger;    
        function __construct(Zend_Log $logger){
            $this->logger=$logger;
        }    
       function print(){
          //Some code
          $this->logger->log('Logger in action ;)');
       }        
    }

なぜPrinterクラスZend_Logが抽象クラスでもインターフェースでもないことに依存するので、依存性逆転の原則に違反しています。

Zend_Log抽象クラスを拡張したり、インターフェイスを実装したりしないことを知って、どうすれば修正できますか?

4

2 に答える 2

5

最も簡単なアプローチは、インターフェイスアダプターを使用することです。たとえば、プリンターがインターフェイスで使用することになっているAPIを作成し、そのインターフェイスをZend_Logコンポーネントのアダプターに実装します。具体的なアダプタをプリンタに渡します。その場合、プリンターは、具体的なZend_Logではなく、PrinterLogに依存します。

interface PrinterLog
{
    public function log($whatever);
}

class ZendPrinterLogAdapter implements PrinterLog
{
    private $logger;

    public function __construct(Zend_Log $logger)
    {
        $this->logger = $logger
    }

    public function log($whatever)
    {
        // delegate call to $this->logger
    }
}

class Printer
{ 
    private $logger; 

    function __construct(PrinterLog $logger)
    { 
        $this->logger = $logger; 
    }
} 

$printer = new Printer(new ZendPrinterLogAdapter(new Zend_Log));
于 2012-11-07T18:30:48.710 に答える
2

これは、同じAPIを使用した別の方法です。したがって、これが標準のセットアップになります。

interface Printerish // couldn't think of a good ajective
{
    public function print();
}

interface CanLogStuff // couldn't think of a good ajective
{
    public function log( $text );
}


class Printer implements Printerish
{
    public function print()
    {
        // do something
    }
}

そして、これはログ可能なプリンターになります。

class LoggedPrinter implements Printerish
{
    protected $logger;
    protected $pritner;

    public function __construct( Printerish $printer, CanLogStuff $logger )
    {
        $this->logger = $logger;
        $this->printer = $printer;
    }

    protected function print()
    {
        $this->logger( 'I can print, I can print !!' );
        $this->printer->print();
    }

}

これがどこから来たのかは、次のユースケースです。現実の世界で実際のプリンターの使用を制御し始めたい場合(インターンはインターネットを再び印刷しています)。そうすれば、別のプリンターを作ることはありません。外部コントロールを追加しようとしています。

プログラミングでは、それはオープン/クローズドの原則に少し関係しています。

これは単なるアイデアであり、本番コードで使用する前に、これをよく確認する必要があることに注意してください。

于 2012-11-07T19:06:25.460 に答える