1. 程式人生 > >策略模式簡單例子

策略模式簡單例子

以Head First設計模式中第一章給出的鴨子例子來講,此例子中有個鴨子的類,一共有普通鴨、模型鴨和玩具鴨三種。區別是普通鴨可以飛行併發出嘎嘎的叫聲;模型鴨不能飛行且不能發聲;玩具鴨不能飛行,但可以依靠火箭推進飛行(^..^就是這麼吊)且發出吱吱的聲音。面對這些有類似的屬性但不同的行為的類來說,使用策略模式便有利於類的拓展,其原則是:多用組合,少用繼承。簡單的思路是:定義演算法族,分別封裝起來,讓它們相互之間可以替換,使演算法的變化獨立於使用演算法的客戶。以下就從例項來說明:
首先是鴨子類,那就建立一個鴨子的超類(Duck),鴨子有飛行和鳴叫的行為,所以其下有兩個方法用於執行其飛行行為(performFly)和鳴叫行為(performQuack),當然可以新增一些其他方法(display)。
Duck類

/**
 * 鴨子的超類
 */
public abstract class Duck {

    public Duck() {
        // 執行鴨子的特徵
        display();
    }

    //鴨子的外觀,所有的鴨子外觀都不一樣,需要例項化的時候自定這隻鴨子是長什麼樣的
    public abstract void display();

    //執行鴨子的飛行行為
    public void performFly(){

    }

    //執行鴨子的鳴叫行為
    public void performFly(){

    }
}

可能此處會想到直接建立三種鴨子子類來繼承Duck超類,然後重寫performFly()和performFly()方法。如果這麼做的話要是再出現一種鴨子可以飛行但是發出吱吱的叫聲那就會和普通鴨子的飛行行為一樣,這樣就需要重寫寫一遍飛行的程式碼而沒有起到最初的程式碼複用的情況。所以此處考慮到一個設計原則,就是找出應用中可能需要變化的地方把它獨立出來,因此採用介面的方式設計飛行行為介面(FlyBehavior)和鳴叫介面(QuackBehavior)

/**
 * 鴨子的飛行行為介面,所有的飛行行為類需實現這個介面
 */
public interface FlyBehavior {
    //實現並賦予飛行行為
    public void fly();
}
/**
 *  同樣鴨子具有叫的行為
 */
public interface QuackBehavior {
    //實現並賦予鳴叫行為
    public void quack();
}

既然有了飛行和鳴叫的介面,那就需要實現其具體的行為,因此再建立所有的行為類實現它們,當然可以新增其他的飛行行為和鳴叫行為

可飛行的行為類:

/**
 *  可飛行
 */
public
class Flyable implements FlyBehavior{ @Override public void fly() { // 實現飛行行為 System.out.println("我飛起來了!"); } }

不可飛行行為類:

/**
 *  無法飛行的行為
 */
public class FlyNoWay implements FlyBehavior{

    @Override
    public void fly() {
        // 這隻鴨子不能飛行,可能是模型鴨
        System.out.println("我飛不起來。");
    }
}

靠火箭飛行行為類:

/**
 *  依靠火箭飛行
 */
public class FlyRocket implements FlyBehavior{

    @Override
    public void fly() {
        // 依靠火箭推進飛行的鴨子
        System.out.println("我可以靠火箭飛行了");
    }
}

當然還有叫聲的行為
發出嘎嘎叫聲:

/**
 *  鴨子嘎嘎的鳴叫聲
 */
public class Gaga implements QuackBehavior{

    @Override
    public void quack() {
        // 鴨子的叫聲是嘎嘎的叫
        System.out.println("我會嘎嘎地叫!!");
    }
}

發出吱吱叫聲

/**
 *  鴨子吱吱地叫
 */
public class Zhizhi implements QuackBehavior{

    @Override
    public void quack() {
        // 鴨子鳴叫聲為吱吱地叫
        System.out.println("我會吱吱地叫!!");
    }
}

叫不出聲

/**
 *  叫不出聲的鴨子(木頭鴨)
 */
public class Silence implements QuackBehavior{

    @Override
    public void quack() {
        // 有些鴨子叫不出聲
        System.out.println("我叫不出聲!");
    }
}

既然飛行行為和鳴叫的行為都有了,現在可以整合鴨子的超類(Duck)了。最初的Duck只有方法而沒有具體實現,現在可以其方法了。到此處還只是宣告鴨子的飛行行為和鳴叫行為,具體是什麼得需要看子類是什麼型別的鴨子了。

/**
 * 鴨子的超類
 */
public abstract class Duck {

    public Duck() {
        // 執行鴨子的特徵
        display();
    }

    //鴨子具有的飛行行為
    FlyBehavior flyBehavior;

    //鴨子的鳴叫行為
    QuackBehavior quackBehavior;

    //鴨子的外觀,所有的鴨子外觀都不一樣,需要例項化的時候自定這隻鴨子是長什麼樣的
    public abstract void display();

    //執行鴨子的飛行行為
    public void performFly(){
        flyBehavior.fly();
    }

    //執行鴨子的鳴叫行為
    public void performQuack(){
        quackBehavior.quack();
    }
}

現在是時候建立三種鴨子了,建立之時初始化其行為便可。
正常鴨(NormalDuck)

/**
 *  建立正常的鴨子,繼承超類,執行飛行和鳴叫的行為,此類鴨子可以飛,並且發出嘎嘎的叫聲
 */
public class NormalDuck extends Duck{

    public NormalDuck() {
        // 普通鴨建構函式
        flyBehavior = new Flyable();
        quackBehavior = new Gaga();
    }

    @Override
    public void display() {
        // 此類鴨子外觀都一致
        System.out.println("這是一隻小黃鴨!!");
    }
}

玩具鴨(ToyDuck)

/**
 *  玩具鴨,不會飛行,但會吱吱地叫
 */
public class ToyDuck extends Duck{

    public ToyDuck() {
        // 玩具鴨建構函式
        flyBehavior = new FlyNoWay();
        quackBehavior = new Zhizhi();
    }

    @Override
    public void display() {
        // 玩具鴨子
        System.out.println("這是一隻玩具鴨!!");
    }
}

模型鴨(ModelDuck)

/**
 *  模型鴨,不會飛也不會叫
 */
public class ModelDuck extends Duck{

    public ModelDuck() {
        // 模型鴨建構函式
        flyBehavior = new FlyNoWay();
        quackBehavior = new Silence();
    }

    @Override
    public void display() {
        // 模型鴨
        System.out.println("這是一隻模型鴨!!");
    }
}

上面說過玩具鴨是可以飛行的,那為什麼不直接將其飛行行為設為靠火箭推進飛行呢?這裡就可以再次整合一下Duck類,使其可以動態設定行為,通過setFlyBehavior(new FlyRocket())動態設定其飛行行為,此方法也可用於設定鳴叫行為。

/**
 * 鴨子的超類
 */
public abstract class Duck {

    public Duck() {
        // 執行鴨子的特徵
        display();
    }

    //鴨子具有的飛行行為
    FlyBehavior flyBehavior;

    //鴨子的鳴叫行為
    QuackBehavior quackBehavior;

    //鴨子的外觀,所有的鴨子外觀都不一樣,需要例項化的時候自定這隻鴨子是長什麼樣的
    public abstract void display();

    //執行鴨子的飛行行為
    public void performFly(){
        flyBehavior.fly();
    }

    //執行鴨子的鳴叫行為
    public void performQuack(){
        quackBehavior.quack();
    }

    //設定鴨子飛行的屬性
    public void setFlyBehavior(FlyBehavior fb){
        flyBehavior = fb;
    }

    //設定鴨子的鳴叫屬性
    public void setQuackBehavior(QuackBehavior qb){
        quackBehavior = qb;
    }
}

至此所有的工作都已經做完,現在開始測試

/**
 *  建立鴨子
 *  先建立鴨子的超類和具有的各種行為,然後建立不同型別的鴨子,最後例項化這些鴨子 
 */
public class CreateDuck {
    public static void main(String[] args) {
        //建立普通鴨子,此類鴨子可以飛行,併發出嘎嘎的叫聲
        Duck normalDuck = new NormalDuck();
        normalDuck.performFly();
        normalDuck.performQuack();

        //建立模型鴨,此類鴨子不能飛行,並且不能發出聲音
        Duck modelDuck = new ModelDuck();
        modelDuck.performFly();
        modelDuck.performQuack();

        //建立玩具鴨,此類鴨子不能飛行,但依靠火箭推進飛行,並且會發出吱吱的聲音
        Duck toyDuck = new ToyDuck();
        toyDuck.performFly();                   //執行玩具鴨的基本屬性(不會飛行)
        toyDuck.setFlyBehavior(new FlyRocket());//賦予玩具鴨行的飛行屬性(火箭推進),至此覆蓋了之前的
        toyDuck.performFly();                   //再次執行時玩具鴨已經擁有火箭推進了,可以飛行了。
        toyDuck.performQuack();
    }
}

執行結果:

這裡寫圖片描述
在這裡看到實現鴨子的各種行為可以使用策略模式將鴨子的行為封裝到一組類中,這樣可以很容易拓展和改變,並且在需要之時還能在執行時改變其行為,如將不會飛行的玩具設定成靠火箭推進飛行。

相關推薦

策略模式簡單例子

以Head First設計模式中第一章給出的鴨子例子來講,此例子中有個鴨子的類,一共有普通鴨、模型鴨和玩具鴨三種。區別是普通鴨可以飛行併發出嘎嘎的叫聲;模型鴨不能飛行且不能發聲;玩具鴨不能飛行,但可以依靠火箭推進飛行(^..^就是這麼吊)且發出吱吱的聲音。面對這

工廠模式簡單例子

void factor 不存在 dmi sta println static nis pack 工廠模式: 1 package factorymode; 2 /** 3 * 工廠模式簡單例子 4 * @author Administrator 5 * 6

策略模式---------簡單分析

cls img 不同 簡單的 方法 @override cat raw ima   繼續我的設計模式之旅,這次學習的是策略模式,自己感覺策略模式跟簡單工廠模式好像,引用大話設計模式裏面的定義,策略模式是一種定義一系列算法的方法,從概念上看,所有這些算法完成的都是相同的工作,

java常用設計模式--觀察者模式簡單例子

package com.ruanyun;import java.util.List;import java.util.Vector;/** * @Auther: maxw * @Date: 2018/11/10 16:14 * @Description:觀察者模式 * 基本概念: * 觀察者模式屬於行為型模式

java常用設計模式--單例模式簡單例子

package com.ruanyun;/** * @Auther: maxw * @Date: 2018/11/10 17:29 * @Description: */public class Test4 { public static void main(String args[]){

java常用設計模式--工廠方法模式簡單例子

package com.ruanyun;/** * @Auther: maxw * @Date: 2018/11/12 11:02 * @Description:工廠方法模式:有四個角色,抽象工廠模式,具體工廠模式,抽象產品模式,具體產品模式。不再是由一個工廠類去例項化具體的產品,而是由抽象工廠的子類去例項化

java常用設計模式--抽象工廠模式簡單例子

package com.ruanyun;/** * @Auther: maxw * @Date: 2018/11/12 11:23 * @Description:抽象工廠模式:與工廠方法模式不同的是,工廠方法模式中的工廠只生產單一的產品,而抽象工廠模式中的工廠生產多個產品。 * 還有個抽象工廠方法模式 只需要

大話設計模式(二)策略模式+簡單工廠

策略模式 定義了演算法,分別封裝起來,讓他們之間可以相互替換,此模式讓演算法的變化不會影響到使用演算法的使用者 /** *定義一個抽象的父類,包含一個抽象的演算法Amethod * / public abstract class Strategy { public abst

java 策略模式+簡單工廠模式+反射

一、場景:在實際的專案開發中,我們常常會遇到這樣的問題,實現一個功能有多重方法或策略。比如商場中計算價格的方法:1、商場中沒有活動,那麼收費就是原價;2、商場中有活動,打8折;3、商場中有活動,滿300件100;這三個中計算價格的方法就是三種策略。我們在不適用設計模式的情況下

C#設計模式---觀察者模式簡單例子

在開發過程中經常遇到一個模組中的 一個方法呼叫了其他模組中相關的方法 比如說在一個系統中,如果出現了錯誤,就呼叫專門進行錯誤處理的模組中的方法進行錯誤處理 而因為錯誤處理的操作有很多,所以將這些具體的操作封裝在其他的模組中 在專門進行錯誤處理的模組中呼叫其他模組中的錯誤操作

Java 關於策略模式+簡單工廠模式下的思考

導讀   最近在做公司一個訊息閘道器的服務,包括:簡訊、微信、郵件等,所有請求通過一個入口,方便介面的管理(記錄日誌、介面限流白名單啥的)。如何寫這個介面呢,還有為了以後擴充套件,對接過簡訊、微信、公眾號的童鞋大概都瞭解,首先定義一個模板,然後後臺傳入json,替換模板中的值,然後傳送。設計框架大概思路是這樣

別隻知道策略模式+簡單工廠,試試更香的策略模式+抽象工廠!

  我的相關博文  三種工廠模式詳解   策略模式 在GOF的《設計模式:可複用面向物件軟體的基礎》一書中對策略模式是這樣說的: 定義一系列的演算法,把它們一個個封裝起來,並且使它們可相互替換。該模式使得演算法可獨立於使用它的客戶而變化。   策略模式為了適應不同的需求

設計模式策略模式淺談以及簡單例子

null 引用 == names bsp args cto 封裝 方法 設計模式之策略模式 策略模式定義了算法類,分別封裝起來,讓他們之間可以相互替換,此模式讓算法的變化獨立於使用算法的客戶。 策略模式是對算法的包裝,是把使用的責任和

對設計模式的總結之簡單工廠與策略模式

mage 建立 不變 href catch nag 實現類 初步 cti 前言 面向對象編程追求的本質-提高擴展性、可維護性、靈活性和復用性。合理利用面向對象6個原則,能夠很好的達到要求。如何利用好就是至關重要的了,前人總結了23+個設計模式能夠讓初學者更容易

設計模式策略模式&簡單工廠模式

抽象 jsb args watermark amp pri eas 時間 並且 學習設計模式已經有非常長一段時間了。事實上先前已經敲過一遍了,可是老認為沒有學到什麽,認識也不夠深刻,如今趁著重構機房。再又一次來過,也不晚。 事實上在敲了機房之後,看看模式,事實

Java 設計模式學習筆記1——策略模式(Duck例子

利用 實例化 top 而是 實現 學習筆記 left ng- 多個 0、假設現有工程(Duck)中遇到為類添加功能的問題,如何設計類添加新的功能? 1、利用繼承提供的Duck(鴨子)的行為會導致哪些缺點? (1)代碼在多個子類中重復 (2)很多男知道所有鴨子的全部行為

二、使用簡單工廠來改進策略模式

麻煩 str 不同 [] ring www ride say 模式 策略模式的使用,把一系列算法進行了封裝,只需要通過配置不同的算法,即可以實現算法的自由切換。具體內容參考第一篇:http://www.cnblogs.com/lay2017/p/7570041.html 但

策略模式簡單工廠(四)

設計模式 策略模式 簡單工廠 策略模式由前端觸發決定使用某一組算法或邏輯,每一組算法或邏輯不相同,互相不幹擾。最後交由一個上下文具體去執行,並可以增加一定公有邏輯。比如某電商平臺搞活動:普通會員:滿100減10塊白銀會員:滿100減15塊 送積分黃金會員:滿100減18塊 送積分 參與抽獎鉆

JavaScript設計模式--簡單工廠模式例子---XHR工廠

++ 原型鏈 this soft microsoft for .proto 跨域 默認 第一步,Ajax操作接口(目的是起一個接口檢測作用) (1)引入接口文件 //定義一個靜態方法來實現接口與實現類的直接檢驗 //靜態方法不要寫出Interface.pro

重構電商例子策略模式

obj item com cached 圖片 子類 tom appid ems 案例分析:重構“策略”模式 《設計模式:可復用面向對象軟件的基礎》一書是這樣概述“策略”模式的: 定義一系列算法,把它們一一封裝起來,並且使它們可以相互替換。本模式使得算法可以獨立於使用它的