次の例では、単一責任の原則について混乱しています
-
06-07-2019 - |
質問
次のビデオでは、作成者は既存のクラスを取得し、Singleそれに対する責任の原則。彼は、データへのアクセス、書式設定、およびレポートの印刷を行う印刷クラスを取ります。彼は各メソッドを独自のクラスに分割し、DataAccessクラスを作成してデータアクセスを処理し、ReportFormatterクラスを作成してReportのフォーマットを処理し、ReportPrinterクラスを作成してReportの印刷を処理します。元のReportクラスには、ReportPrinterのクラスメソッドPrintを呼び出すPrint()という1つのメソッドが残ります。 DataAccessとReportFormatterには責任があるように見えますが、ReportPrinterはDataAcessとReportFormatterに依存しているので、これによりSRPが壊れたり誤解したりしませんか?
解決
単一の責任の原則は、特定のクラスに単一の責任(または「変更の理由」)が必要であることを示しています。それ自体では、その責任がどのように満たされるかを示すものではありません。これを行うには、共同作業者として複数の他のクラスの協力が必要になる場合があります。
他のヒント
ビデオを見なくても、合理的なデザインのように聞こえます。データアクセスを処理するメソッドはReportPrinterクラスには表示されず、「必要なデータを取得するために何かを呼び出すことができる」という概念のみが表示されるため、SRPは壊れていません。
もう少しプッシュして、データアクセスクラス、フォーマッタクラス、およびプリンタクラスのアクティビティの調整のみを行うコーディネータクラスを用意することもできます。また、コーディネーターがデータをフォーマッターに送信し、プリンターに送信し、コーディネーターがプリンターを(直接)知らないようにするなど、さまざまな方法でオブジェクトを配置することもできます。
焦点を絞ったオブジェクトの努力を調整することについて、何か知っておく必要があります。それが彼らの責任になります。他のオブジェクトが何をするのかを知らないか気にしない限り、他のオブジェクトが何をするのかというアイデアや概念を知っていても構いません。インターフェイスを「責任の継ぎ目」と考える良いスタートです。
また、オブジェクトを「行う」のではなく、互いにデータを渡すと考える場合にも役立ちます。物事。したがって、ReportFormatterは、既存のレポートで(概念的に)オブジェクトを実行するのではなく、フォーマットされたレポートを表す新しいオブジェクトを返します(または転送します)。
SRPは依存関係を解決しません。クラスを単一の責任クラスに分割すると、それらの依存関係を後で簡単に分割できます。 SRPは、一緒に言及された2つの原則の1つである凝集性と結合性に対処します。 SRPは凝集度が高く、依存性が高いカップリングを示している可能性があります。優れた設計には、高い凝集力と低い結合があります。これらの2つの原則は相反する場合があります。
いいえ。 SRPを壊しません。
仮定します
DataAccess implements IDataAccess
ReportFormatter implements IReportFormatter
ReportPrinter implements IReportPrinter
ReportPrinterはDataAccessおよびReportFormatter
に依存していますが、 IDataAccessまたはIReportFormatter
の契約の変更は、 DataAccessおよびReportFormatter
それぞれ。 ReportPrinter
は、これらのクラスの責任の変更について心配しません。
Composition
を使用するか、 Mediator パターンを実装してルーズを提供できますこれら3つのクラスを結合し、仕事を終わらせます。 カップリング
部分を責任
から遠ざけます。