8

ほとんどの任意のアプリケーションでは、ロギング、メッセージ バス、構成など、利用可能なすべてのレイヤー間で対処する必要がある横断的な問題が多数あります。私が気付いたのは、一部のクラスでは、モジュールが IoC を使用して注入されている場合、コンストラクターを完全に爆破する傾向があるということです。

public class MyService : IService 
{
    public MyService(ILogger logger, IAppSettings settings, IEventBus eventBus...)
    {

    }
}

コンストラクターの過剰注入の通常のケースでは、クラス内の依存関係が少なくなるように、関係を密接に関連するビルディング ブロックに屈折させる傾向があります。しかし、これは横断的な概念では不可能です。

ロギング フレームワークの中で、静的ファクトリ/サービスは非常に人気があるようです。

// Application root
MyLoggerService.SetFactory(log4NetFactory);

// Somewhere
MyLoggerService.GetLogger("name") // returns Log4NetLogger created by Log4NetFactory.

私の質問は次のとおりです。このアプローチは、あらゆる種類の分野横断的なものに適していますか? コードが次のようになる場合の欠点は何ですか。

public class MyService : IService
{

    private readonly IReallyNeedThat _dependency;

    public MyService(IReallyNeedThat dependency)
    {
        _dependency = dependency;
    }

    private readonly ILogger _logger = LoggerService.GetLogger("MyService");
    private readonly IEventBus _eventBus = EventBusService.GetEventBus();
    private readonly IConfiguration _configuration = ConfigurationService.GetConfiguration(Level.Roaming)
    private readonly IExceptionHandler _exceptionHandler = ExceptionPolicy.GetHandler();
    private readonly ITracer _tracer = TraceManager.GetDebugTracer();
}
4

2 に答える 2

8

コンストラクターから依存関係を移動しても問題は解決しません。クラスの依存関係の量を減らさず、単一責任の原則とオープン/クローズの原則にまだ違反している可能性が高く、コードがテストしにくく、変更しにくく、保守しにくい。

代わりに、多くの場合、これらの分野横断的な懸念事項をコンポーネントから引き出して、その分野横断的な関心事向けに特別に調整されたコンポーネントに配置し、そのコンポーネントが元のコンポーネントをラップすることです。つまり、デコレータを作成します。

関連するサービスのセットを定義するための一般的な抽象化がない場合、抽象化ごとにデコレータを定義する必要があり、多くのコードの重複が発生するため、おそらくクラスの設計を変更する必要があります。ほとんどの場合悪い。

代わりに、コマンド/ハンドラークエリ/ハンドラーを中心にシステムをモデル化すると、はるかに優れた場所にいることができます。ビジネス ロジックの各部分を、一度定義すればあらゆる場所で再利用できる汎用デコレータで装飾できます。これにより、システムはクリーンに保たれますが、非常に柔軟です。

于 2014-08-11T15:34:04.807 に答える