👋

[SOLID原則] 単一責任の原則

2021/03/27に公開

ソフトウェアエンジニアならよく聞くであろう SOLID原則 の入門記事です。
書籍 クリーンアーキテクチャ
を参考にしています。 今回は「単一責任の原則」です。

単一責任の原則

Single Responsibility Principle で単一責任の原則です。

モジュールはたったひとりのユーザーやステークホルダーに対して責務を負うべきである。

というのが定義です。
他の記事などを見ると、この原則は別の定義もされているようです。
それは、「どのモジュールもたったひとつのことだけを行うべき」という定義です。

この原則自体はよく目にするでしょう。「小さいことは良いこと」であり、関数もクラスも究極的には1個の関心事だけを持つべきです。
ですが、 単一責任の原則 はこれとは全く違うもの です。
関数やクラスの書き方の話はもっと下位レベルの実装の話であり、アーキテクチャの文脈で単一責任の原則と言った場合には、もっと上位レベルの話になります。

「たったひとりのユーザーやステークホルダー」とは一体どういうことでしょうか。
そもそも、ソフトウェアシステムが開発、運用されるのは必ずユーザーやステークホルダーを満足させるためです。

  • LINE → 連絡を取りたいユーザーを満足させている
  • Google Map → 友人との待ち合わせ場所に辿り着きたいユーザーを満足させている
  • Amazon → インターネットで買い物したいユーザーを満足させている

であるならば、ソフトウェアを構築する時に考慮する中心として「ユーザーやステークホルダー」がいるのは理にかなっています。
この「ユーザーやステークホルダー」そのものが単一責任の原則が指す「システムを変更する理由」です。


さて、「たったひとりのユーザーやステークホルダー」と書きましたが、これは正確ではありません。
複数のユーザーやステークホルダーがシステムに対して同じ変更を望む可能性があるからです。
社内システムにおける経費精算を効率化する変更は、経理部の Aさんだけが望むものではありません。経理部の Bさんも Cさんも、もっと言えば経営層も喜んでくれるはずです。

このように同じ変更を望む人たちをグループにしたものを「アクター」と呼ぶことにします。
ソフトウェアを変更する理由は、1つの「アクター」のみが理由になっているかを意識すると良いでしょう😊

  • その関数やクラスはどのアクターのためのものですか?
  • 2つ以上のアクターのために作られていませんか?

解決策

「どのモジュールもたったひとつのことだけを行うべき」という定義とは別物だと言っておいてなんですが、この考え方が単一責任の原則を満たす上では非常に役に立ちます。
そして、ヒントになるのが関数やクラスの「命名」です。

関数やクラスに名前を付ける時に悩む方は多いと思いますが、それはどうしてでしょうか?
単純に数をこなしていない、「リーダブルコード」を読んだことない、などもあると思いすが、私が思うには 「1つ以上の責務を持っているから」です。
1個のことしかやっていない関数やクラスは命名が楽です。1個しかやっていないのだからそれを付ければ良いです。

関数に名前を付けるとき、考えてみたものの「ピンとこない」ことがあります。
そういう時は大体2つ以上のことを1つの関数の中でやろうとしています。
そうなったらリファクタリングをする時なのではないでしょうか🙂

関数レベルでこれを守っていると、非常に良い副作用もあります。
それは、関数がそのクラスに所属していることが適切かどうかが分かりやすくなることです。
よく、 is a の関係 などと言われますが、関数を分割することによって違和感が具体的になっていきます。


原理原則の理解にも力を入れていきたい今日この頃🤔

Discussion