質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

Q&A

解決済

1回答

4349閲覧

依存関係逆転の原則(DIP)は[UI層←→ビジネスロジック層]にも適用されるのか。

ikngtty

総合スコア11

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

0グッド

1クリップ

投稿2017/05/21 11:42

編集2017/05/22 10:39

依存関係逆転の原則(DIP)について。
以下のような状態を良しとする原則だと解釈しています。

・上位モジュールは下位モジュールのためのインターフェースを規定し、それに依存する。
・下位モジュールはそのインターフェースを実装する。
→ 依存関係が[上位→下位]から[上位←下位]に逆転される。(上位モジュールが下位モジュールの設計に対し主導権を握るようになる。)

さて、ここで以下のような一般的な3層アーキテクチャを例に考えます。

UI層 ↓ ビジネスロジック層 ↓ データアクセス層

これにDIPを適用させると、以下のような依存関係が理想となるように思われます。

UI層 ↑ ビジネスロジック層 ↑ データアクセス層

しかし実際のところ、一番主導権を握らせたい対象は基本的にビジネスロジック層だと思います。
この中ではビジネスロジック層が一番変更が少ないように思われますし、
「1つのビジネスロジックに対し複数のUIを実装して切り替える」
「1つのビジネスロジックに対し複数のデータアクセスを実装して切り替える」
という要件は非常によくあることだと思います。

そう考えると、理想は以下のような依存関係ではないでしょうか。

UI層 ↓ ビジネスロジック層 ↑ データアクセス層

ここで質問なのですが、

  1. 私のDIPの理解は正しいでしょうか。
  2. [UI層←→ビジネスロジック層]においてはDIPは例外的に適用できないのでしょうか。(こんな大きな例外があるなら、DIPはPrincipleというよりはただのPatternにすぎないように思えるのですが…。)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

akabee
ikngtty
akabee

2017/05/22 11:11

ビジネスロジック層ですと伝わります。また私の参考リンクではUI層が登場しないため疑問点が解消しないという点も理解しました。良い回答ができるかどうか分かりませんが、後ほど個人的に検討し、有益な回答ができそうであれば回答してみます。
akabee

2017/05/22 11:17

ビジネスロジック層に表現を変更された質問内容を再度読み返してみたのですが、1点だけ分からない点があり、それは「ビジネスロジック層が一番変更が少ないように思われますし、 」という部分です。一般的にはビジネスロジック層が最も変更が多い箇所と想定されますので前提が良く把握できなくなってきています。何か補足等あればご返答下さい。
ikngtty

2017/05/22 11:53

ビジネスロジックがビジネスルールをそのまま表現したものであるのに対し、UIはシステムへの要件に依るものと考え、ビジネスルールとシステム要件では後者の方が変更が多いかと感じていました。ただ、本当にそうかと言われると怪しく思えてきました…。ですが、理由が1つ減ってももう1つ残っているので、ビジネスロジックがシステムの核であり主導権を握るべきという見解は変わらないです。こちら(http://tech.cm55.com/wiki/Designs/DIP)やこちら(http://stackoverflow.com/questions/13390909/user-interface-depending-on-business-logic-layer-breaks-dependency-inversion-pri)でもビジネスロジック層が他から依存される形式を推奨しています。
guest

回答1

0

ベストアンサー

まず依存、主導権という言葉の定義を固めておきましょう。

依存とは、「他のものによりかかり、それによって成り立つこと」、主導権とは、「ある1つの要素が全体への大きな影響力を持つこと」というように理解できると思います。

依存関係逆転の原則とは上位モジュールが下位モジュールに依存しないようにし、下位モジュールが上位モジュールに対して依存するような設計にすることです。
これは言い換えれば、上位モジュールが下位モジュールの動作に影響されないように設計するということと同義です。

上記は非常に一般的な議論として用いることができ、下位モジュールが変更される度に上位モジュールに影響が及ぶような設計の場合、システムのメンテナンスの負荷が非常に高くなります。
例えば25箇所で利用されているような下位モジュールが変更され、その影響が上位モジュールに及ぶとした場合、下位モジュールを修正したいがために、上位の25箇所についても修正を必要とすることになります。
これは上位モジュールが下位モジュールの動作に依存してしまっているためです。上位モジュールの動作が下位モジュールの動作によって成り立ってしまっている(依存している)と言い換えるとわかりやすいと思います。またこのような状態の場合、システム全体への影響力は上位モジュールよりも下位モジュールのほうが高くなっている(主導権が下位モジュールにある)ことも理解できると思います。

上記はMVCモデルの議論等にも頻出する話題です。

また、依存性逆転の原則はもう一つ重要な主張をしており、UIは抽象に依存すべきだと言っています。これはこちらこちらの議論を見ていただくと分かってくると思うのですが、要するにUIとビジネスロジックは疎結合であるべきだと言っています。
これはUIとビジネスロジックの関係に関わらず一般的な議論としても非常にポピュラーな内容です。

さてここまでが伝わったとして、それでもなお質問文の「一番主導権を握らせたい対象は基本的にビジネスロジック層だと思います。 」という主張が果たして正しい主張だったかという議論になると思います。
システムの主導権はできるだけ下位にあってはいけないというのは一般的なコーディングの原則です。ビジネスロジックを変更したらそれに依存しているUIまで変更しなければならないなどというのは多少センスの悪い設計と言わざるを得ません。

上から1,2,3と3つの表示項目があったとして、上から名前、性別、生年月日を出力するUIがあったとします。それぞれの要素はビジネスロジックで取得しています。
ある日、元号出力だった生年月日を西暦出力に変えてくれとシステム要件が変わったとします。
このとき、修正するのはビジネスロジックだけで済ませたいです。ビジネスロジック側で元号出力しているロジックを西暦出力するように変更すれば、UIはそれに影響されずに勝手に西暦出力してくれるほうが、システムメンテナンスの負荷は低いです。

でもシステムの都合によって、ビジネスロジック側で西暦出力するように変更するとUI側も変更しなければならないとすると、修正対象がビジネスロジックとUIの2つになり、単純に修正の負荷が2倍になります。
しかしそのビジネスロジックを使っているUIが1つとは限りません。例えば30個のUIでそのビジネスロジックを用いていた場合、ビジネスロジック1つ修正したら30個のUI全ての表示が変更されてくれるほうが有り難いわけです。西暦出力にするだけでシステムの修正が30を超えるなんて、もしもっと大きな修正要望が出された場合にはどれだけの手間がかかってしまうのでしょうね。
こうなってしまうのも全て上位モジュール(UI)が下位モジュール(ビジネスロジック)に依存してしまっているためです。両者は疎結合でインターフェース等の抽象的なものを介して関連しており、どちらかの修正がどちらかに影響を与えないように設計すれば解決されると依存性逆転の原則は言っています。

追記依頼にて会話しているうちに、依存、主導権という言葉と実際のシステムの動作に誤解があるのではないかと考えましたので、このような説明をしてみました。

なおこの原則、いつ頃誰がどこで提唱したものなのかよく分かりませんが、下位が上位に依存する、という設計思想は個人的にはちょっと賛同しかねます。
文中にも何度も出現させましたが、上位、下位は疎結合であるべきだと私個人は思っていますし、依存性逆転の原則でも抽象に依存するべきだと主張しているあたり、下位が上位に依存すべきだというよりは、やはり各モジュール間の関係は疎結合であるべきだという内容が主張の本質だと私は理解しました。
下位が上位に依存するべきだ、などと画一的に理解してしまうと少し混乱を招いてしまうかもしれません。

投稿2017/05/23 00:08

akabee

総合スコア1947

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

akabee

2017/05/23 00:24

こちら(http://tech.cm55.com/wiki/Designs/DIP)の主張はちょっと著者の意図を掴みかねるのですが、こちら(https://stackoverflow.com/questions/13390909/user-interface-depending-on-business-logic-layer-breaks-dependency-inversion-pri)はUIとビジネスロジックは抽象に依存すべきだということでcloseされていると思います。 前者のページの意見は、間違った主張ではないと思うのですが、著書の内容をきちんと汲み取った上で主張されているように感じません。つまり本文中でも書いたとおり依存関係が下位から上位になるべきだというよりも両者は疎結合であるべきだというのがこの原則の主眼だと思いますので、そのあたりを汲み取っていない状態で書かれた文章に感じられました。(勿論ページ著者の方の主張も聞いてみたいところですが)
ikngtty

2017/05/23 01:07

ご丁寧に回答いただきありがとうございます。お陰様で理解が深まりました。 「依存性逆転」という言葉に囚われすぎていました。 そもそもの話になるのですが一箇所だけ理解が固まっていない箇所があって、「上位」「下位」という言葉の具体的な定義についてです。これもご教授頂けたら幸いです。
akabee

2017/05/23 04:06

一般化すると、呼び出し元が上位、呼び出されている側が下位という理解で良いと思います。 具体的には、例えばUIとビジネスロジックとデータアクセスの例を考えてみますと、UIモジュールはビジネスロジックモジュールが保持するデータを呼び出して表示し、ビジネスロジックモジュールはデータアクセス用のモジュールを呼び出してデータを取得します。 こちら(http://qiita.com/UWControl/items/98671f53120ae47ff93a)のCarとEngineの例ですと、CarからEngineを呼び出していて、Carが呼び出し元で上位、Engineが呼び出されている側で下位ということになります。その2つの間にはiEngineというインターフェース(抽象)が存在しており、依存性逆転の原則を体現しています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問