これは、それなしでやってみて、それがどのように混乱するかを見るまで、それが必要であることを知らないものの1つです。
独自の Logger ユーティリティを作成するとします。最初は単純なので (stdout に書き込むメソッドを持つシングルトン)、そのすべての機能を 1 つのクラスに入れることにします。それを使用すると、追加する機能がさらに考えられます。
ログを記録するさまざまな宛先 (stderr、ファイル、キューなど)
メッセージのフォーマットを変更する機能
カテゴリごとに個別のロガーを提供する
ログレベルでカテゴリのメッセージをフィルタリングする機能
プログラムの実行中にログレベルを変更できるようにしたい
新しいログ レベル (ERROR、WARN、INFO、DEBUG など)
など、すべての機能の実装を、開始した同じクラスに追加します。変更を行うたびに、同じクラスに戻り、並べ替えて関連するものを確認し、変更を加えることを意味します。クラスには、これらの各機能が初期化されるさまざまなライフサイクル イベントがあるため、すべての機能コードが 1 か所にあるのではなく、クラス内のさまざまなメソッドに分散されます。
すべてのコードが 1 つのクラスに詰め込まれ、メソッドにはさまざまな機能を実装するコードが含まれているため、変更に関連するすべての部分を追跡するのは困難であり、変更が他の機能に不注意で影響を与える可能性が常にあります。 -既存の機能は、状況によっては動作しなくなる可能性があります。したがって、これらのエラーを検出するには、クラス内のすべての機能をテストする必要があり、さらに悪いことに、すべての機能のすべての組み合わせをテストする必要があります。つまり、テストが不完全になり、エラーが入り込む可能性があります。
次に、log4j のような実際のプロジェクトがこの処理をどのように処理するかを見てみましょう。さまざまなクラスが書式設定を処理し、出力がどのように書き込まれるかを処理し、カテゴリのロガーを提供し、これらすべての部分間の相互作用が明確に定義されているという懸念事項が分離されています。他の部分には影響しません。ユーザーは、必要な機能を追加する独自のクラスを作成し (ログ フレームワークについてすべてを知る必要はなく、追加したい特定の種類の部分のコントラクトのみを知る必要があります)、プラグインできます。 、ユーザーはさまざまなプラグインを組み合わせて使用できます。プラグインが破損した場合、その破損がそのプラグインを超えて広がることはなく、個々の部分への変更がプロジェクト全体の整合性を脅かすことはありません。コントラクトが部分の相互作用を管理する限り、特定の機能のさまざまな組み合わせをすべてテストする必要はありません。そして、それぞれが単一の責任を持つピースで構成されているため、そのように機能します。
単一クラスのアプローチではそれができず、誰かが追加した新しい機能のすべてがプロジェクトのフォークになり、それぞれを元に戻すことは、次第に大きなタスクになります。単一責任の原則とその他の SOLID ルールのポイントは、物事を壊すことなく制御された方法でソフトウェアを変更できるようにする全体的な戦略を提供することです。