読者です 読者をやめる 読者になる 読者になる

kikki's tech note

技術ブログです。UnityやSpine、MS製品など技術色々について解説しています。

雑談:Dependency Inversion PrincipleとDependency Injectionについて

雑談

本章では、今回、開発に関する雑談をつらつらと書き殴ります。

プログラミングの設計について

プログラミングの成果物は、コーディングはもちろん、それ以前の設計思想に対しても依存します。高品質かつ柔軟な設計は、運用保守段階において、非常に有利に働きます。そのため、「動くこと」を目標とするのではなく、「後の人のために」を目標として設計できると、プロジェクトはもちろん自身も幸せになれるかと思います。

手続き型指向

手続き型指向言語では、静的な性質を表現する構造体と、動的な性質を表現する関数で大きく構成されます。考え方の軸となるのが、コンピュータに命令を促す関数です。ただこれは、コンピュータの視点に立った開発であるため、開発者に視点に立った考え方が必要となっていました。

オブジェクト指向

そこへ、オブジェクト指向言語が誕生しました。オブジェクト指向言語では、モノが主体となる考え方となっていて、モノを定義したクラスという箱の中に静的な性質を表現するメンバと動的な動作を表現するメソッドがあります。

学業で学ぶオブジェクト指向の弊害

このクラスは、学校や書籍で習った場合、クラスの中に別のクラスを保有するケースが多く説明例としてあります。iPhoneで例えると、iPhoneの中のパーツに村田製作所コンデンサエルピーダのメモリ、ソニーのカメラが使われているといったケースです。本来、iPhoneの中のカメラやメモリはどこの企業の製品と代替しても、機能(役割)としては変わらないはずです。しかし、カメラを他の企業のカメラに変更した場合、品質面で何かが変わります。ここでもし仮に、iPhoneのカメラを別の企業のカメラと交換した場合、サイズや電力要件等でうまく交換ができないはずです。
これは、プログラミング言語でも同じことがいえます。プログラミングでも他のクラスに依存するクラス設計となった場合、機能の代替・追加といった仕様変更に耐えれない設計となります。これを改善するために、他のクラスに依存しない設計が求められます。

Dependency Inversion Principle と Dependency Injection

一つの考え方として、 Dependency Inversion Principle(DIP)「依存性逆転の原則」という考え方があります。これは、*1クラスの中に他のクラスは持たず、機能だけを定義したインタフェースだけを持たせる思想です。インタフェースだけをもたせることで、特定のクラスに依存しない柔軟なクラスとなります。
また、DIPを発展させた考え方として、Dependency Injection(DI)「依存性の注入」があります。これは、*2クラス内でインタフェースを用いたとしても、オブジェクトを生成しないということです。iPhoneを例とすると、iPhoneiPhone自身の機能としてカメラを使用するために、ソニー製カメラを一から作る責任を負うのではなく、カメラという箱をiPhoneに導入するといったアプローチを取るべきという考えです。

これらの考え方をプログラム例として、以下に示します。

public interface ICamera
{
    void TakePhoto();
}

public class SonyCamera : ICamera
{
    void TakePhoto()
    {
        // SonyCameraでの処理を記述
    }
}

// DIPとDIを実現するために、他のクラスが存在せず、オブジェクト生成も行っていません
public class iPhone
{
    private ICamera _cameraItem;

    // コンストラクタベースの依存性注入
    public iPhone(ICamera icamera)
    {
        this._cameraItem = icamera;
    }

    public void DoSomething()
    {
        this._cameraItem.TakePhoto();
    }
}

public class Main
{
    // ここでは説明のために、例外的に、オブジェクトを生成しています
    var smartPhone = new iPhone(new SonyCamera());
    smartPhone.DoSomething();
}

iPhoneのクラスでは、固有のクラスを持たず、動作だけを定義したカメラのインタフェースを保有しています。このような設計とすることで、実体となるカメラがSonyからCanonなどに変更となった場合でも容易に使用変更が可能となります。

筆休め

業務の現場レベルでは、仕様変更に柔軟なプログラミングを心がけて実施しますが、プロジェクトメンバの技術レベルによって大きく成果物の品質が変わるのが現状です。そのため、可能な限り、高レベルな品質を基準に社内人材の育成を心がけていくほうがいいかと思われます。

以上、「雑談:Dependency Inversion PrincipleとDependency Injectionについて」でした。

*1:簡単に説明すると

*2:非常に簡潔に説明すると

※無断転載禁止 Copyright (C) 2015 kikkisnrdec All Rights Reserved.