オブジェクトオブジェクトの概要10-11


10.継承とコード再利用


繰り返しコード


重複を作成しないでください.一次、一次原則または単点制御原則と呼ばれる.
コードを繰り返す弊害をよく知っていると思います.さらに深刻なのは、重複を除去せずに重複コードを保持すると、より大きな重複が発生します.
ちなみに、ここでいう繰り返しはコードの形が同じだけではありません.コードの外観は似ていますが、変更点が異なる場合は重複しません.(登録名と会員加入機能コードが同じで団結することはできません.)

継承


継承はコード再利用に使用できます.
ただし、継承は、継承された親と継承された子を強く縛ります.考えずに継承すれば、親階級と子供階級が団結する.
具体的にどんな問題があったか見てみましょう
不要なインタフェース継承問題<=スタッククラスは、Vectorクラスのindex add機能に関連するインタフェースを継承します.
メソッドオーバーライドの問題.<=継承の欠点は、親の方法の実現方法を詳しく理解する必要があることです.
親と子の同時修正の問題
  • 脆弱なベースクラスの問題
    継承を使うのは避けられない根本的な弱点だ.
  • 改善する

  • 抽象に依存
    2つのメソッドが似ているように見える場合は、相違をメソッドとして抽出し、共通点を親に送信します.
    変化(相違)から不変(共通点)を分離する.
  • public abstract class AbstractPhone {
      //...
      public Money calculateFee() {
        //...
        result = result.plus(calculateCallFee(call));
      }
      abstract protected Money calculateCallFee(Call call);
    }
    
    public class Phone extends AbstractPhone {
        //...
        @Override
        protected Money calculateCallFee(Call call){
        	//...
        }
    }
    
    public class NightlyDiscountPhone extends AbstractPhone {
        //...
        @Override
        protected Money calculateCallFee(Call call){
        	//...
        }
    }

    特定のクラスは抽象クラスに依存する
    抽象クラスでは、具体的なメソッドは抽象メソッドに依存します.
    できるだけ具体的な子供を抽象的な子供に頼らせる.

  • データが往復移動する関数に名前を付けるときは、get、setだけでなく、コラボレーション脈絡を表示する関数に名前を付けます.(ep buy, sell)

    それも。


    課税ロジックを追加すると、どのような変化が発生しますか?
    汎用論理部分calculateFeeを修正するだけでいいのですが、そうではありません.新しいメンバー変数が追加されたため、サブクラスはsuperキーを使用して新しいメンバー変数を登録する必要があります.
    継承して共通点を抽出し、抽象化することで、名前がきれいになっても、子供と親の間で避けられない依存性をもたらす.

    11.合成と柔軟設計


    継承関係:is-a関係、ホワイトボックスの再使用(内部露出実施)
    合成関係:has-a関係、ブラックボックス再使用(インタフェースで囲まれた)
    コードを再使用するには、クラス継承よりもオブジェクト合成の方が良い方法です.
    継承を使用する場合、問題の合成を使用しても発生しません.
    不要なインタフェースの継承を回避
    依存オブジェクトのメソッドは常に共通インタフェースに囲まれているため,外部オブジェクトのメソッド実装は影響を受けない.
  • 級爆発(類爆発)
    コンビネーション爆発とも呼ばれます.組合せは条件の結合であり,条件が独立している場合,各条件の仮定数に組合せ爆発的に増加する現象が現れる.
  • 継承を使用すると、独立した条件とクラスの間に強力な結合が発生するため、各条件にクラスを作成する必要があります.
    ただし、合成を使用して抽象的なキャラクタオブジェクトをパラメータとすると、独立条件と対応する条件が合成されたクラスと弱い結合性を形成し、以降の実行時に特定のオブジェクトを注入するように柔軟になります.

    かき混ぜる


    合成が実行時にオブジェクトを組み合わせる再利用方法である場合、ミキシングはコンパイル時に必要なコードセグメントを組み合わせる再利用方法である.
    ミックスは継承よりも合成に近い方法です.特定のオブジェクトと依存するコードをclass codeから除外することで、class内部を低結合状態に保つ.
    //trait
    trait RateDiscountablePolicy extends BasicRatePolicy{
      val discountAmount: Money;
      
      override def calculateFee(phone: Phone):Money = {
      	super.calculateFee(phone);
        //...
      }
    }
    
    //use
    class RateDiscountableRegularPolicy(amount: Money, seconds: Duration, ...)
    extends RegularPolicy(amount, seconds)
    with RateDiscountablePolicy;
    
    //instance
    new RegularPolicy(Money(100),...)
    with RateDiscountablePolicy
    with TaxablePolicy {
    //...
    }
    mixinのtrait内部superは合成オブジェクトの共通インタフェースであり,カプセル化された演算のみを提供する.また,traitのextends構文は継承を意味するのではなく,マージ可能なオブジェクトの制限を意味する.trait自体とtraitを適用するクラスとの間には共通インタフェースが分離される.
    したがって,クラスコードを記述した後,複数のtrait追加機能を組み合わせることも問題ない.合成が実行時に実際のオブジェクトを注入して機能を組み合わせる場合、mixinはコンパイル時に作成したクラスにフィーチャーを結合して機能を組み合わせる.

    継承は、各条件の組合せの結果を事前に生成します.
    合成は、予め結合された生成物を作製するのではなく、運転時に依存性注入により所望の生成物を組み合わせて使用する.
    Mixinはコードを記述する過程で,必要に応じて条件を組み合わせて結果を生成し,予め結合した結果を作成するのではない.