6

One Class, One Responsibilityの原則について学びたいです。それに関する記事をいくつか見つけましたが、例はありません。原則に反するクラスの例を教えていただければ助かります。

get メソッドと set メソッドのように、メソッドが 1 つのことだけを行うべきだという考えはよく知っています。set メソッドと get メソッドはどちらもクラス内で実装されるため、One Class, One Responsibilityと同じであってはなりません。クラスには設定と取得の両方の責任があるため、これはクラスがルールに違反していることを意味しますか?

1 つのクラス、1 つの責任の原則とは何ですか?

4

5 に答える 5

1

私はこのデザイン パターンの 100% の専門家ではありませんが、以下のように考えています。オブジェクトを作成すると、オブジェクトは 1 つのことを担当します。何か他のことをする必要があるが、状況に応じて別のオブジェクトに関連している場合は、継承またはインターフェイスを使用します。

これはかなり単純に思える概念です。特定のオブジェクト (またはメソッド) が 1 つのロジックを処理するようにします。それ以上処理する場合は、別のオブジェクト (またはメソッド) が必要です。

于 2012-04-21T22:56:18.340 に答える
0

責任を混同しないという原則の側面について。

請求書を処理し、ビジネス ルールに基づいて計算を行い、請求書を含む PDF を生成し、データベースを処理して販売者に追加のボーナス ポイントを登録する InvoiceProcessor クラスがある場合、関心の分離が必要な明確なケースがあります。この場合、明確な分離または他のクラスへの委譲が必要です。

しかし、One Class - One Responsibility はさらに巧妙で恐ろしいものです。請求書処理のソリューションを提供する必要があり、これらのボーナス ポイントのように達成すべき目標がいくつかある場合は、売り手のボーナス ポイントと顧客の割引を計算するという、いくつかの目標を達成する違反関数を使用できます。

小規模な場合: プライオリティ キューなどのデータ構造を持つクラスがあり、同時にリストやマップなどを使用してパーツをキャッシュするためのデータ構造と混合する場合、いくつかのデータ構造が絡み合うように、キャッシュリスト内でアドレス指定するなど、さまざまな懸念のためにデータを操作していることがわかります。次に、優先度を変更してキャッシュ状態を変更する関数がある場合、将来的にプロセスを理解することが難しくなります。

いくつかの異なる側面を実装する必要がある違反に遭遇することがよくありますが、それらは 1 つのクラスで実行されます。API には、さまざまな抽象化レベルまたは難しいセマンティックでの呼び出しがあります。

于 2012-04-21T23:07:27.303 に答える
0

これは、それなしでやってみて、それがどのように混乱するかを見るまで、それが必要であることを知らないものの1つです。

独自の Logger ユーティリティを作成するとします。最初は単純なので (stdout に書き込むメソッドを持つシングルトン)、そのすべての機能を 1 つのクラスに入れることにします。それを使用すると、追加する機能がさらに考えられます。

  • ログを記録するさまざまな宛先 (stderr、ファイル、キューなど)

  • メッセージのフォーマットを変更する機能

  • カテゴリごとに個別のロガーを提供する

  • ログレベルでカテゴリのメッセージをフィルタリングする機能

  • プログラムの実行中にログレベルを変更できるようにしたい

  • 新しいログ レベル (ERROR、WARN、INFO、DEBUG など)

など、すべての機能の実装を、開始した同じクラスに追加します。変更を行うたびに、同じクラスに戻り、並べ替えて関連するものを確認し、変更を加えることを意味します。クラスには、これらの各機能が初期化されるさまざまなライフサイクル イベントがあるため、すべての機能コードが 1 か所にあるのではなく、クラス内のさまざまなメソッドに分散されます。

すべてのコードが 1 つのクラスに詰め込まれ、メソッドにはさまざまな機能を実装するコードが含まれているため、変更に関連するすべての部分を追跡するのは困難であり、変更が他の機能に不注意で影響を与える可能性が常にあります。 -既存の機能は、状況によっては動作しなくなる可能性があります。したがって、これらのエラーを検出するには、クラス内のすべての機能をテストする必要があり、さらに悪いことに、すべての機能のすべての組み合わせをテストする必要があります。つまり、テストが不完全になり、エラーが入り込む可能性があります。

次に、log4j のような実際のプロジェクトがこの処理をどのように処理するかを見てみましょう。さまざまなクラスが書式設定を処理し、出力がどのように書き込まれるかを処理し、カテゴリのロガーを提供し、これらすべての部分間の相互作用が明確に定義されているという懸念事項が分離されています。他の部分には影響しません。ユーザーは、必要な機能を追加する独自のクラスを作成し (ログ フレームワークについてすべてを知る必要はなく、追加したい特定の種類の部分のコントラクトのみを知る必要があります)、プラグインできます。 、ユーザーはさまざまなプラグインを組み合わせて使用​​できます。プラグインが破損した場合、その破損がそのプラグインを超えて広がることはなく、個々の部分への変更がプロジェクト全体の整合性を脅かすことはありません。コントラクトが部分の相互作用を管理する限り、特定の機能のさまざまな組み合わせをすべてテストする必要はありません。そして、それぞれが単一の責任を持つピースで構成されているため、そのように機能します。

単一クラスのアプローチではそれができず、誰かが追加した新しい機能のすべてがプロジェクトのフォークになり、それぞれを元に戻すことは、次第に大きなタスクになります。単一責任の原則とその他の SOLID ルールのポイントは、物事を壊すことなく制御された方法でソフトウェアを変更できるようにする全体的な戦略を提供することです。

于 2013-12-06T16:03:02.723 に答える
0

原則はまさにその通りであり、それ以上のものではありません。1 つのクラスは 1 つの責任のみを持つ必要があります。ただし、責任を定義するのは難しい場合があります。例として、アプリケーション内のすべてのデータベース要求を処理する「DatabaseHandler」クラスがあります。

さらに読む:結束

于 2012-04-21T23:04:37.380 に答える