web-dev-qa-db-ja.com

インターフェイスが単一責任の原則に違反するように強制する場合はどうすればよいですか?

(私が投稿しなければならないコードは巨大なので、関数名だけに再開します)

私は現在、プロジェクトで次の問題に直面しています。「このフレームワークの各モジュールは、ユーザーがその動作を制御するために使用する小さなビューを持つことができます」ビューコンテナーのようなものがあります。

基本的に、各モジュールはリスト内に視覚的なスポットを持つことができ、ユーザーはクリックして上記のモジュールで何ができるかを確認できます。つまり、私のモジュールはすべてModuleInterfaceインターフェイスを尊重しているため、システムはそれらを認識します事実、モジュールと各モジュールは以下を尊重する必要があります。

shouldItLoad, loadModule, getModuleName, getStartingAction, getPriorityこれらはすべて必須であり、多くのことを行うように聞こえますが、それは必須事項ですまだ、これにさらに追加すると、私はあまりにも多くのことをするオブジェクトになってしまいます。

私のシステムができるようにするためだけに、そのビューコンテナ上にあることを望む各オブジェクトがViewBlockインターフェースも尊重することを望んでいることがわかりましたそれらを取り込み、そのビューを作成します。

現在、機能を最低限9〜10個使用しています。読み通すのは地獄であり、最も重要なことは、非常に多くのことを行いますが、

  1. それでも、ビューのパラメーターを定義するのはそのモジュールの仕事であり、他のものではありません。
  2. 再利用可能なViewBlockObjectを渡すことにオプトインした場合、Moduleがデータを設定し、それを取り込み、保持しますが、今は言うまでもなく、まだ多くのオーバーヘッドがあります**契約を強制できません(ViewBlockObject内の変数にModuleを保持する必要があるため)。

ここでの解決策は何でしょうか?各Moduleに、Moduleオブジェクト自体にオーバーヘッドをかけずに、ビューを必要とする各ユーザーが尊重する必要がある動作を持たせるにはどうすればよいですか?

4
coolpasta

答えは簡単です。モジュールに、すべてのモジュールが提供する必要がある機能を追加します。

単一責任の原則は、クラスが1つのことだけを実行する必要があることを意味しません。 do-one-thing-and-do-it-well は、主に関数に適用される別の原理です。 SRPは、変更する理由が1つあるべきだとだけ言っています。その原則の発明者であるボクルおじさんが 自分自身を説明する (そして彼の弟子たち- 確認 )。どちらの原則も 多くの場合、誤って混乱している であり、過剰なエンジニアリングにつながることがあります。したがって、将来の変更に備えて、本質的に凝集と結合の観点から原理を検討してください。したがって、クラス自体の責任ofではなく、因果責任for変更についての詳細です

ただし、もう1つの原則は、 インターフェイス分離の原則 です。あなたのインターフェースによって約束されたすべての機能がすべてのモジュールに関連していることを確信していますか?

4
Christophe

方法が多すぎると思われる場合、考慮すべき原則は低結合です。

SOLID原則は唯一の原則ではありません。素晴らしいスピーカーがそれらを支持していない健全な原則を尊重してください。

私が最初にあなたに会うのはshouldItLoadです。気にしないでください。ロードする時だと言ったら、気になったらロードします。ロードされたものを伝える必要がある場合は、ロードした内容を教えてください。あなたはいつ私に言うことを心配するだけです。

次のように、教えてはいけない質問は、インターフェースを単純化するのに役立ちます。何が起こっているのかすべての細部を知る必要のあるコントロールフリークであるようなインターフェースを複雑にするものはありません。いいえ、詳細を押しのけて、何か他のものに対処させます。

同様に、次にgetStartingActionに尋ねて、開始するときにstartを呼び出すのはどうですか?また、startの直後に常にloadを付けないだけの十分な理由があることを確認してください。

1
candied_orange

インターフェースを実装するクラスが単一のクラスにあるべき以上のことを行うと感じた場合でも、自分が属していると考えるものを別々のクラスに分離することができます。

次に、インターフェースを実装する単一のクラスがそれらのクラスを構成できます。これらのクラスのインスタンスが含まれ、外部メソッドへの呼び出しをそれらのクラスにリダイレクトするだけです。

複数のクラスがすべて同じインターフェースの同じメンバーのすべてとどのように相互作用するかに興味があります。見ないと分からないが、それはインターフェースに依存するクラスをリファクタリングする余地を示唆している。 1つのメソッドがこれらすべての依存関係と相互作用しますか?そうでない場合、そのメソッドは重複したコードによく似ていますか?

または、インターフェイスに依存するクラスの中で、異なるパブリックメソッドが重複することなくインターフェイスの異なるメンバーを使用していますか?その場合、おそらくそれらは別個のクラスである可能性があります。インターフェースの異なるメンバーを使用することは、そのクラスのメソッドが異なることをしていることを示唆するかもしれません。

後者の場合は、一部のインターフェイスメンバーのみを使用するクラスが作成される可能性があり、その結果、インターフェイスが分離され、元の問題が解決されます。

0
Scott Hannen