回答編集履歴
4
冗長な部分を修正
answer
CHANGED
@@ -1,40 +1,32 @@
|
|
1
|
+
既に回答が出揃ってる感ありますが、少しでもお役に立てればと思ったので回答させていただきます。
|
1
|
-
|
2
|
+
僕も初学の際に同じような疑問を持っていたので、僕なりにわかりやすくお伝えできればと思います。
|
2
3
|
|
3
|
-
#####前提
|
4
|
+
##### 前提
|
4
5
|
|
5
6
|
以下のようなアプリケーションであればインターフェースを利用するメリットはほとんどありません。
|
6
7
|
- 一人で開発するアプリケーション
|
7
8
|
- 一度作って終わる(作った後一切変更をしない)アプリケーション
|
8
9
|
- レイヤ化(MVC等)する必要のないアプリケーション
|
9
10
|
|
10
|
-
故に、上記
|
11
|
+
故に、上記に当てはまらないアプリケーション開発をイメージして説明させていただきます。
|
12
|
+
(ほとんどこのケースですが・・・)
|
11
13
|
|
12
14
|
|
13
|
-
#####説明
|
15
|
+
##### 説明
|
14
16
|
> 何のメリットがあるんですか?
|
15
17
|
|
16
|
-
【Who】
|
17
|
-
|
18
|
+
インターフェースの実装が増えても利用者はそれを意識せず形式的に利用できるというメリットがあります。
|
19
|
+
詳細は、例を踏まえて後述します。
|
18
20
|
|
19
|
-
【When】
|
20
|
-
インターフェースの実装が増えた時にメリット
|
21
21
|
|
22
|
-
【What】
|
23
|
-
インターフェースの実装が増えても利用者はそれを意識せず形式的に利用できるというメリット
|
24
|
-
|
25
|
-
|
26
|
-
【Why/How】
|
27
|
-
例を踏まえて後述
|
28
|
-
|
29
|
-
|
30
22
|
> 開発が短縮されるんですか?
|
31
23
|
|
32
|
-
長期的な目線で見ると短縮されることがあります。
|
24
|
+
上記のメリットがあるので、長期的な目線で見ると短縮されることがあります。
|
33
|
-
一
|
25
|
+
ただし、一度作って終わるものはファイルを余計に作成するだけなので逆に開発が延びます。
|
34
26
|
|
35
27
|
> バラバラな(派生化してその目的に特化した)クラスを統一するなら、最初からきちんと完璧に設計すれば早いと思うのですがどうでしょうか?
|
36
28
|
|
37
|
-
将来的に起こりうる変更を予測して、最初からきちんと完璧に設計できるのであれば、それに越したことはありません
|
29
|
+
将来的に起こりうる変更を予測して、おっしゃるように「最初からきちんと完璧に設計」できるのであれば、それに越したことはありません。
|
38
30
|
|
39
31
|
|
40
32
|
> わかりやすいような例や例えで教えてくれませんか?
|
@@ -46,25 +38,28 @@
|
|
46
38
|
そして、もしかしたら、将来的に原子力発電は廃止されて、それに変わる新たな発電方式が生み出されるかもしれません。その場合でも今まで通り「電気ちょーだい」というと電気が供給されるはずです。
|
47
39
|
このように、**利用者は、契約(インターフェース)によって、電源(実装)を意識しなくても、形式的に電気(メソッド)を利用することができます。**これがインターフェースの主な存在意義だと思います。
|
48
40
|
|
49
|
-
では、その考え方が
|
41
|
+
では具体的に、その考え方がどのように実装に活かされるのかを、簡単な例になりますが見ていきましょう。
|
50
|
-
|
42
|
+
TODO管理のアプリケーションをチーム(複数人)で開発する場面を想像してみてください。
|
51
43
|
|
44
|
+
0. まず、TODOのデータを保存する場所を考える必要がありますよね。
|
45
|
+
最初は、開発スピード等を重視して、この保存先にローカルのファイルを選んだとしましょう。
|
52
|
-
|
46
|
+
0. 次に、少なくともリクエストをコントロールする「クラスA」と、ローカルのファイルに対してTODOデータをCRUDする「クラスB」を実装すると思います。
|
47
|
+
※ここでは「クラスA」と「クラスB」との間にインターフェース(契約)を設けないでアプリケーションを作り上げたとします。
|
48
|
+
0. リリース後、ユーザーが順調に増え、アプリケーションがまともに動かなくなってきました。
|
49
|
+
0. スケーラブルな構成への変更を余儀なくされ、データの保存先をローカルのファイルから、クラウドのRDBMSへ移行することを決めます。
|
50
|
+
0. そして、誰かがRDBMSに対してTODOデータをCRUDする「クラスC」を実装しようとします。
|
53
51
|
|
54
|
-
|
52
|
+
ここからが悲劇の始まりです。
|
55
|
-
0. そうすると、少なくとも、リクエストをコントロールする「クラスA」の作成と、RDBMSに対してTODOデータCRUDするメソッドを持った「クラスB」を作成すると思います。
|
56
|
-
|
53
|
+
過去に誰かが実装した「クラスA」は「クラスB」からデータをもらう前提で実装されています。
|
57
|
-
0. しかし1年後、オープンソースのRDBMSに深刻な脆弱性が見つかり、それを使い続けていくことが難しくなったとします。
|
58
|
-
0. そこで、高速でセキュアな無料で使えるクラウドのデータストレージサービス(以下「クラウド」)があったとして、それに移行することを決めたとします。
|
59
|
-
0. そうすると、クラウドに対してTODOデータをCRUDする「クラスC」を作成することになると思います。
|
60
|
-
|
54
|
+
今回の変更で「クラスA」は「クラスB」ではなく「クラスC」からデータをもらうことになるので「クラスC」の実装・テストに加え「クラスC」の実装を知った上で「クラスA」の修正・テストも必要になります。
|
55
|
+
せっかく責務を分離してクラスを分けていたのに、結局クラスAへの影響も大きそうですね。。。
|
61
56
|
|
57
|
+
もし、最初から「クラスA」と「クラスB(TODOデータをCRUDするクラス)」との間にインターフェース(契約)があれば、今回も「クラスC」がそのインターフェースを実装することによって戻り値の型は保証されるので「クラスA」は「クラスC」の実装を知る必要がありません。
|
58
|
+
そして多くの場合「クラスA」にほとんど影響はありません。
|
59
|
+
また、この先NoSQLに対してCRUDを行う「クラスD」、新型のDBに対してCRUDを行う「クラスE」・・・が現れても「クラスA」と「TODOデータをCRUDするクラス」との間にインターフェース(契約)があるかぎり「クラスA」はそのクラスの実装を全く意識する必要はありません。
|
62
|
-
|
60
|
+
「クラスA」は「クラスB〜E・・・」がどんな実装をしてどこからデータを取ってこようが、それらのクラスが契約通りに実装してくれれば「クラスA」に変更が加わることは原則ありません。
|
63
61
|
|
64
|
-
|
65
|
-
上位レイヤーの「クラスA」は、下位レイヤーの「クラスB・・D」がどんな実装をしてどこからデータを取ってこようが、同じ型の値を契約どおりに返してくれれば、「クラスA」に変更が加わることは原則ありません。
|
66
|
-
|
67
|
-
実用例の一部を紹介してきましたが、前述の通り、役割ごとにカテゴライズされた**各レイヤー間にインターフェース(契約)を設ける**ことによって、**各レイヤー間を疎結合にし**(依存度を低くし)、**変更に強いアプリケーション作ることができる**
|
62
|
+
以上、簡単な例でしたが前述の通り、役割ごとにカテゴライズされた**各レイヤー間にインターフェース(契約)を設ける**ことによって、**各レイヤー間を疎結合にし**(依存度を低くし)、**変更に強いアプリケーション作ることができる**
|
68
63
|
これがインターフェースを利用する最大のメリットと言っても過言ではないと思います。
|
69
64
|
|
70
65
|
#####補足
|
3
edit
answer
CHANGED
@@ -39,7 +39,7 @@
|
|
39
39
|
|
40
40
|
> わかりやすいような例や例えで教えてくれませんか?
|
41
41
|
|
42
|
-
一般的に、インターフェースとは契約と言われ
|
42
|
+
一般的に、インターフェースとは「契約」と言われることが多いです。
|
43
43
|
日常生活で身近な契約って何だろて考えたときに、電力会社との契約とかがわかりやすいかなと思います。
|
44
44
|
電力会社と契約済みであれば、極端ですが「電気ちょーだい」というと電気が供給されると思います。
|
45
45
|
この時、供給された電気はどこでどのように生み出されたのか意識したことはありませんよね?(原子力発電なのか、火力発電なのか、風力発電なのか)
|
@@ -69,4 +69,4 @@
|
|
69
69
|
|
70
70
|
#####補足
|
71
71
|
インターフェースのメリットを最大限に活かす仕組みとしてDependency Injection(依存性の注入)というデザインパターンがあります。
|
72
|
-
少々複雑な上、質問に対する回答にはならないのでここでは触れませんが、インターフェースを理解された次のステップとして、知っておくと良いと思います。
|
72
|
+
少々複雑な上、質問に対する回答にはならないのでここでは触れませんが、インターフェースを理解された次のステップとして、知っておくと良いと思います。
|
2
補足
answer
CHANGED
@@ -47,7 +47,7 @@
|
|
47
47
|
このように、**利用者は、契約(インターフェース)によって、電源(実装)を意識しなくても、形式的に電気(メソッド)を利用することができます。**これがインターフェースの主な存在意義だと思います。
|
48
48
|
|
49
49
|
では、その考え方が、具体的に実務でどのように活かされているのかを、簡単な例にはなりますが記載させていただきます。
|
50
|
-
ちなみに以降は、レイヤ化アーキテクチャ(MVC等)の知識が前提になります。
|
50
|
+
ちなみに以降は、レイヤ化アーキテクチャ(MVC等)の知識が前提になります。
|
51
51
|
|
52
52
|
それでは、簡単なTODOを管理するアプリケーションを開発する場面を想像してください。(TODOだとCRUDが基本ですが、ここではReadにフォーカスします)
|
53
53
|
|
@@ -56,12 +56,17 @@
|
|
56
56
|
0. そのまま、「クラスA」と「クラスB」との間にインターフェース(契約)を設けないでアプリケーションを作り上げたとします。
|
57
57
|
0. しかし1年後、オープンソースのRDBMSに深刻な脆弱性が見つかり、それを使い続けていくことが難しくなったとします。
|
58
58
|
0. そこで、高速でセキュアな無料で使えるクラウドのデータストレージサービス(以下「クラウド」)があったとして、それに移行することを決めたとします。
|
59
|
-
0. そうすると、クラウドに対してTODOデータをCRUDする「クラスC」を
|
59
|
+
0. そうすると、クラウドに対してTODOデータをCRUDする「クラスC」を作成することになると思います。
|
60
|
-
0. そのため、「クラスA」は「クラスC」がデータをどこから取ってきて、どういう型で返却してくるかを知る必要があります。
|
60
|
+
0. そのため、「クラスA」は、「クラスB」と同様に「クラスC」がデータをどこから取ってきて、どういう型で返却してくるかを知る必要があります。
|
61
61
|
|
62
62
|
つまり、「クラスC」の戻り値の型が保証されていないので、「クラスC」のテストに加え、「クラスA」のテストも必要になりますし、場合によっては、「クラスA」を修正することになります。
|
63
63
|
|
64
64
|
もし「クラスA」と「データをCRUDするクラス」との間に、最初から共通のインターフェース(契約)があれば、データの取得元は変わっても戻り値の型は保証されるので、「クラスA」は「クラスC」の実装を知る必要がありませんし、この先、ファイルに対してCRUDを行う「クラスD」、NoSQLに対してCRUDを行う「クラスE」、メモリキャッシュに対してCRUDを行う「クラスF」・・・が現れても、「クラスA」との間にインターフェース(契約)がある以上、「クラスA」は全く実体を意識する必要はありません。また、多くの場合「クラスA」に影響はありません。
|
65
|
+
上位レイヤーの「クラスA」は、下位レイヤーの「クラスB・・D」がどんな実装をしてどこからデータを取ってこようが、同じ型の値を契約どおりに返してくれれば、「クラスA」に変更が加わることは原則ありません。
|
65
66
|
|
66
|
-
実用例の一部を紹介しましたが、前述の通り、役割ごとにカテゴライズされた**各レイヤー間にインターフェース(契約)を設ける**ことによって、**変更に強いアプリケーション作ることができる**
|
67
|
+
実用例の一部を紹介してきましたが、前述の通り、役割ごとにカテゴライズされた**各レイヤー間にインターフェース(契約)を設ける**ことによって、**各レイヤー間を疎結合にし**(依存度を低くし)、**変更に強いアプリケーション作ることができる**
|
67
|
-
これがインターフェースを利用する最大のメリットと言っても過言ではない
|
68
|
+
これがインターフェースを利用する最大のメリットと言っても過言ではないと思います。
|
69
|
+
|
70
|
+
#####補足
|
71
|
+
インターフェースのメリットを最大限に活かす仕組みとしてDependency Injection(依存性の注入)というデザインパターンがあります。
|
72
|
+
少々複雑な上、質問に対する回答にはならないのでここでは触れませんが、インターフェースを理解された次のステップとして、知っておくと良いと思います。
|
1
edit
answer
CHANGED
@@ -29,7 +29,7 @@
|
|
29
29
|
|
30
30
|
> 開発が短縮されるんですか?
|
31
31
|
|
32
|
-
長期的な目線で見ると短縮されます。
|
32
|
+
長期的な目線で見ると短縮されることがあります。
|
33
33
|
一発ものでは、ファイルを余計に作成することになるので逆に開発は長くなります。
|
34
34
|
|
35
35
|
> バラバラな(派生化してその目的に特化した)クラスを統一するなら、最初からきちんと完璧に設計すれば早いと思うのですがどうでしょうか?
|
@@ -46,7 +46,7 @@
|
|
46
46
|
そして、もしかしたら、将来的に原子力発電は廃止されて、それに変わる新たな発電方式が生み出されるかもしれません。その場合でも今まで通り「電気ちょーだい」というと電気が供給されるはずです。
|
47
47
|
このように、**利用者は、契約(インターフェース)によって、電源(実装)を意識しなくても、形式的に電気(メソッド)を利用することができます。**これがインターフェースの主な存在意義だと思います。
|
48
48
|
|
49
|
-
では、その考え方が、具体的に実務でどのように活かされているのかを、
|
49
|
+
では、その考え方が、具体的に実務でどのように活かされているのかを、簡単な例にはなりますが記載させていただきます。
|
50
50
|
ちなみに以降は、レイヤ化アーキテクチャ(MVC等)の知識が前提になります。DIの知識なんかもあるとさらに理解が深まると思います。
|
51
51
|
|
52
52
|
それでは、簡単なTODOを管理するアプリケーションを開発する場面を想像してください。(TODOだとCRUDが基本ですが、ここではReadにフォーカスします)
|
@@ -63,5 +63,5 @@
|
|
63
63
|
|
64
64
|
もし「クラスA」と「データをCRUDするクラス」との間に、最初から共通のインターフェース(契約)があれば、データの取得元は変わっても戻り値の型は保証されるので、「クラスA」は「クラスC」の実装を知る必要がありませんし、この先、ファイルに対してCRUDを行う「クラスD」、NoSQLに対してCRUDを行う「クラスE」、メモリキャッシュに対してCRUDを行う「クラスF」・・・が現れても、「クラスA」との間にインターフェース(契約)がある以上、「クラスA」は全く実体を意識する必要はありません。また、多くの場合「クラスA」に影響はありません。
|
65
65
|
|
66
|
-
実用例の
|
66
|
+
実用例の一部を紹介しましたが、前述の通り、役割ごとにカテゴライズされた**各レイヤー間にインターフェース(契約)を設ける**ことによって、**変更に強いアプリケーション作ることができる**
|
67
67
|
これがインターフェースを利用する最大のメリットと言っても過言ではないでしょう。
|