[SOLID]単一責任原則(SRP)


SOLIDって何?


一般に対象向けの5大原則と呼ばれるSOLID原則とは、SRP(単一責任原則)、OCP(オープン・クローズド・原則)、LSP(リスク交換原則)、依存逆転原則(DIP)、ISP(インタフェース分離原則)のことであり、前者は、プログラマーが時間をかけてもメンテナンスや拡張が容易になるソフトウェアの開発を支援するためである.

単一責任原則の原理


単一責任の原則は「階級には一つの責任しかない」ということだ.これは簡単なルールを意味します.クラスに複数の責任がある場合、クラスは各責任に基づいて変更されます.したがって、クラスが1つの理由で変更された場合、クラスは1つの責任のみを負います.このため、この原則のもう一つの言い方は「クラスを変更する理由は一つしかない」ということです.高度な表現.
しかし、この「責任」を明確に定義することは難しい.まず、責任を議論する前に、単一責任の原則を守らなかったときの問題を見てみましょう.

単一責任の原則を守らない場合の問題



上記のコードは、HTTPプロトコルを使用してデータを読み取り、画面に表示します.display()メソッドは、loadHtml()から読み込まれたHTML応答文字列をupdateGui()メソッドに送信します.また、updateGui()メソッドは、ParseDataToGuaData()メソッドを使用し、HTML応答メッセージをGUIに表示するためのGuiDataオブジェクトに変更し、実際のtableUIを使用してデータを表示します.
データを提供するサーバがHTTPを利用してメンテナンスを行っていれば,それだけの責任を負っても問題にならない.ただし、データを提供するサーバがスロットベースのプロトコルに変更された場合はどうなりますか?このプロトコルが応答データをバイト配列で提供すると、多くのコード変化が発生します.

LoadHtml()メソッドから読み込まれたデータの構造をStringからbyte[]に変更し、updateGuiのパラメータタイプを変更し、GuiDataを生成するParseDataToGuiData()メソッドのコードを変更します.
私たちはデータを提供するサーバが変化しただけで、コードは連鎖的に修正されました.これは、責任の個数が多ければ多いほど、1つの責任の職能変化が別の責任に与える影響が比例的に増加するためである.最終的には、コードをプロセス向けに変更し、メンテナンスを悪化させます.
したがって、データGUIの表示を担当するオブジェクトと、データの読み取りを担当するオブジェクト、および抽象データ自体の3つのオブジェクトとを分離しなければならない.
単一責任の原則を守らない場合の2つ目の問題は、再利用が難しいことです.上のDataViewerは、HttpClientパッケージを使用してHTTPバインディングを行い、GuiCompパッケージを使用して画面にデータを表示するデータを読み出すクラスです.
データのみを取得する場合は、不要なGuicCompパッケージも必要です.単一の責任原則に従って責任を分離する場合は、HttpClientパッケージのみが必要です.

責任は何ですか?1


以上より,1つの責任の実施変更が他の責任に関連するコード変更の可能性を増大させることが分かった.ただし、上記のコードからデータを読み出す方式を維持していれば、DataViewerクラスを変更する必要はありません.このような機能変更要求がなければ、修正の問題はなく、逆に、責任の単位が変更の部分に関係していることを意味する.
上記のコードでは、DataViewerクラスからデータを読み出す機能が変化しており、このような変化により、データを読み取る機能が個別に分離される必要があることが理解できる.
また、各責任は異なる理由で変更されるため、データを読み取る責任が変化した場合に、データを表示する責任は変更されてはならない.
では、変更の原因が異なることをどのように知っていますか?それは誰が実行するかを見ることです.また,これらのユーザがこのクラスの異なるメソッドを使用すると,それらのメソッドは異なる責任に属する可能性が高く,責任分離候補と判断できる.
DataViewerクラスを再度表示します.

ここで、Aクラスはdisplay()メソッドを使用し、BクラスはloadHtml()メソッドを使用し、Aクラスが画面表示を変更する必要がある場合はdisplay()メソッドを変更し、Bクライアントが読み出したデータ型を別のタイプに変換する必要がある場合はloadHtml()メソッドを変更すると仮定する.
クラスの使用者が異なる方法を使用すると,責任を分離できるかどうかを考えることができる.

責任は何ですか?2


責任は変化に対するものであることを認識する.しかし,コードから見ると,単一責任は単なる方法で機能する機能にすぎないようである.そのため、このほかに、次のような疑問があります.
  • クラスに複数の(共通の)方法がある場合、どのくらいの責任がありますか?
  • クラスに複数の継承(または複数の実装)がある場合、複数の責任がありますか?
  • 複数のユーザー(クライアント)がクラスに依存している場合、なぜ変更が発生しますか?
  • 単一の責任が1つの方法で行われていると考えられる場合は、これが最初の考えだと思います.クラスが複数のクラスに継承されている場合は、単一の責任を負いません.最後に、クラスに複数のユーザーがいる場合は、変更の原因が多様であるため、単一の責任は負いません.
    この疑問を解決するために良い定義があります.
    1つのモジュールは1つだけで、1つのオペレータだけが責任を負います.
    SOLIDを創設したロバートCマーティンの言葉は、SRPを再定義した.ここで、「actitor」とは、システムを同じ方法で変更したいユーザ群を指す.つまり、actorは一人でも複数人でもよい.したがって,SRPを設計する際には,クラスがどのactitorに依存するかをマクロ的に考慮することが望ましい.
    例を挙げて詳しく説明する.例えば、チョルスとヨンヒが「スマートフォン」という相手を使っているとする.この時、チョルスはゲームをするためにスマートフォンを使い、ヨンヒは動画を見るために使った.
        class 스마트폰 implements 게임플레이어, 동영상플레이어 {
            ...
        }
    上記のスマートフォンの対象は、チョルスとヨンヒが異なる方法で変わることを望んでいる可能性があるので、チョルスとヨンヒは異なる動作だ.チョルスが自分の好きなゲームをするためにスマートフォンのCPUを変えたり、ヨンヒが動画を見るために液晶サイズを増やしたりすれば、これらは動作に合わない変化だ.そのため、このスマートフォンは単一責任の原則を守るために、異なるゲーム機に分離しなければならない.
    しかし、チョルスとヨンヒが同じような要求でスマートフォンを使うなら、チョルスとヨンヒを一つの動作と見なすことができるので、単一責任の原則を守らなければならない.
    今、上の疑問点を解決しましょう.まず,2番目と3番目はactitorの概念によって容易に解決できる.多重継承が得られたとしても、actitorがすべての多重継承を使用した場合、単一責任原則を満たすことであり、クラスのユーザが複数のユーザであるが、同じ要求を使用している場合、単一責任原則を遵守する.
    1つ目の疑問は,同様に,異なるアクチュエータがこの種の種々の手法を用いていない場合,種々の手法を用いても単一責任の原則を遵守しなければならないことである.