質問

単一の責任の原理を使ってクラスをすべきで用いられていたものです。場合によいカットします。その他にも、難しいのでどのような"一つのこと"で見た場合、指定されたレベルの抽象化する複数のものを見た時より低いレベル。も恐れた場合には、単一の責任原則は、低レベルにおいて過剰に分離し,デフォルト値が設定されravioliコードは、ラインを過ごした作りの小さなクラスのもと配管の情報をより実際に解決の問題ることができることとなります。

どのようなところか一つのこと"です。このコンクリートの向上のクラスは以上の"一つのこと"?

役に立ちましたか?

解決

私はロバート・C・マーティン(ボブおじさん)が本当に好きです 単一の責任原則(PDFにリンク)を修正する:

クラスが変更する理由は決してありません

従来の「1つのことだけを行う必要がある」定義とは微妙に異なり、クラスについての考え方を変えることを強制するため、これが好きです。 「これは一つのことをしているのか」について考えるのではなく、代わりに何が変わるか、そしてそれらの変化があなたのクラスにどのように影響するかについて考えます。たとえば、データベースが変更された場合、クラスは変更する必要がありますか?出力デバイスが変更された場合(画面、モバイルデバイス、プリンターなど)。他の多くの方向からの変更のためにクラスを変更する必要がある場合、それはあなたのクラスの責任が多すぎるという兆候です。

リンクされた記事で、ボブおじさんは次のように結論付けています。

SRPは、最も単純な原則の1つであり、正しくなるのが最も難しいものの1つです。結合する責任は、私たちが自然に行うことです。これらの責任を互いに見つけて分離することは、ソフトウェアデザインの多くのことの多くです。

他のヒント

SRPが解決しようとしている問題はどのような問題ですか? SRPはいつ私を助けてくれますか?これが私が思いついたものです:

次の場合は、クラスの責任 /機能をリファクトする必要があります。

1)機能性を複製しています(ドライ)

2)あなたのコードがそれを理解するのに役立つために、コードが別のレベルの抽象化を必要とすることがわかります(KISS)

3)あなたは、あなたの機能の部分があなたのドメインの専門家によって異なるコンポーネント(ユビキタス言語)の一部であると理解されていることを発見しました

クラスの責任を取り外してはいけません。

1)重複した機能はありません。

2)機能は、クラスのコンテキスト以外では意味がありません。別の言い方をすれば、クラスは機能を理解しやすいコンテキストを提供します。

3)ドメインの専門家は、その責任の概念を持っていません。

SRPが広く適用された場合、ある種の複雑さ(中にあまりにも多くのことをしてクラスの頭または尾を作ろうとしている)を別の種類(すべての協力者 /レベルのレベルを維持しようとする)を広く交換することが私に起こります。これらのクラスが実際に何をするかを把握するために、抽象化。

疑わしいときは、除外してください!明確なケースがある場合は、いつでもリファクタリングできます。

どう思いますか?

客観的なスケールがあるかどうかはわかりませんが、これを与えるのは方法です - それらの数ではなく、それらの機能の多様性です。分解をやりすぎることができることに同意しますが、それについての厳しいルールに従うことはありません。

答えは定義にあります

あなたは何 定義 責任は、最終的にあなたに境界を与えます。

例:

責任を持つコンポーネントがあります 表示 請求書 - >この場合、私がさらに何かを追加し始めた場合、原則を破っています。

一方で、私が責任を言った場合 取り扱い 請求書 - >複数の小さな機能の追加(例: 請求書, 、更新 請求書)すべてがその境界内にあります。

ただし、そのモジュールが処理され始めた場合 どれか 以外の機能 請求書, 、それはその境界の外にあります。

私はいつも2つのレベルでそれを見ています:

  • 私は自分の方法が一つだけをして、それをうまくやっていることを確認します
  • クラスは、1つのことを表す方法の論理的(OO)グループと見なしています

したがって、犬と呼ばれるドメインオブジェクトのようなもの:

Dog 私のクラスですが、犬は多くのことをすることができます!などの方法があるかもしれません walk(), run()bite(DotNetDeveloper spawnOfBill) (申し訳ありませんが抵抗できませんでした; p)。

もしも Dog 扱いにくくなり、私はこれらのメソッドのグループを別のクラスで一緒にモデル化する方法について考えます。 Movement クラス、私を含むことができます walk()run() 方法。

困難で高速なルールはありません。OOデザインは時間とともに進化します。私は、クリアカットインターフェイス/パブリックAPIと、1つのことと1つのことをうまく行う簡単な方法を探しています。

見であり、aクラスのみ 代表 が一つあります。適切な@Kariannaの例にして Dog プレステージ方法 walk(), run()bark().てるつもりはありませんの追加方法 meaow(), squeak(), slither() または fly() ではない犬もいます。れるものその他の動物、及びその他の動物について、自分のクラスを表示します。

(ちなみれば、愛犬 フライ、その停止を投げかを示しませんでした。

クラスは、独自のレベルの抽象化で表示されたときに1つのことを行う必要があります。それは間違いなく、それほど抽象的なレベルで多くのことをするでしょう。これは、プログラムをより保守しやすくするためにクラスが機能する方法です。それらを綿密に調べる必要がない場合、実装の詳細を非表示にします。

これのテストとしてクラス名を使用しています。クラスにかなり短い説明的な名前を与えることができない場合、またはその名前に「and」のような単語がある場合、おそらく単一の責任の原則に違反しています。

私の経験では、この原則をより具体的なより低いレベルで維持する方が簡単です。

また独自 rôle.

各クラスを再開することによる役割の名前です。役割として(セット)動詞("s")に関連するコンテキスト

例えば:

ファイルをファイルのアクセス。FileManager管理ファイルオブジェクト。

資源データを保持するための一つの資源からのファイルです。ResourceManagerの開催を提供してます。

こちらできる動詞のように"管理"ことを意味しているセットのその他の動詞があります。動詞だけでは良い思想としての機能により授業になっています。場合の動詞を意味すぎる行為、独自の共通の文脈で、このクラスそのものです。

その考え方を"みする、単純なアイデアはどういったクラスを定義することによって独自の役割というのagregateのコミュニケーションの役割(行員によるオブジェクトやその他のオブジェク

私はよく構築Managerクラスに複数の異なる他のクラスです。工場のように、レジストリなど。参照マネージャクラスのようにグループ長を団長とガイドその他の人々を成し遂げるために共に働くことで高いレベルのアイデアです。ってひとつの役割がとも、他の独自の役割です。でも確認できたような会社が主催:表取締役社長からの生産の純生産性のレベルがものではございませんが、その後何もないので正しく動作します。"彼の役割を担う。

設計する場合には、特に、独自の役割です。それぞれの役割、再び合うかどうかを確認できないカットは、その役割です。その場合に必要な思い出や郷愁に弾方法の変更マネージャーの構築物を変えるだけで、工場、平和です。

SRPは、クラスを分割するだけでなく、機能を委任することでもあります。

上記で使用した犬の例では、SRPを正当化として使用して、Dogbarker、Dogwalkerなど(低凝集)などの3つの別々のクラスを持つことはありません。代わりに、クラスの方法の実装を見て、「知りすぎ」かどうかを決定します。まだdog.walk()を持つことができますが、おそらくウォーク()メソッドは、歩行の達成方法の詳細を別のクラスに委任する必要があります。

実際には、犬のクラスが1つの理由を変えることを許可しています。犬が変わるためです。もちろん、これを他の堅実な原則と組み合わせることで、犬を変えるのではなく、新しい機能のために犬を拡張します(オープン/クローズド)。そして、ImoveやIeatなどの依存関係を挿入します。そしてもちろん、これらの個別のインターフェイス(インターフェイスの分離)を作成します。犬は、バグが見つかった場合、または犬が根本的に変化した場合にのみ変化します(Liskov Sub、拡張して、行動を除去しないでください)。

SOLIDの正味の効果は、既存のコードを変更する必要があるよりも頻繁に新しいコードを書くことができることです。これは大きな勝利です。

それはすべて、責任の定義と、その定義がコードの維持にどのように影響するかに依存します。すべてが1つのことに要約されており、それがあなたのデザインがあなたのコードを維持するのに役立つ方法です。

そして、誰かが「水の上を歩いて、与えられた仕様からソフトウェアを設計するのは簡単で、両方が凍結されていれば簡単です」と言ったように。

したがって、より具体的な方法で責任を定義している場合、それを変更する必要はありません。

時には責任が明白に明白になることもありますが、時にはそれが微妙である可能性があり、慎重に決定する必要があります。

Catchthief()という名前の犬のクラスに別の責任を追加するとします。今では、追加の異なる責任に至る可能性があります。明日、犬が泥棒を捕まえている方法が警察部によって変更されなければならない場合、犬の授業を変更する必要があります。この場合、別のサブクラスを作成し、それをThiefcathcerdogと名付けた方が良いでしょう。しかし、別の見解では、それがいかなる状況でも変わらないと確信している場合、またはキャッチングが実装されている方法が外部パラメーターに依存している場合、この責任を負うことはまったく問題ありません。責任が驚くほど奇妙でない場合、ユースケースに基づいて慎重に決定する必要があります。

「変更する理由の1つ」は、システムを使用している人に依存します。各アクターのユースケースを使用していることを確認し、使用可能な変更ごとに最も可能性の高い変更のリストを作成してください。まったく新しいユースケースを追加している場合は、そうするためにクラスを拡張する必要があることを確認してください。

ライセンス: CC-BY-SA帰属
所属していません softwareengineering.stackexchange
scroll top