プログラミングマガジン

プログラミングを中心にIT技術をできるだけわかりやすくまとめます。

  • ホーム
  • オブジェクト指向
  • 【オブジェクト指向】「依存関係逆転の原則」について
 
 
     
  • サーバー言語  
    • Python
    • Ruby
    • PHP
    • SQL
  •  
  • インフラ  
       
    • AWS
    •  
    • 基本
    • Git
  • Web
       
    • Web開発
    • JavaScript
    • Vue.js
    • React
  •  
  • 設計  
       
    • 実装設計
    • DB設計
  • 問い合わせ
  

【オブジェクト指向】「依存関係逆転の原則」について

04.10

  • miyabisan2
  • コメントを書く

この記事は3分で読めます

SOLIDの観点から見たこの原則の私的見解

基本的にはSOLIDにおいて「バリエーションがあるコードを書く際に意識する原則の一つ」になります。

バリエーションを意識したコードを書く際に意識する際の原則として他には「オープンクローズドの原則」、「リスコフの置換原則」などがありますが、それらを別視点(モジュール依存関係的な視点)で言い換えた原則と言えるでしょう。(実装コード例はほぼ同じになる)概ね実装する際は、「依存関係逆転の原則」と「オープンクローズドの原則」、「リスコフの置換原則」はセットで意識する原則みたいなものとして捉えておくと良いでしょう。

【オブジェクト指向】「オープン・クローズドの原則」とは

依存関係逆転の原則とは?

上位レベルのモジュールは下位レベルのモジュールに依存すべきではない。どちらも抽象に依存すべきであるという原則。

上位モジュール

下位モジュールを呼ぶ。ユーザーが触れる部分。

  • 画面など

下位モジュール

上位モジュールから呼ばれる。例えば、外部通信などを行う。(ファイル、DB、各種通信など)

上記のように抽象に依存させましょうという感じの実装です。

DI(依存性の注入)

この外部から上位モジュールに対して下位モジュールを注入することをDI(依存性の注入)とも言います。「依存関係逆転の原則」を実装するには「DI(依存性の注入)」も同時に意識することになりますので覚えておきましょう。

【オブジェクト指向】「DI(依存性の注入)」、「DIコンテナ」について

原則違反の例

  • クライアントコードから直接「OracleDBからデータを取得する」というような具体的なコードを書いてしまうなど。

抽象は詳細に依存してはならない。詳細が抽象に依存すべきであるという原則。

例

  • 抽象:「ボタンを押したら保存する」、詳細:「ボタンを押したらOracleDBに保存する」

なぜこの原則を守った方が良いのか?

下位モジュールがないと動かないため上位モジュールの再利用性がない。

下位モジュールに依存している時点で「下位モジュールがないと動かない」というプログラムになってしまっているということになるため。Oracleなど特定のアーキテクチャに紐づいてしまっている画面などは、アーキテクチャが変わった場合にそちらのコードにすぐに再利用できなくなってしまいます。

抽象(ユーザーがやりたいこと)は変わりづらく、詳細(テクニカル部分)は変わりやすいため。

抽象(ユーザーがやりたいこと)は変わりづらいです。例えば、ATMに顧客が振り込むというシステムがあったら「ATMの振り込みボタンを押す」という動作だったり、「ATMで振り込み操作が行われたら何かに保存をする」というフローはなかなか変わりづらいためです。

逆に、詳細コード(テクニカル部分)は変わりやすいです。例えば、今はオンプレミスのOracleを使っていても、今後クラウドのAuroraに移行したいといった場合に詳細に依存していると上位モジュールの書き換えが必要になりコードの書き換えが大変になってしまいます。

ダミーコードやテストコードを書く際にも便利になる。

また、ダミーデータや、テストコードを記述するときも便利です。(例えば、テスト時はAmazonS3ではなくminioに接続するようにするなどの場合にも対応できます。)

具体的には、getDataというメソッドがあった場合にOracleからデータを取ってくるような本実装クラスがあった場合に、テストコードではOracleに接続せずに、getDataというMockのメソッドなどを作ってあげて返してあげるようにしてそのMockのクラス自体を外側からテスト対象のクラスに対して与えてあげます。(依存性の注入)

Mockを毎回書くのは大変

テストコードを書くためにMockを毎回書くのは大変です。そのためC#などの言語ではMoqなどのライブラリが用意されていたりします。(返すデータを都度setupできるツール。まあ、データを用意する手間という点ではそこまで変わらないですが。わざわざMock用のダミークラスを作る必要はなくなります。)

実リソースを使った方が良い場合もある

もちろん、実リソースを使ってテストをするということはできなくはないです。(テストするたびにDBのデータを削除して、真っさらなデータを投入し直して再度テストするみたいなことはできなくはないので。)、もし、例えばOracleでストアドを使っていて外部インフラにロジックがある場合などはそのようにテストせざるおえないでしょう。最近はビジネスロジックはプログラム言語で補完した方が良い設計という風潮はありますが。

下位モジュールの実装を強制化できる

下位モジュールを抽象に依存させることで下位モジュールの実装を強制化することができます。例えば、saveというメソッドを抽象クラスに追加したら全ての下位モジュールでsaveというメソッドを追加しなければなりません。

そうすることで上位モジュールのコードに影響を与えません(少なくともコンパイルエラーにはなりません)

スポンサーリンク
  • 2022 04.10
  • miyabisan2
  • コメントを書く
  • オブジェクト指向
  • Tweets Twitter
  • このエントリーをはてなブックマークに追加
  • LINEで送る

関連記事

  1. 2021 08.28

    【オブジェクト指向】「オープン・クローズドの原則」とは

  2. 2018 05.13

    【GoFのデザインパターン】「Proxy(プロキシ)」ってどんなパターン?

  3. 2018 05.13

    【GoFのデザインパターン】「Facade(ファザード)」ってどんなパターン?、設計方針なども。

  4. 2022 03.26

    【オブジェクト指向】「単一責任の原則」

  5. 2018 05.19

    【設計】クラス設計(オブジェクト指向設計)の基本(保守性、再利用性の高いソースコードを書くには?)

  6. 2021 12.13

    【オブジェクト指向】「ガーベジコレクション」の仕組み

  • コメント ( 0 )
  • トラックバック ( 0 )
  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

返信をキャンセルする。

【オブジェクト指向】「継承以外」で「似たような処理」を…

【オブジェクト指向】「DI(依存性の注入)」、「DIコ…

RETURN TOP

著者プロフィール

エンジニア歴10年で過去に業務系、Webデザイン、インフラ系なども経験あります。現在はWeb系でフロントエンド開発中心です。

詳細なプロフィールはこちら

スポンサーリンク

カテゴリー

  • Android
  • AngularJS
  • API
  • AWS
  • C++
  • CSS
  • C言語
  • DDD
  • DevOps
  • Django
  • Docker
  • Figma
  • Git
  • GitLab
  • GraphQL
  • Hasura
  • Java
  • JavaScript
  • Kubernetes
  • Laravel
  • linux
  • MySQL
  • Next.js
  • nginx
  • Node.js
  • NoSQL
  • Nuxt.js
  • Oracle
  • PHP
  • Python
  • React
  • Redux
  • Rspec
  • Ruby
  • Ruby on Rails
  • Sass
  • Spring Framework
  • SQL
  • TypeScript
  • Unity
  • Vue.js
  • Webサービス開発
  • Webデザイン
  • Web技術
  • インフラ
  • オブジェクト指向
  • システム開発
  • セキュリティ
  • その他
  • データベース
  • デザインパターン
  • テスト
  • ネットワーク
  • プログラミング全般
  • マイクロサービス
  • マイクロソフト系技術
  • マルチメディア
  • リファクタリング
  • 副業
  • 未分類
  • 業務知識
  • 生成AI
  • 設計
  • 関数型言語
RETURN TOP

Copyright ©  プログラミングマガジン | プライバシーポリシー