0

「より大きな」アプリケーションを作成していて、クラスで特定のエラーをログに記録したいとしましょう。現在、ほぼすべてのクラスが Logger にアクセスする必要があります。

1つの簡単な解決策は次のとおりです(PHPですが、それは問題ではありません):

class SomeClass {
  public function someMethod() {
    // stuff ...
    Logger::log("something happened");
    // stuff ...
  }
}

このアプローチの問題は、Logger を使用するすべてのクラスがそれに依存するようになり、Logger なしで他のプロジェクトで同じクラスを単純に使用できないことです。しっかりと結合されています。また、 の実装を変更せずに、メッセージがログに記録される方法を変更することはできませんSomeClass

上記のアプローチの「少し」のアップグレードは次のようになります。

class SomeClass {

  private $logger;

  public function __construct(/* stuff */) {
    $this->logger = LoggerFactory::getLogger();
  }

  public function someMethod() {
    // stuff ...
    $this->logger->log("something happened");
    // stuff ...
  }
}

SomeClassは単純に に依存し、LoggerFactoryそれに密結合しているため、これで問題が実際に解決されるわけではありません。これの良いところは、クラスLoggerFactoryのさまざまなインスタンスを返すことができるようになったことです。Loggerしたがって、メッセージが記録される方法を変更したい場合、 の実装を変更する必要はありませんSomeClass

別のアプローチは、依存性注入を使用することです。

class SomeClass {

  private $logger;

  public function __construct(Logger $logger, /* stuff */) {
    $this->logger = $logger;
  }

  public function someMethod() {
    // stuff ...
    $this->logger->log("something happened");
    // stuff ...
  }
}

SomeClass現在、これは特定のクラスに結合されていません。Loggerインターフェイスを実装するクラスが必要なだけです。Loggerしかし、これに関する問題は、オブジェクトを作成するたびにインスタンスをコンストラクターに渡す必要があることです。

$object = new Position($this->logger, $x, $y);

これに関するもう 1 つの問題は、Logger が実際にはandのPositionようなクラスの一部ではないことです。それは単なるユーティリティです。$x$y

そのような状況にどのように対処するのが最善ですか? この場合、カップリングと結束の間の最適な妥協点は何でしょうか?

4

2 に答える 2

1

AOPは、ロギングをビジネスロジックから分離できる優れたツールです。

AOPを使用する最も一般的なシナリオの1つはロギングであるため、一見の価値があるかもしれません。

ニーズに合ったフレームワークがあるかどうかを分析して、それがどのように機能するかを確認できます。

このリンクでは、C#AOPフレームワークであるpostsharpを使用してロギングを実装する方法を確認できます。

于 2013-03-01T12:29:26.850 に答える
1

あなたのアプローチは正しく、制御原理の反転に対する答えです。ただし、あなたが述べたように、ロガーはアプリケーションの分野横断的な問題であり、Position エンティティとは何の関係もありません。言い換えれば、それは純粋に技術的なものであり、私たちはそれについて知りたくありません.

ここに 2 つのオプションがあります。

1) ある種の Manager クラスを介してすべてのロガーを参照し、クラス レベルで必要なものを使用します。この LoggingManager は、ロギング機能を必要とするソリューション内のすべてのクラスに認識されている必要があります。これは、外部のログ フレームワーク (例: Log4Net) を使用するときに頻繁に行ってきました。

2) または、必要なロガーを提供する上位エンティティ (サービス) から実行時にロガーを要求できます。依存性注入フレームワークまたはアスペクト指向プログラミング スタイルのクラス構成を使用すると、クラス自体からロガー タイプ (またはファクトリ) の選択が削除されます。

残念ながら私は PHP に詳しくないので、コード例を提供することはできません。しかし、C# で AOP のこの良い例を見つけました: http://visualstudiomagazine.com/articles/2011/05/12/wccsp_aspect-directional-programming.aspx

于 2013-03-01T13:10:51.273 に答える