一、策略者模式(Strategy Pattern)—-2

來源:互聯網
上載者:User

繼承不能很好的解決問題,因為鴨子的行為在子類中會不斷的變化,為了適應這種變化,我們不得不一遍遍的在子類中覆蓋父類的方法。

介面也不能解決這個問題,因為介面的代碼布不具有複用的特性,如果某一天所有的鴨子都變成嘰嘰叫,那麼,你不得不到所有的子類中一個個的修改。

幸運的是,有一個設計原則適應這種情況:

找出應用可能需要變化之處,把他們獨立出來,不要和那些不需要變化的代碼混淆在一起。把會變化的部分取出來並封裝起來,以便以後可以輕易的改動或者擴充此部分,而不需要影響其他不需要變化的部分。

一、首先,分清楚該應用中變化的和不變化的部分,將他們區分開。然後,將變化的部分fly和quack建立兩組類,一組與fly有關,一組和quack有關,每一組實現自己各自的動作。

飛行行為的介面:FlyBehavior.java,具體的飛行的行為都要實現該介面

/** * 具體的飛行的行為都要實現該介面 */public interface FlyBehavior {void fly();}

用翅膀飛行:FlyWithWings.java

/** * 用翅膀飛行的行為 */public class FlyWithWings implements FlyBehavior{@Overridepublic void fly() {System.out.println("我用翅膀飛行");}}

不能飛行:FlyNoWay.java

/** * 不能飛行 */public class FlyNoWay implements FlyBehavior{@Overridepublic void fly() {//不能飛行,空實現}}

叫 行為的介面:QuackBehavior.java,具體的叫的行為都要實現該介面

/** * 具體的叫的行為都要實現該介面 */public interface QuackBehavior {void quack();}

呱呱叫:Quack.java

/** * 呱呱叫 */public class Quack implements QuackBehavior{@Overridepublic void quack() {System.out.println("我可以呱呱叫");}}

吱吱叫:Squeak.java

/** * 吱吱叫 */public class Squeak implements QuackBehavior{@Overridepublic void quack() {System.out.println("我可以吱吱叫");}}

不會叫:MuteQuack.java

/** * 不會叫 */public class Quack implements QuackBehavior{@Overridepublic void quack() {//空實現}}

這樣就設計好了行為的變化,這樣的設計,可以使飛行和呱呱叫的動作被其他的對象複用,因為這些行為已經和鴨子沒有關係。任何具備這兩種特性的對象都可以利用。

並且,我們可以新增加一些行為,而不會對其他的行為有任何的影響。

二、鴨子的行為都已經封裝好了,現在就是要把它們整合到鴨子中來。

1、鴨子的超類:Duck.java

/** * 所有鴨子的父類 */public class Duck {FlyBehavior flyBehavior;//飛行行為QuackBehavior quackBehavior;//叫的行為public void swim() {System.out.println("我可以遊泳");}public void display() {}public void performFly() {flyBehavior.fly();}public void performQuack() {quackBehavior.quack();}}

2、鴨子的子類

綠頭鴨:

/** * 綠頭鴨,會飛,會叫 */public class MallardDuck extends Duck {public MallardDuck() {flyBehavior = new FlyWithWings();quackBehavior = new Quack();}@Overridepublic void display() {System.out.println("我是綠頭鴨!");}}

紅頭鴨:

/** * 紅頭鴨,會飛,會叫 */public class ReadheadDuck extends Duck {public ReadheadDuck() {flyBehavior=new FlyWithWings();quackBehavior=new Quack();}@Overridepublic void display() {System.out.println("我是紅頭鴨!");}}

橡皮鴨:

/** * 橡皮鴨是吱吱叫的,不會飛的, */public class RubberDuck extends Duck{public RubberDuck() {flyBehavior=new FlyNoWay();quackBehavior=new Squeak();}@Overridepublic void display() {System.out.println("我是橡皮鴨!");}}

誘餌鴨:

/** * 誘餌鴨,不會飛,不會叫 */public class DecoyDuck extends Duck{//針對不同的鴨子給與不同的實現public DecoyDuck() {flyBehavior=new FlyNoWay();quackBehavior=new MuteQuack();}@Overridepublic void display() {System.out.println("我是誘餌鴨!");}}

3、測試鴨子的行為

public class TestClass {public static void main(String[] args) {MallardDuck mallardDuck=new MallardDuck();//綠頭鴨ReadheadDuck readheadDuck=new ReadheadDuck();//紅頭鴨RubberDuck rubberDuck=new RubberDuck();//橡皮鴨DecoyDuck decoyDuck=new DecoyDuck();//誘餌鴨mallardDuck.display();mallardDuck.performFly();mallardDuck.swim();mallardDuck.performQuack();System.out.println("-------------------");readheadDuck.display();readheadDuck.performFly();readheadDuck.swim();readheadDuck.performQuack();System.out.println("-------------------");rubberDuck.display();rubberDuck.performFly();rubberDuck.performQuack();rubberDuck.swim();System.out.println("-------------------");decoyDuck.display();decoyDuck.performFly();decoyDuck.swim();decoyDuck.performQuack();}}

4、測試結果:

我是綠頭鴨!我用翅膀飛行我可以遊泳我會呱呱叫-------------------我是紅頭鴨!我用翅膀飛行我可以遊泳我會呱呱叫-------------------我是橡皮鴨!我可以吱吱叫我可以遊泳-------------------我是誘餌鴨!我可以遊泳

三、這樣的一個鴨子應用的體系就已經設計好了,不管是我們要添加更多的飛行行為,還是叫的行為,直接繼承FlyBehaviour介面或者QuackBehavior介面,而不會對其他的部分產生影響。修改某個鴨子的行為,也只要在其構造的方法裡面針對不同行為的實現就可以了。

而且我們還可以在啟動並執行時候動態修改鴨子的行為。只需要在Duck超類中添加兩個方法就可以了

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.