オブジェクトオブジェクトの概要8~9


8.依存性の管理


オブジェクトに依存する必要がある場合...


≪実行ポイント|Run Point|emdw≫:依存するオブジェクトを正常に実行するには、実行時に依存するオブジェクトが存在する必要があります.
≪実装時間|Implements Time|emdw≫:依存オブジェクトが変更された場合は、依存オブジェクトのクラスコードを同時に変更する必要があります.

ポイント依存分類

//Movie
public class Movie{
  private DiscountPolicy discountPolicy;
  //...
  
  public Movie(String title, ..., DiscountPolicy discountPolicy){
    this.discountPolicy = discountPolicy;
    //...
  }
  //...
}

//Main
Movie movie = new Movie(new AmountDiscountPolicy(...), ...);
コンパイル時間依存性:コード単位依存性,MovieクラスはDicountPolicyクラスの影響を受ける.
ランタイム依存性:ランタイム依存性.Movieオブジェクトを作成するにはAmountDiscountPolicyオブジェクトが必要です.
コンパイル時には,抽象クラスに依存し,実行時に特定のオブジェクトに依存する方式で柔軟な設計を想定することができる.
コンテキストの独立性
特定のクラスに依存することは、特定のクラスのインスタンスがどのコンテキストで使用されるかを示すことに等しい.コードを記述する際には、特定のコンテキストに最大限依存してはならない.

依存性の解決


分散接続のコンパイル時間依存性は、具体的に実行するために実行時依存性に変更する必要があります.
1)オブジェクトの作成時に作成者を使用して依存性を解決
2)オブジェクト作成後、setterメソッドによる依存性の解決
3)メソッド実行時にパラメータを使用して依存性を解決する(一時的に依存する場合)
通常は1)と2)を混合して使用します.+Factoryモードを使用すると、クライアントへの依存性も低下します.

フレキシブル設計の推奨事項


  • 依存性と結合度は,すべての依存性が悪いわけではないが,過度な依存性はよくない.再利用可能な程度にのみ依存する.

  • 知識が結びつく.

  • 抽象化に頼る.
    特定のクラス=>抽象クラス=>インタフェースは、オブジェクトを使用するために必要な知識を減らします.

  • newは有害です.
    オブジェクトを作成すること自体が、複数のオブジェクトを理解することです.生成される行為自体が依存性を引き起こすことを覚えておいてください.
    ただし、コラボレーションのデフォルトオブジェクトを設定するように、依存性を放棄して利便性を得る場合が多いので、盲目的な作成に反対しないでください.

  • 標準類への依存は無害である.
    依存性が問題となる場合,依存するオブジェクトが変更される可能性がある.標準クラス、長時間検証されたライブラリなどは信頼性と依存性があります.

  • 未指定の依存性は有害である.
    特定の方法が何かに依存している場合は、必ず標識に表現しなければならない.今後,方法実装部分のみに現れる依存性を見つけることは困難である.
  • //Bad
    public void show(){
      Movie movie = new Movie()
    }
    //Modefied
    public void show(Movie movie){
    	//...
    }
  • コンテキスト独立=>組合せ
  • 9.柔軟な設計


    開放閉鎖の原則


    Open-Closed Principle
    ソフトウェアオブジェクトは、拡張では開いているが、修正では閉じている必要があります.
    核心は抽象化に頼ることだ.何を隠すか、何を見せるかを真剣に考えてこそ、良いデザインが得られる.
    具体的には,コンパイル時間依存性と実行時間依存性を多形性で分けることを提案する.

    作成を無効にする


    柔軟な設計を望む場合は、生成されたコードと使用されているコードを分けるべきです.
    ソフトウェアシステムは、依存性の開始と開始後の実行段階を分離しなければならない.[288page]
    Factory Object
    設計を容易にするために人為的に作成されたPure Fabrication.生成に関する責任を一方に集中する.
    Dependency Injection
    分離を作成および使用する場合は、実行時に生成されたオブジェクトを使用者に注入する必要があります.これを依存注入と呼ぶ.注入法は上記の依存性を解決する部分で議論した.

    Service Locator


    Service Locatorモードと呼ばれる設計にのみ依存性を注入するオブジェクトを作成できます.
    サービスLocatorで依存性を管理するため、使用するオブジェクトの一方が使用するオブジェクトの生成情報を知る必要はありません.
    public class Movie{
      private DiscountPolicy discountPolicy;
      
      public Movie(String title, Duration runningTime, Money fee){
        this.title = title;
        this.runningTime = runningTime;
        this.fee = fee;
        // ServiceLocator가 의존성 주입 담당.
        this.discountPolicy = ServiceLocator.discountPolicy();
      }
    }
    しかし、問題はサービスLocatorが依存性を隠していることです.MovieのインタフェースにはDiscountPolicyに依存する情報はなく,依存性を注入する部分もService Locatorに隠されている.
    しかし、サービスLocatorが計画的に悪いという意味ではありません.正確に言えば、これは隠れた依存性が悪いことを意味する.

    依存性逆転の原則(DIP)

  • 上級モジュールは、下位モジュールに依存することはできません.私たち二人とも抽象化に頼ってみましょう.
  • 抽象化は具体的な事項に頼ることができない.具体的な事項は抽象化に頼らなければならない.
  • 番外包装の場合も抽象部分と具体部分を区別します.

    上記の構成は、DiscountPolicyが具体的な政策に縛られ、具体的な事項変更時のMovieにも影響します.
    しかし、底部では、具体的な政策が変化してもDicountPolicyから分離されるため、Movieには影響しない.

    柔軟性の推奨事項


    柔軟な設計は柔軟性が必要な場合にのみ正しい.
    柔軟にデザインされた潜在的なセリフは理解しにくいデザインであることを覚えておいてください.