1. 程式人生 > >設計模式一之策略模式筆記

設計模式一之策略模式筆記

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

 

設計原則:找出應用中可能需要變化之處,把它們獨立出來,不要和那些不需要變化的程式碼混在一起。

把會變化的部分取出並「封裝」起來,好讓其他部分不會受到影響。

思考方式:「把會變化的部分取出並封裝起來,以便以後可以輕易地擴充此部分,而不影響不需要變化的其他部分」。

 

設計原則:針對介面程式設計,而不是針對實現程式設計。

「針對介面程式設計」真正的意思是「針對超型別(supertype)程式設計」。

這裡所謂的「介面」有多個含意,介面是一個「概念」,也是一種Java的interface構造。你可以在不涉及Java interface的情況下,「針對介面程式設計」,關鍵就在多型。利用多型,程式可以針對超型別程式設計,執行時會根據實際狀況執行到真正的行為,不會被綁死在超型別的行為上。「針對超型別程式設計」這句話,可以更明確地說成「變數的宣告型別,應該是超型別,通常是一個抽象類或者是一個介面,如此,只要是具體實現此超型別的類所產生的物件,都可以指定給這個變數;這也意味著,宣告類時,不用理會以後執行時的真正物件型別!」

 

設計原則:多用組合,少用繼承。

使用組合建立系統具有很大的彈性,不僅可將演算法族封裝成類,更可以『在執行時動態地改變行為』,只要組合的行為物件,符合正確的介面標準即可。組合用在『許多』設計模式中。

 

學習例項:

實現:

Ducu.java

public abstract class Duck {

    FlyBehavior flyBehavior;
    QuackBehavior quackBehavior;

    public abstract void display();

    public void setFlyBehavior(FlyBehavior flyBehavior) {
        this.flyBehavior = flyBehavior;
    }

    public void setQuackBehavior(QuackBehavior quackBehavior) {
        this.quackBehavior = quackBehavior;
    }

    public void performFly() {
        flyBehavior.fly();
    }

    public void performQuack() {
        quackBehavior.quack();
    }

    public void swim() {
        System.out.println("All ducks float, even decoys!");
    }


}

介面FlyBehavior.java

public interface FlyBehavior {

    public void fly();

}
實現介面fly行為類 =>
public class FlyNoWay implements FlyBehavior {
    public void fly() {
        System.out.println("I can't fly");
    }
}


public class FlyRocketPowered implements FlyBehavior {
    public void fly() {
        System.out.println("I'm flying with a rocket");
    }
}


public class FlyWithWings implements FlyBehavior {

    public void fly() {
        System.out.println("I'm flying!!!");
    }
}
介面QuackBehavior.java
public interface QuackBehavior {

    public void quack();

}

實現介面Quack行為類 =>

public class MuteQuack implements QuackBehavior {
    public void quack() {
        System.out.println("<Silence>");
    }
}


public class Quack implements QuackBehavior {
    public void quack() {
        System.out.println("Quack");
    }
}


public class Squeak implements QuackBehavior {
    public void quack() {
        System.out.println("Squeak");
    }
}
鴨子類=>MallardDuck.java
public class MallardDuck extends Duck {

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

    public MallardDuck() {
        quackBehavior = new Quack();
        flyBehavior = new FlyNoWay();
    }
}

 

Ok可以測試了 => MiniDuckSimulater.java

public class MiniDuckSimulater {

    public static void main(String[] args) {
        Duck mallard = new MallardDuck();

        mallard.performQuack();
        mallard.performFly();

        System.out.println("-----上面是改變前-------");
        System.out.println("-----下面是改變後-------");

        mallard.setFlyBehavior(new FlyRocketPowered());//這裡可以動態改變他的fly行為
        mallard.setQuackBehavior(new MuteQuack());//這裡可以動態改變他的quack行為

        mallard.performQuack();
        mallard.performFly();



    }

}

執行結果 =>

Quack
I can't fly
-----上面是改變前-------
-----下面是改變後-------
<Silence>
I'm flying with a rocket

 

結構圖: