web-dev-qa-db-ja.com

コンストラクタインスタンス変数の代わりに、クラス内の他のクラスのインスタンス?

私はそのようなコードでOOPレッスンを見ていました:

class UsersConstroller {

    protected $userService
    protected $logger

    public function __construct {

        UserService $userService,
        Logger $logger
     }

}

このクラスが行うことは、コンストラクターで他のクラスを渡すことです。次に、それらを変数に割り当て、クラス内で$ thisとともに使用されます。

これらのクラスをコンストラクターに渡さず、次のようにクラスコードの必要な場所に直接インスタンス化するのは間違っていますか?

( new Logger )->logMessage("this is a message")

このようにして、他のクラスの多くのインスタンスをクラスに渡すことを回避できます。

1
Robert Brax

あなたが提供した例で説明されていることは 依存性注入 と呼ばれ、一般的には良い習慣と考えられています。

必要なときにいつでもクラスのオブジェクトをインスタンス化すると、パフォーマンスの低下、メモリの断片化、およびマネージ言語でのメモリ消費の増加につながる可能性があります(ガベージコレクタがこれらの参照の一部を解放するのに時間がかかります)。管理されていない言語では毎回そのメモリを解放する必要があることは言うまでもありません。つまり、メモリリークの大きなリスクがあります(どこかでdelete loggerを書くのを忘れるでしょう)。

実際のところ、ロガーがローカル変数である場合、つまりそのクラスの他のメソッドに影響を与えない場合を除いて、(new Logger)-> logMessage("this is a message")のようなものが使用される有効なシナリオはわかりません。

ただし、この特定のケースでは、ロガーが通常行うことを考慮すると、このようなことを行うことが良い習慣であるというシナリオはまったくありません。ロガークラスは、複数のスレッドからの同じログファイルへの同時書き込みを処理できる必要があります。毎回新しいクラスをインスタンス化する場合、これを実現するのは非常に困難です。

4
Vladimir Stokic