私はSOLIDを長年にわたって認識してきましたが、「OLID」は従うべき優れた設計原則の集まりでしたが、問題は常に困難を感じてきました。 「S」を使用すると、私は常にそれを非常にあいまいな原則として考え、信じています。私はこの原則について多くの異なる場所/本から読んだことがあります...
今日、私はこれを発見しました 記事 そして、それはSRPに関する私のすべての考え/懸念を非常によくまとめています。
だから私はあなたに尋ねたいのですが、それはSRPが実際に以下の定義のペアのような原則ですか?
- 信念や行動のシステムや推論の連鎖の基盤となる基本的な真実または命題。 「正義の基本原則」同義語:真実、命題、概念、アイデア、理論、仮説。もっと
- 幅広い分野にわたって数多くの特別な用途を持つ一般的な科学定理または法律。
なぜ私はこれを尋ねるのですか?まあ、明確で明確な方法でSRPを適用して、最終的にクラスまたは無料の関数を使用でき、誇らしげに論理的に「これはSRPに従う」と言え、正式にそれを証明できるといいですね。
「良い」とは、「論理的に言えば」正しいことを意味します。記事が言うとき私は好きです:
私は本当にSRPを理解し、好きにしようとしました。本当にやってみました。しかし、私はそれに同意することができません、そしてそれが私がこれを発表することに決めた理由です。
それは基本的に常に私の関心事でした。この場合、「これを公開することを決めた理由」から「ここに尋ねることを決めた理由」によってその文から変更するので、ベテランのエキスパートコーダーが知恵の真珠をもたらすことができます。
私はあいまいな用語を使用しませんが、間違いなく状況判断の重要な要素があります。
質問に前もって答えるには、いいえ、それを遵守しているかどうかをテストする正式で数学的に検証可能な手段はありません。
理由は、すべてのソフトウェアプログラムとドメインが同じではないためです。ジョエルはエッセイでこれについて触れました Five Worlds 。巨大な企業向けビジネスプロセス管理ソフトウェアには、自動販売機を制御するソフトウェアとは異なる設計アプローチが必要です。
私は、SRPがSOLIDグループの最も判断が多い概念の1つであることを認識します。そこには多くの悪い説明があります。多くの場合、エンタープライズコンサルティングウェアなどで執筆者がしっかりと書いています他の世界の側面を完全に認識または無視する絶対的なステートメントを記述します。人々が頻繁に書く「変更する1つの理由」の行は、特に無意味で曖昧だと思います。SOLIDの原則は、エンタープライズコンサルティングウェアの種類のソフトウェア、およびプロの作成者(ボブおじさんなど)は、そのような種類の企業にサービスを販売して生計を立てていることがよくあります。
単一の責任は、さまざまな状況でさまざまな人々にさまざまなことを意味する可能性があります。例として、私は最近、プログラムの設定を処理するクラスが必要になりました。この1つのクラスは、構成ファイルを読み取り、それを解析し、構成値にアクセスする手段を持ち、構成をディスクに書き戻すことができます。これらすべて、単一のクラスではConfigurationSettings
です。私の特定の状況では、これらのさまざまな異なることを行っているにもかかわらず、私のクラスは単一の責任、つまり構成の処理に固執していると主張します。
さて、何人かの人々は私のデザインは欠陥があると言います、それはあまりにも多くをします。構成ファイルパーサーオブジェクトを挿入し、new()
の代わりにConfigSettingsクラスをインスタンス化する抽象的なIConfigファクトリー、またはそのクラスの責任をさらに分割するために他の多くのものを用意する必要があります。
誰が正しいのですか?それは、単一の責任が全体像にどのように適合するかによって異なります。一部の著者が単一の責任の説明に「特定の抽象化レベル」で取り組むのを見たことがありますが、これは非常に理にかなっていると思います。そして、私の状況では、選択した抽象化レベルで、ConfigurationSettings
クラスは1つの処理のみを実行し、プログラム設定を保持します。保存される場所などの構成ファイル形式の詳細は、全体像ではまったく問題ではなく、どこに行くかを気にする人はいません。
抽象ファクトリー愛好家が私のクラスについて正しいとは、どのような状況でしょうか?多くの場合、彼らはその大企業の世界の人々でしょう。私のソフトウェアには正確に1人の顧客がいて、その単一の顧客以上のものは決してありません。 「古いバージョンを削除して、新しいバージョンをインストールする」だけで構成されるアップグレードプロセスを利用できます。古い形式との下位互換性がない構成設定への変更を導入した場合、古い構成を削除して新たに開始させることができます。
誰もが自分の構成設定についてそれほど無頓着であるとは限りません。一部の人々は数百または数千の顧客向けのソフトウェアを書いているかもしれません。ソフトウェアの異なるバージョン間で異なるフォーマットを管理および保持する必要がある場合があります。複数のコンピューターで共有される単一の構成をサポートし、すべて同じ場所から読み取る必要がある場合があります。私はそれをする必要はありません。しかし、これらの他の人々にとって、ファイル形式、場所など、は重要です。このような状況では、設定のフォーマットがわかったら、パーサーを構成クラスに挿入するのが理にかなっているかもしれません。ファクトリーにそれを理解させることは意味があるかもしれません。私が使用しているような一連の静的(グローバル)変数の代わりに、設定が変更されたときに通知システムを使用することは理にかなっています。
何千もの歯科医院が予定を立てて請求を行うためのソフトウェアを書いていたら、私の構成クラスは間違いなく適切ではないでしょう。しかし、それは私がやっていることではないので、そうです。
スカイネットレベルのAIが不足していると、静的分析ツールはクラスを調べて、その意図する抽象化レベルを理解することができないため、SRPコンプライアンスの意味のある判断を行うことができません。
問題の記事は「泥の大玉」アーキテクチャを提唱しているようです。
コードを書くとき、本当の現在の要件しかありません。未来はかなり無関係です
これは非常に近視的な開発の見方です。結局のところ、私たちが将来を気にしないのであれば、なぜ保守可能なコードを書くように努力するのでしょうか。現在の要件を満たすために、常に最も速くて汚いハックを常に使用しないのはなぜですか?
実際には、その価値のある開発者は、将来の変更を見越してコードを設計します。
SRPはこれを明示的に述べているだけです。将来的に要件を変更する可能性のある要因を分析し、これらの行に沿ってコードを構造化する必要があります。どのような力や興味が要件に影響するかを理解する必要があります。
つまり、ビジネスと組織を理解する必要があります。
「形式的に」および「論理的に」、一部のコードがSRPに従っていることを証明することはできません。これは、世界が煩雑で複雑になるにはほど遠いものです。このような証明には、コードだけでなく、コード全体に影響を与えるビジネス全体およびすべての外部の力が関与する必要があります。
ボブ・マーティンは彼の新しい本と同様にいくつかの会談でSRPを明らかにしました。見積もり:
すべてのSOLID=原則の中で、単一責任原則(SRP)は最もよく理解されていない可能性があります。これは、特に不適切な名前を持っているためと考えられます。プログラマが名前を聞いたり、次に、すべてのモジュールが1つのことだけを実行する必要があることを意味します。
しないという意味です。マーティン氏が言おうとしていることは、特定のモジュールは1人の変更担当者にのみ認められるべきだということです。
変更エージェントの識別は、おそらく組織/プロジェクトの規模に依存しますが、識別されたら、誰がどのモジュールに影響を与えることができるかは明らかです。
たとえば、iOSアプリを作成しています。 UIデザイナ、UXデザイナ、およびサーバー開発者に頼るモジュールがあります。サーバーへの変更によりモジュールSが変更される可能性がある場合、設計者がボタンのサイズを変更することを決定したため、変更が必要なモジュールは何もないはずです。また、UXデザイナーがアプリの論理フローを変更したいと考えていたため、変更が必要なモジュールもありません。
他の回答の1つでは、「設定」クラスの例が使用されています。クラスが記述されているように、情報を保存する方法が変更された場合、または保存する必要のあるロジックが変更された場合に変更する必要があるため、SRPが機能しなくなります。これらは、さまざまな理由で変化する2つの異なる懸念事項です。保存方法を変更すると、クラスが更新され、保存する必要があるものを変更すると、クラスも更新されます。
コメントへの対応:基本的に、SRPは、ビュー/プレゼンテーションコードをモデル/ロジックコードから分離する際に従う原則です。データベースにアクセスするコードを、データベースに何を保存するかを決定するコードから分離するのは、この原則に従うことです。
コメントに応じてさらに編集する:コメントでは、OPは、特定のモジュールがSRPに従うかどうか、変更エージェントが誰であるかを特定するための「明確な方法」を探していることを明確にしています。ありますが、それは普遍的ではありません。開発者として、変更要求を行うことができるユーザーとできないユーザーを知っている可能性があります。または、コードがいくつかの要件ドキュメントに基づいている場合があります。その場合、それらは変更エージェントです。たとえば、私の場合、ロジックを定義するユースケースドキュメントがあり、次にプレゼンテーションを定義するルックアンドフィールドキュメントがあり、サーバー統合を定義するサーバーエンドポイントドキュメントがあります。最後に、ストレージ戦略や、外部モジュールの追加/削除の可能性を残したいコードの領域などを定義する自分自身の技術的なニーズもあります。したがって、私の場合は、4つの変更エージェントがいます。他の企業では、ストレージ戦略は、変更エージェントを追加する全社的な命令である場合があります。他の状況では、変更エージェントを削除するサーバー統合がない場合があります。