Strategy

strategy.png
strategy.png

1.作戦をクラス化する(インタフェース分離の法則)
2.そしてその作戦インタフェースをメンバ変数として持つ(継承よりコンポジションを好む

定義

Strategyパターンは一連のアルゴリズムを定義し、(振る舞いをクラス化して)
それぞれをカプセル化してそれらを交換可能にします。
Strategyパターンによって、アルゴリズムを使用するクライアントとは独立して、
アルゴリズムを変更できます。[4]

必要に応じて実行時でさえも簡単に拡張や変更のできる独自のクラス群に、鴨の振る舞いがカプセル化されていることを表します。[4]
設計原則の継承よりコンポジションを好む
継承は再利用性に優れていて、
コンポジションは保守性拡張性に優れている[4]

オブジェクトは、要求を実行するための戦略(strategy)を表現するオブジェクトに要求を委譲する。
オブジェクトは一つの状態しか持たないが、さまざまな要求のために多くの戦略を有することができる。[5]

親クラスが鴨で
飛べる鴨、いろいろな鳴き方の鴨がいる場合。
全部をサブクラス化するのではなく、
飛ぶ、鳴く、
という振る舞いのクラスを作るということ。

作り方

  1. インタフェースを複数、メンバとして持つabstractクラスを作る
  2. その抽象クラスの中で、インタフェースを使って関数を呼び出すだけの関数を書く。

親クラスは、振る舞いオブジェクトを持つ。
このオブジェクトはインタフェースクラスにしておく。

Step1.複数のインタフェースへの参照をメンバとして持つ抽象クラスを作る

package strategy;
public abstract  class Duck {
    FlyBehavior flyBehavior;
    QuackBehavior quackBehavior;
    public Duck(){}
    public abstract void display();
    public void performFly(){
        flyBehavior.fly();
    }
    public void performQuack(){
        quackBehavior.quack();
    }
    public void swim(){
        System.out.println("すべての鴨は浮かびます。おとりの鴨でも!");
    }
}

Step2.メンバとなるインタフェースとそれを実装したクラス

FlyBehavior.java QuackBehavior.java
package strategy;
public interface FlyBehavior {
    public void fly();
 
}
package strategy;
 
public interface QuackBehavior {
    public void quack();
 
}
package strategy;
 
public class FlyWithWings implements FlyBehavior {
 
    @Override
    public void fly() {
        System.out.println("飛んでいます!!");
 
    }
 
}
package strategy;
 
public class Quack implements QuackBehavior {
 
    @Override
    public void quack() {
        System.out.println("ガーガー");
 
    }
 
}
package strategy;
 
public class FlyNoWay implements FlyBehavior {
 
    @Override
    public void fly() {
        System.out.println("飛べません");
 
    }
 
}
package strategy;
 
public class Squeak implements QuackBehavior {
 
    @Override
    public void quack() {
        System.out.println("キューキュー");
 
    }
 
}

変数に代入されるオブジェクトがスーパータイプの任意の具象実装となれるように、
宣言する変数の型をスーパータイプ(通常は抽象クラスかインタフェース)にすべきです。
これにより、変数を宣言するクラスが、
実際のオブジェクトの型について知る必要がなくなります。[4]


interface-segregation mvc

サポートサイト Wikidot.com interface-segregationmvc