【Java设计模式】行为型模式-策略模式

源代码:https://gitee.com/AgentXiao/BehavioralPatterns
要点:
1、条件语句和策略模式的差异
2、策略模式的本质及实现

一、场景

某个的报价策略可以简单作如下分类:
• 普通客户小批量报价
• 普通客户大批量报价
• 老客户小批量报价
• 老客户大批量报价

具体选用哪个报价策略,这需要根据实际情况来确定。
我们可以使用一下机制实现:

public double getPrice(String type, double price){
        if(type.equals("普通客户小批量")){ 
            System.out.println("不打折,原价"); 
            return price; 
        }else if(type.equals("普通客户大批量")){ 
            System.out.println("打九折"); 
            return price*0.9; 
        }else if(type.equals("老客户小批量")){ 
            System.out.println("打八五折"); 
            return price*0.85; 
        }else if(type.equals("老客户大批量")){ 
            System.out.println("打八折"); 
            return price*0.8; 
        } return price;
    }

通过if-else if-else实现起来比较容易,符合开发人员的一般思路!但是当报价策略类型比较多,同时每个类型的报价方式比较复杂时,会导致整个条件控制语句非常地长,难以维护。

我们可以使用策略模式解决这个问题。

二、策略模式

策略模式对应于解决某一个问题的一个算法族,允许用户从该算法族中任选一个算法解决某一问题,同时可以方便的更换算法或者增加新的算法。并且由客户端决定调用哪个算法。

也就是说,策略模式将每一种报价规格封装为一个类,这个类只解决这一种报价算法,在需要使用时以引用的方式注入。这就很好的解决了条件语句难以维护的难题。同时需要增加新的策略时,只需要新增一个类。

1、算法族通过一个接口将所有的具体算法聚集在一起

/**
 * @interfaceName Strategy
 * @Description 策略算法族
 * @Author xwd
 * @Date 2018/10/28 15:23
 */
public interface Strategy {
    /**
     * @MethodName getPrice
     * @Descrition 价钱的计算方法
     * @Param [price]
     * @return double
     */
    double getPrice(double price);
}

2、具体的算法按照实际情况进行确定,统一实现算法族接口

/**
 * @ClassName NewCustomerFewStrategy
 * @Description 新客户小批量
 * @Author xwd
 * @Date 2018/10/28 15:25
 */
public class NewCustomerFewStrategy implements Strategy {
    @Override
    public double getPrice(double price) {
        System.out.println("新客户小批量:不打折!");
        return price;
    }
}
/**
 * @ClassName NewCustomerFewStrategy
 * @Description 新客户大批量
 * @Author xwd
 * @Date 2018/10/28 15:25
 */
public class NewCustomerManyStrategy implements Strategy {
    @Override
    public double getPrice(double price) {
        System.out.println("新客户大批量:95折!");
        return price*0.95;
    }
}
/**
 * @ClassName NewCustomerFewStrategy
 * @Description 老客户小批量
 * @Author xwd
 * @Date 2018/10/28 15:25
 */
public class OldCustomerFewStrategy implements Strategy {
    @Override
    public double getPrice(double price) {
        System.out.println("老客户小批量:9折!");
        return price*0.9;
    }
}
/**
 * @ClassName NewCustomerFewStrategy
 * @Description 老客户大批量
 * @Author xwd
 * @Date 2018/10/28 15:25
 */
public class OldCustomerManyStrategy implements Strategy {
    @Override
    public double getPrice(double price) {
        System.out.println("老客户大批量:85折!");
        return price*0.85;
    }
}

3、需要一个管理算法族的类,作为客户和算法族之间的中间人(就像超超市的售货员),它持有算法族的引用,因此客户只需要和该中间人打交道,实现了客户和算法之间的解耦

/**
 * @ClassName Boss
 * @Description 商店老板,管理报价策略
 * @Author xwd
 * @Date 2018/10/28 15:29
 */
public class Boss {

    private Strategy strategy;//持有报价策略的引用

    public Boss(Strategy strategy) {
        this.strategy = strategy;
    }

    /**
     * @MethodName getPrice
     * @Descrition 获得价格
     * @Param [price]
     * @return void
     */
    public void getPrice(double price){
        System.out.println("报价:"+this.strategy.getPrice(price));
    }
}

4、客户,找到持有算法引用的中间人

/**
 * @ClassName Client
 * @Description 客户
 * @Author xwd
 * @Date 2018/10/28 15:32
 */
public class Client {
    public static void main(String[] args) {
        Boss boss = new Boss(new OldCustomerFewStrategy());
        boss.getPrice(500);
    }
}

5、测试结果

测试结果

三、总结

1、本质

分离算法,选择实现。

2、开发中常见的场景:

1)JAVASE中GUI编程中,布局管理
布局管理中有多种布局方式,例如流布局、边界布局等,在使用时直接指定相应的布局方式即可。
2)Spring框架中,Resource接口,资源访问策略
3)javax.servlet.http.HttpServlet#service()

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,525评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,203评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,862评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,728评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,743评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,590评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,330评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,244评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,693评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,885评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,001评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,723评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,343评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,919评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,042评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,191评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,955评论 2 355

推荐阅读更多精彩内容