《Head First 設計模式》:策略模式

正文

1、定義

策略模式定義了算法族,分別封裝起來,讓它們之間能夠相互替換,此模式讓算法的變化獨立於使用算法的客戶。算法

要點:ide

  • 策略模式把系統中會變化的部分抽出來封裝。

2、實現步驟

一、建立策略接口

/**
 * 策略接口
 */
public interface Strategy {

    /**
     * 執行策略行爲
     */
    public void perform();
}

二、建立策略接口的實現類

(1)策略實現類 A

/**
 * 策略實現類A
 */
public class StrategyImplA implements Strategy {

    /**
     * A策略行爲
     */
    @Override
    public void perform() {
        System.out.println("perform A...");
    }
}

(2)策略實現類 B

/**
 * 策略實現類B
 */
public class StrategyImplB implements Strategy {

    /**
     * B策略行爲
     */
    @Override
    public void perform() {
        System.out.println("perform B...");
    }
}

三、在使用策略的類中,聲明並使用接口類型的策略變量

/**
 * 策略使用者
 */
public class StrategyUser {
    
    /**
     * 聲明接口類型的策略變量
     */
    private Strategy strategy;
    
    /**
     * 經過構造實例化策略
     */
    public StrategyUser(Strategy strategy) {
        this.strategy = strategy;
    }

    /**
     * 執行策略使用者的行爲
     */
    public void doBehavior() {
        // do something...
        
        // 使用策略
        strategy.perform();
        
        // do something...
    }
}

四、經過實例化不一樣的策略實現類,來改變使用者的行爲

public class Test {
    
    public static void main(String[] args) {
        // 使用策略A
        StrategyUser userA = new StrategyUser(new StrategyImplA());
        userA.doBehavior();
        // 使用策略B
        StrategyUser userB = new StrategyUser(new StrategyImplB());
        userB.doBehavior();
    }
}

3、舉個栗子

一、背景

Joe 上班的公司作了一套至關成功的模擬鴨子游戲:SimUDuck。遊戲中會出現各類鴨子,鴨子的種類及屬性以下:測試

  • 種類:綠頭鴨、紅頭鴨、橡皮鴨、誘餌鴨。
  • 屬性:外觀、游泳行爲、飛行行爲、呱呱叫行爲(叫聲)。

不一樣種類的鴨子所對應的屬性以下:this

  • 綠頭鴨:綠頭鴨的外觀、會游泳、會飛行、呱呱叫。
  • 紅頭鴨:紅頭鴨的外觀、會游泳、會飛行、呱呱叫。
  • 橡皮鴨:橡皮鴨的外觀、會游泳(漂浮)、不會飛行、吱吱叫。
  • 誘餌鴨:誘餌鴨的外觀、會游泳(漂浮)、不會飛行、不會叫。

二、要點

  • 因爲不一樣種類的鴨子可能具備不一樣的飛行行爲、呱呱叫行爲,所以,可使用策略模式把這兩種行爲抽出來。

三、實現

(1)建立行爲接口

/**
 * 飛行行爲接口
 */
public interface FlyBehavior {

    public void fly();
}
/**
 * 呱呱叫行爲接口
 */
public interface QuackBehavior {

    public void quark();
}

(2)實現行爲接口

/**
 * 用翅膀飛行
 */
public class FlyWithWings implements FlyBehavior {

    @Override
    public void fly() {
        System.out.println("I'm flying!");
    }
}

/**
 * 不會飛行
 */
public class FlyNoWay implements FlyBehavior {

    @Override
    public void fly() {
        System.out.println("I can't flying!");
    }
}
/**
 * 呱呱叫
 */
public class Quack implements QuackBehavior {

    @Override
    public void quark() {
        System.out.println("Quack");
    }
}

/**
 * 吱吱叫
 */
public class Squeak implements QuackBehavior {

    @Override
    public void quark() {
        System.out.println("Squeak");
    }
}

/**
 * 不會叫
 */
public class MuteQuack implements QuackBehavior {

    @Override
    public void quark() {
        System.out.println("<<Silence>>");
    }
}

(3)建立鴨子抽象類,並使用行爲接口

/**
 * 鴨子抽象類
 */
public abstract class Duck {
    
    FlyBehavior flyBehavior;
    QuackBehavior quackBehavior;
    
    public Duck() {
    }
    
    /**
     * 外觀
     */
    public abstract void display();

    /**
     * 游泳行爲
     */
    public void swim() {
        System.out.println("All ducks float, even decoys!");
    }
    
    /**
     * 飛行行爲
     */
    public void performFly() {
        flyBehavior.fly();
    }
    
    /**
     * 呱呱叫行爲
     */
    public void performQuark() {
        quackBehavior.quark();
    }
}

(4)建立鴨子子類,並指定具體的行爲實現

/**
 * 綠頭鴨
 */
public class MallardDuck extends Duck {
    
    public MallardDuck() {
        // 指定具體的飛行行爲
        flyBehavior = new FlyWithWings();
        // 指定具體的呱呱叫行爲
        quackBehavior = new Quack();
    }

    @Override
    public void display() {
        System.out.println("I'm a real Mallard duck");
    }
}

/**
 * 紅頭鴨
 */
public class RedHeadDuck extends Duck {
    
    public RedHeadDuck() {
        // 指定具體的飛行行爲
        flyBehavior = new FlyWithWings();
        // 指定具體的呱呱叫行爲
        quackBehavior = new Quack();
    }

    @Override
    public void display() {
        System.out.println("I'm a red head duck");
    }
}

/**
 * 橡皮鴨
 */
public class RubberDuck extends Duck {
    
    public RubberDuck() {
        // 指定具體的飛行行爲
        flyBehavior = new FlyNoWay();
        // 指定具體的呱呱叫行爲
        quackBehavior = new Squeak();
    }

    @Override
    public void display() {
        System.out.println("I'm a rubber duck");
    }
}

/**
 * 誘餌鴨
 */
public class DecoyDuck extends Duck {
    
    public DecoyDuck() {
        // 指定具體的飛行行爲
        flyBehavior = new FlyNoWay();
        // 指定具體的呱呱叫行爲
        quackBehavior = new MuteQuack();
    }

    @Override
    public void display() {
        System.out.println("I'm a decoy duck");
    }
}

(5)測試

public class Test {
    
    public static void main(String[] args) {
        // 綠頭鴨
        MallardDuck mallardDuck = new MallardDuck();
        mallardDuck.performFly();
        mallardDuck.performQuark();
        // 紅頭鴨
        RedHeadDuck redHeadDuck = new RedHeadDuck();
        redHeadDuck.performFly();
        redHeadDuck.performQuark();
        // 橡皮鴨
        RubberDuck rubberDuck = new RubberDuck();
        rubberDuck.performFly();
        rubberDuck.performQuark();
        // 誘餌鴨
        DecoyDuck decoyDuck = new DecoyDuck();
        decoyDuck.performFly();
        decoyDuck.performQuark();
    }
}
相關文章
相關標籤/搜索