単一責任の原則
(「すべてのクラスに1つの責任のみを持たせる必要があります。言い換えれば、すべてのクラスに1つだけの変更理由を持たせる必要があります」)
同意しません。私が考える方法を変更する唯一の理由があるはずであり、クラスのすべてのメソッドが持つべき1-別の論理的な関係を、しかし、クラス自体は実際にあります行う、いくつかの(関連)のものを。
私の経験では、この原則はあまりにも熱心に適用されすぎており、多くの小さな1つのメソッドクラスになってしまいます。私が働いたアジャイルショップは両方ともこれを行っています。
.Net APIの作成者がこの種のメンタリティを持っているとしたら、 List.Sort()、List.Reverse()、List.Find()などではなく、ListSorter、ListReverser、およびListSearcherクラスがあると想像してください!
SRP (それ自体は理論上ひどいものではありません)に反論するのではなく、長年の逸話的な経験をいくつか紹介します。
私が働いたある場所で、ノード、グラフ、グラフ作成者、グラフソルバー、グラフ作成者/ソルバーを使用して問題を解決するクラスの5つのクラスで構成される非常にシンプルな最大フローソルバーを作成しました実世界の問題。特に複雑なものや長いものはありませんでした(ソルバーは、最大で150行まで)。ただし、クラスには「責任」が多すぎると判断されたため、同僚はコードのリファクタリングに取り掛かりました。それらが完了すると、私の5つのクラスは25のクラスに拡張され、コード行の合計は元の3倍以上になりました。コードの流れはもはや明らかではなく、新しい単体テストの目的でもありませんでした。私は自分のコードが何をしたかを理解するのに苦労しました。
同じ場所で、ほぼすべてのクラスには1つのメソッドしかありません(「責任」のみ)。プログラム内のフローを追跡することはほぼ不可能であり、ほとんどの単体テストは、このクラスが別のクラスのコードを呼び出したことをテストすることで構成されていました。文字通り数百のクラスがあり、そこには数十のクラス(IMO)しかありませんでした。各クラスは「もの」を 1つだけ実行しましたが、「AdminUserCreationAttemptorFactory」のような命名規則を使用しても、クラス間の関係を伝えることは困難でした。
別の場所(クラスは1つだけのメソッドを持つという考え方もあります)で、特定の操作中に95%の時間を費やすメソッドを最適化しようとしました。(少し愚かな)最適化を少し行った後、なぜそれが何千回も呼ばれている理由に注意を向けました。それはクラスのループで呼び出されていました...そのメソッドは別のクラスのループで呼び出されていました..これもループで呼び出されていました..
すべてのことを言って、13のクラスに(真剣に)広がる5つのレベルのループがありました。あるクラスが実際に何をしていたかは、それを見ただけでは判断できませんでした。クラスが呼び出したメソッド、それらのメソッドが呼び出したメソッドなどのメンタルグラフをスケッチする必要がありました。すべてが1つのメソッドにまとめられていた場合、問題のメソッドはすぐにわかる5つのレベルのループ内にネストされているため、長さは約70行でした。
これらの13のクラスを1つのクラスにリファクタリングするという私の要求は拒否されました。