63837


まず私はプログラミング初心者です。業務経験などありません。独習C#を一通り読んでGoFを覚えた(あまり理解はしていません)程度の知識です。

本題です。Clean
Architectureという本のISPの解説を読んでいただくのが早いと思いますが、一応解説を書きます。クラス図は次のサイトに載っていますので日本語を読むのが面倒な場合は該当箇所を見てください(<https://scrapbox.io/mwtndmik/Clean_Architecture>)。まずOPSというクラスがop1,op2,op3というメソッドを持っています。そしてUser1,User2,User3がそれぞれop1,op2,op3のみを使っています。このとき「op2のコードを変更したときに、User1の再コンパイルと再デプロイが必要になる」と書いてあります。  
これを改善するためにOPSがU1Ops,U2Ops,U3Opsというインターフェース(それぞれop1,op2,op3を実装する必要がある)を継承し、User1,User2,User3はそれぞれのインターフェースを使用します。このとき「OPSに変更があったとしても、もしそれがUser1に関係のない部分であれば、User1の再コンパイルと再デプロイは不要になる」と書かれています。

疑問点1:なぜUser1の再コンパイルなどが必要になるのかがわかりません（どのような仕組みでこうなるのか）。あるいは再コンパイルが必要になるものとそうでないものの違いはどのように判断されるのでしょうか。  
疑問点2:そもそもUser1が何なのかがわかりません、これはクラスなのでしょうか。  
疑問点3:インターフェースを使って改善した後にUser1に関係のある部分を変更した場合、User1の再コンパイルなどは必要になるのでしょうか。

これらの疑問を解決するために日本語や英語でいろいろと検索をしたつもりですが、解決できなかったので質問しました。質問が曖昧だと思った場合はそれが明確になるように促していただけると幸いです。なにか参考になりそうなサイトや本があれば最悪それだけ提示していただいても結構です。元の本に何らかの言語でソースコードが書いてあったわけではありません。ここで質問をするのは初めてなのでなにかおかしなことがあれば言ってください。


CC BY-SA 4.0
2020-03-14T08:27:21.033
63824
2020-03-15T00:05:35.637
2020-03-14T14:25:43.057
19110
38207
question
アーキテクチャ
Clean ArchitectureのISPの説明でUser1の再コンパイルが必要になる理由がわかりません


>
> 疑問点1:なぜUser1の再コンパイルなどが必要になるのかがわかりません（どのような仕組みでこうなるのか）。あるいは再コンパイルが必要になるものとそうでないものの違いはどのように判断されるのでしょうか。

同じ質問が [Interface Segregation Principle in Clean
Architecture](https://softwareengineering.stackexchange.com/questions/384787/interface-
segregation-principle-in-clean-architecture)
に上がっていました。しかし、そこの回答でも現在使われているようなプログラミング言語ではUser1の再コンパイルは必要ではないし、話題をそこにフォーカスさせるのも例として不適切と書かれています。なので、気にしなくていいと思います。

試しに手元でJavaとC++で同じことを試してみましたが、OPSの関数の実装を修正してコンパイル（とリンク）が走るのはOPSのモジュールだけです。OPSの関数名（メソッドシグネチャ）を変えると当然関数名を変えたクラスもコンパイルが走りますが、それと関係ないクラスまでリコンパイルする必要はありません。

> 疑問点2:そもそもUser1が何なのかがわかりません、これはクラスなのでしょうか。

クラスという認識でいいと思います。

例えばJavaのWEB開発っぽく書くと

  * `class User1Controller`
  * `class User2Controller`
  * `class User3Controller`

がそれぞれ抽象クラス（＝インターフェース）として

  * `interface U1Ops`
  * `interface U2Ops`
  * `interface U3Ops`

を呼び出していて

具象クラス（実装）

  * `class Ops implements U1Ops, U2Ops, U3Ops`

interfaceを作ってない場合、具象クラスの実装の修正がそのままUser1,2,3に影響します（引数や返り値の型など）。interfaceを作っておけば具象クラス側の修正だけで済みます。  
インターフェースを分離することで、具象クラスの変化（例えば利用してるライブラリ・フレームワークの変更、仕様の変更、利用するはずのAPIの変更）に巻き込まれないようになる。

みたいな感じになると思います。

> 疑問点3:インターフェースを使って改善した後にUser1に関係のある部分を変更した場合、User1の再コンパイルなどは必要になるのでしょうか。

疑問点１の回答と同じで、ISPの話題で再コンパイルのことは気にしないでいいです


CC BY-SA 4.0
2020-03-14T15:42:40.183
63837
2020-03-14T16:14:26.733
2020-03-14T16:14:26.733
4715
4715
63824
answer


コメントにかけないので、ここに。ちょっと試してみました。下記のように、OPSのpublic static
finalな定数を変更したタイミング（のみ）でUser1のハッシュ値が変わります。（ビルド結果が変わる＝再ビルド必要）

[code]

    find . -type f -exec md5sum {} \; |grep step|grep User1
    (1)2368f868b0662a860516cef4a06b22c0 *./step0/User1.class
    ★(2)443dd309c307113720494576bdc8ec13 *./step1/User1.class 定数(static final)の値を変更した場合。
    (3)443dd309c307113720494576bdc8ec13 *./step2/User1.class (2)のfinal変数を変更した場合 
    (4)443dd309c307113720494576bdc8ec13 *./step3/User1.class (3)のfinalメソッドを変更した場合
    (5)443dd309c307113720494576bdc8ec13 *./step4/User1.class (4)のメソッドを変更した場合
    
[/code]


CC BY-SA 4.0
2020-03-15T00:05:35.637
63848
2020-03-15T00:05:35.637
10174
63824
answer