`

浅谈策略模式

 
阅读更多

最近开始了解设计模式,在网上看到的一篇很好的关于策略模式的介绍:

 

策略(Strategy)模式:又名Policy,它的用意是定义一组算法,把它们一个个封装起来,并且使他们可以相互替换。策略模式可以独立于使用他们的客户端而变化。GOF策略模式静态结构类图如下:

通过上图可以看出策略模式有以下角色构成:

1、抽象策略(Strategy)角色:抽象策略角色由抽象类或接口来承担,它给出具体策略角色需要实现的接口;

2、具体策略(ConcreteStrategy)角色:实现封装了具体的算法或行为;

3、场景(Context)角色:持有抽象策略类的引用。

策略模式重点是封装不同的算法和行为,不同的场景下可以相互替换。策略模式是开闭原则的体现,开闭原则讲的是一个软件实体应该对扩展开放对修改关闭。策略模式在新的策略增加时,不会影响其他类的修改,增加了扩展性,也就是对扩展是开放的;对于场景来说,只依赖于抽象,而不依赖于具体实现,所以对修改是关闭的。策略模式的认识可以借助《java与模式》一书中写到诸葛亮的锦囊妙计来学习,在不同的场景下赵云打开不同的锦囊,便化险为夷,锦囊便是抽象策略,具体的锦囊里面的计策便是具体的策略角色,场景就是赵云,变化的处境

选择具体策略的条件。

 

策略模式在程序设计中也很常用,在板桥(banq)的博客里有篇文章叫 “你还在用if else吗?”
http://www.jdon.com/artichect/ifelse.htm”讲的很好,策略模式不但是继承的代替方案而且能很好地解决if else问题,下面举个实例来说明,怎么使用策略模式。

需求如下:

某支付系统接入以下几种商户进行充值:易宝网易,快线网银,19pay手机支付,支付宝支付,骏网一卡通,由于每家充值系统的结算比例不一样,而且同一家商户的不同充值方式也有所不同,具体系统情况比较复杂,像支付宝既有支付宝账号支付和支付宝网银支付等这些暂时不考虑,为了讲述策略模式这里简单描述,假如分为四种,手机支付,网银支付,商户账号支付和点卡支付。因为没个支付结算比例不同,所以对手续费低的做一些优惠活动,尽可能让用户使用手续费低的支付方式来充值,这样降低渠道费用,增加收入,具体优惠政策如下:

①网银充值,8.5折;

②商户充值,9折;

③手机充值,没有优惠;

④点卡充值,收取1%的渠道费;

对于一个新手的代码如下:

Java代码  收藏代码
  1. package strategy;  
  2.   
  3. public class Example {  
  4.   
  5.     /** 
  6.      *  
  7.      *作者:alaric 
  8.      *时间:2013-8-5上午11:00:06 
  9.      *描述:计算用户所付金额 
  10.      */  
  11.     public Double calRecharge(Double charge ,RechargeTypeEnum type ){  
  12.           
  13.         if(type.equals(RechargeTypeEnum.E_BANK)){  
  14.             return charge*0.85;  
  15.         }else if(type.equals(RechargeTypeEnum.BUSI_ACCOUNTS)){  
  16.             return charge*0.90;  
  17.         }else if(type.equals(RechargeTypeEnum.MOBILE)){  
  18.             return charge;  
  19.         }else if(type.equals(RechargeTypeEnum.CARD_RECHARGE)){  
  20.             return charge+charge*0.01;  
  21.         }else{  
  22.             return null;  
  23.         }  
  24.   
  25.     }  
  26.       
  27. }  

 

Java代码  收藏代码
  1. package strategy;  
  2.   
  3. public enum RechargeTypeEnum {  
  4.   
  5.     E_BANK(1"网银"),  
  6.       
  7.     BUSI_ACCOUNTS(2"商户账号"),  
  8.       
  9.     MOBILE(3,"手机卡充值"),  
  10.       
  11.     CARD_RECHARGE(4,"充值卡")  
  12.     ;  
  13.       
  14.     /** 
  15.      * 状态值 
  16.      */  
  17.     private int value;  
  18.       
  19.     /** 
  20.      * 类型描述 
  21.      */  
  22.     private String description;  
  23.       
  24.       
  25.       
  26.     private RechargeTypeEnum(int value, String description) {  
  27.         this.value = value;  
  28.         this.description = description;  
  29.     }  
  30.           
  31.     public int value() {  
  32.         return value;  
  33.     }  
  34.     public String description() {  
  35.         return description;  
  36.     }  
  37.       
  38.   
  39.     public static RechargeTypeEnum valueOf(int value) {  
  40.         for(RechargeTypeEnum type : RechargeTypeEnum.values()) {  
  41.             if(type.value() == value) {  
  42.                 return type;  
  43.             }  
  44.         }  
  45.         return null;   
  46.     }  
  47. }  

 可以看出上面四种不同的计算方式在一个方法内部,不利于扩展和维护,当然也不符合面向对象设计原则。对以上的代码利用策略模式进行修改,类图如下:

 


 实例代码如下:

 

Java代码  收藏代码
  1. package strategy.strategy;  
  2.   
  3. import strategy.RechargeTypeEnum;  
  4.   
  5. /** 
  6.  *  
  7.  *作者:alaric 
  8.  *时间:2013-8-5上午11:03:17 
  9.  *描述:策略抽象类 
  10.  */  
  11. public interface Strategy {  
  12.   
  13.     /** 
  14.      *  
  15.      *作者:alaric 
  16.      *时间:2013-8-5上午11:05:11 
  17.      *描述:策略行为方法 
  18.      */  
  19.     public Double calRecharge(Double charge ,RechargeTypeEnum type );  
  20. }  

 

Java代码  收藏代码
  1. package strategy.strategy;  
  2.   
  3. import strategy.RechargeTypeEnum;  
  4. /** 
  5.  *  
  6.  *作者:alaric 
  7.  *时间:2013-8-5上午11:14:23 
  8.  *描述:网银充值 
  9.  */  
  10. public class EBankStrategy implements Strategy{  
  11.   
  12.     @Override  
  13.     public Double calRecharge(Double charge, RechargeTypeEnum type) {  
  14.         return charge*0.85;  
  15.     }  
  16.   
  17.       
  18.   
  19. }  

 

Java代码  收藏代码
  1. package strategy.strategy;  
  2.   
  3. import strategy.RechargeTypeEnum;  
  4. /** 
  5.  *  
  6.  *作者:alaric 
  7.  *时间:2013-8-5上午11:14:08 
  8.  *描述:商户账号充值 
  9.  */  
  10. public class BusiAcctStrategy implements Strategy{  
  11.   
  12.     @Override  
  13.     public Double calRecharge(Double charge, RechargeTypeEnum type) {  
  14.         // TODO Auto-generated method stub  
  15.         return charge*0.90;  
  16.     }  
  17.   
  18. }  

 

Java代码  收藏代码
  1. package strategy.strategy;  
  2.   
  3. import strategy.RechargeTypeEnum;  
  4. /** 
  5.  *  
  6.  *作者:alaric 
  7.  *时间:2013-8-5上午11:14:43 
  8.  *描述:手机充值 
  9.  */  
  10. public class MobileStrategy implements Strategy {  
  11.   
  12.     @Override  
  13.     public Double calRecharge(Double charge, RechargeTypeEnum type) {  
  14.         // TODO Auto-generated method stub  
  15.         return charge;  
  16.     }  
  17.   
  18. }  

 

Java代码  收藏代码
  1. package strategy.strategy;  
  2.   
  3. import strategy.RechargeTypeEnum;  
  4. /** 
  5.  *  
  6.  *作者:alaric 
  7.  *时间:2013-8-5上午11:13:46 
  8.  *描述:充值卡充值 
  9.  */  
  10. public class CardStrategy implements Strategy{  
  11.   
  12.     @Override  
  13.     public Double calRecharge(Double charge, RechargeTypeEnum type) {  
  14.         return charge+charge*0.01;  
  15.     }  
  16.   
  17. }  

 

Java代码  收藏代码
  1. package strategy.strategy;  
  2.   
  3. import strategy.RechargeTypeEnum;  
  4.   
  5. /** 
  6.  *  
  7.  *作者:alaric 
  8.  *时间:2013-8-5上午11:03:38 
  9.  *描述:场景类 
  10.  */  
  11. public class Context {  
  12.   
  13.     private Strategy strategy;  
  14.       
  15.     public Double calRecharge(Double charge, Integer type) {  
  16.         strategy = StrategyFactory.getInstance().creator(type);  
  17.         return strategy.calRecharge(charge, RechargeTypeEnum.valueOf(type));  
  18.     }  
  19.   
  20.     public Strategy getStrategy() {  
  21.         return strategy;  
  22.     }  
  23.   
  24.     public void setStrategy(Strategy strategy) {  
  25.         this.strategy = strategy;  
  26.     }  
  27.       
  28. }  

 

Java代码  收藏代码
  1. package strategy.strategy;  
  2.   
  3. import java.util.HashMap;  
  4. import java.util.Map;  
  5.   
  6. import strategy.RechargeTypeEnum;  
  7. /** 
  8.  *  
  9.  *作者:alaric 
  10.  *时间:2013-8-5上午11:31:12 
  11.  *描述:策略工厂 使用单例模式 
  12.  */  
  13. public class StrategyFactory {  
  14.   
  15.     private static StrategyFactory factory = new StrategyFactory();  
  16.     private StrategyFactory(){  
  17.     }  
  18.     private static Map<Integer ,Strategy> strategyMap = new HashMap<>();  
  19.     static{  
  20.         strategyMap.put(RechargeTypeEnum.E_BANK.value(), new EBankStrategy());  
  21.         strategyMap.put(RechargeTypeEnum.BUSI_ACCOUNTS.value(), new BusiAcctStrategy());  
  22.         strategyMap.put(RechargeTypeEnum.MOBILE.value(), new MobileStrategy());  
  23.         strategyMap.put(RechargeTypeEnum.CARD_RECHARGE.value(), new CardStrategy());  
  24.     }  
  25.     public Strategy creator(Integer type){  
  26.         return strategyMap.get(type);  
  27.     }  
  28.     public static StrategyFactory getInstance(){  
  29.         return factory;  
  30.     }  
  31. }  

 

Java代码  收藏代码
  1. package strategy.strategy;  
  2.   
  3. import strategy.RechargeTypeEnum;  
  4.   
  5. public class Client {  
  6.   
  7.     /** 
  8.      * 作者:alaric 时间:2013-8-5上午11:33:52 描述: 
  9.      */  
  10.     public static void main(String[] args) {  
  11.   
  12.         Context context = new Context();  
  13.         // 网银充值100 需要付多少  
  14.         Double money = context.calRecharge(100D,  
  15.                 RechargeTypeEnum.E_BANK.value());  
  16.         System.out.println(money);  
  17.   
  18.         // 商户账户充值100 需要付多少  
  19.         Double money2 = context.calRecharge(100D,  
  20.                 RechargeTypeEnum.BUSI_ACCOUNTS.value());  
  21.         System.out.println(money2);  
  22.   
  23.         // 手机充值100 需要付多少  
  24.         Double money3 = context.calRecharge(100D,  
  25.                 RechargeTypeEnum.MOBILE.value());  
  26.         System.out.println(money3);  
  27.   
  28.         // 充值卡充值100 需要付多少  
  29.         Double money4 = context.calRecharge(100D,  
  30.                 RechargeTypeEnum.CARD_RECHARGE.value());  
  31.         System.out.println(money4);  
  32.     }  
  33.   
  34. }  

运行结果:

 

85.0

90.0

100.0

101.0

从上面类图和代码可以看出,策略模式把具体的算法封装到了具体策略角色内部,增强了可扩展性,隐蔽了实现细节;它替代继承来实现,避免了if-else这种不易维护的条件语句。当然我们也可以看到,策略模式由于独立策略实现,使得系统内增加了很多策略类;对客户端来说必须知道兜友哪些具体策略,而且需要知道选择具体策略的条件。
分享到:
评论

相关推荐

    设计模式浅谈1——策略模式

    策略模式是一种行为设计模式,它使你能在运行时改变对象的行为。在软件工程中,我们经常遇到需要根据不同条件或场景动态地改变算法的情况。策略模式就是为了解决这类问题而诞生的,它允许我们用不同的策略(即算法)...

    浅谈简单工作流设计——责任链模式配合策略与命令模式的实现

    本文以项目中的一个工作流模块,演示责任链模式、策略模式、命令模式的组合实现!最近在做的一个项目,涉及到的是一个流程性质的需求。关于工程机械行业的服务流程:服务任务流程和备件发运流程。项目之初,需求不是...

    浅谈多级分布式库存管理模式在海洋石油企业的应用.pdf

    针对传统库存管理模式的弊端,戴雀桥在其文章《浅谈多级分布式库存管理模式在海洋石油企业的应用》中提出了一个基于协调中心的多级分布式库存管理模式。这种模式强调从供应链整体的角度出发,协调和控制供应链上的...

    浅谈电商B2C模式

    电商平台如淘宝商城(现天猫)的提价策略,反映出B2C模式对信用体系、价格竞争以及服务质量的要求日益提升,同时,也显示出该模式的盈利潜力和市场前景。 四、B2C模式面临的困难 尽管B2C模式展现出强大的生命力,...

    浅谈小学数学深度学习的教学策略.pdf

    与传统教学模式相比,深度学习更注重全过程学习,强调学习过程的可视性,以及心灵感知的作用。 在小学数学深度学习的教学策略上,有几点是值得探讨的: 首先,营造良好的教学环境至关重要。由于小学数学较为抽象,...

    浅谈以人为本模式下的小学学校科学管理策略.docx

    【以人为本的管理模式】在小学学校科学管理中,以人为本的核心理念是指将师生的需求和发展放在首位,以激发他们的潜能和积极性为目标,构建和谐、高效的教学环境。这种管理模式强调尊重个体差异,关注教师的职业发展...

    快捷支付浅谈

    ### 快捷支付浅谈:便捷性和安全性分析 #### 一、引言 近年来,随着互联网技术的迅猛发展,各种新型支付方式不断涌现,其中快捷支付作为一种新兴的互联网支付模式,因其便捷的操作流程和较高的用户体验受到广泛...

    浅谈网络营销的策略.zip

    这篇文档“浅谈网络营销的策略”将深入探讨这个主题,旨在帮助读者理解并掌握在网络环境中实施有效营销策略的关键点。 首先,网络营销的核心是了解目标市场和消费者。在数字化时代,消费者的行为模式发生了巨大变化...

    浅谈星巴克盈利模式.doc

    星巴克的商业模式可以分为运营性和策略性两大类,两者共同构建了其独特的价值体系。 一、运营性商业模式 1. 产业价值链定位:星巴克位于咖啡产业链的下游,作为零售端,通过提供高质量的咖啡、糕点和相关商品,...

    浅谈生鲜电商物流渠道下沉的阻碍与未来发展策略.pdf

    生鲜电商物流渠道下沉是指将电商物流配送体系从主要的城镇区域向农村地区拓展,旨在提升...生鲜电商物流下沉的成功实施将极大地促进农村地区的消费模式转变,提升农民的生活品质,并且推动整个生鲜电商行业的健康发展。

    玩具行业专题报告:玩具系列VI之商业模式:推本溯源浅谈我国中小玩具企业突围之路.pdf

    玩具行业的商业模式探讨集中在如何构建一个以知识产权(IP)为核心的泛娱乐...在这个过程中,IP的核心作用得到了强调,同时也提出了一个渐进式的IP布局模式,这被证明是符合大多数中小玩具企业当前发展阶段需求的策略。

    浅谈烟草企业财务管理模式现状及创新策略

    鉴于上述问题,烟草企业财务管理模式的创新策略应包括: 1. 建立健全财务管理体系:烟草企业需要深刻理解现代企业管理思想,完善审批流程,明确岗位职责,实现重要岗位间的相互监督和制约。同时,要建立资产管理、...

    204-2 浅谈汽车营销策略(1).zip

    这篇文档“204-2 浅谈汽车营销策略(1)”深入探讨了汽车行业的营销之道,旨在为相关人员提供宝贵的指导。以下是对这个主题的详细解析。 一、市场分析 在制定营销策略之前,对市场进行深入分析至关重要。这包括了解...

    设计模式浅谈24种.ppt

    在《设计模式浅谈24种》中,主要讨论了24种经典的GOF设计模式,这些模式被分为三大类:创建型、结构型和行为型。 创建型模式主要关注对象的创建,包括以下几个核心模式: 1. **Abstract Factory**(抽象工厂)模式...

    浅谈电商模式中的原创服装品牌及运营.pdf

    本文将详细解读电商模式中原创服装品牌的重要性以及其运营策略。 首先,我们需要认识到服装行业本身的特点及发展趋势。服装作为人们生活的基本需求,随着我国经济的持续增长和人民生活水平的提高,其市场需求正变得...

    浅谈电商模式中的原创服装品牌及运营.zip

    本文将深入探讨电商模式如何助力原创服装品牌的创立与发展,以及运营策略的关键点。 首先,电商模式为原创服装品牌提供了广阔的市场空间。通过线上平台,品牌可以直接触达全国乃至全球的消费者,不再受限于实体店铺...

    浅谈4S店的营销策略.doc

    3. **分销策略**:4S店通常采用直销模式,但也可以通过线上平台进行销售。建立多渠道的销售网络,如电商平台、社交媒体等,能扩大市场覆盖,吸引更多潜在客户。 4. **促销策略**:定期举办优惠活动,如打折促销、...

    浅谈电动汽车的整车控制策略.pdf

    本文主要探讨了电动汽车的四种主要控制策略:起步控制策略、标准模式控制策略、动力模式控制策略以及经济模式控制策略。 1. 电动汽车的起步控制策略: 起步阶段是电动汽车从静止状态加速到一定速度的过程。电机在此...

    204-2 浅谈汽车营销策略.zip

    "204-2 浅谈汽车营销策略"的主题着重于探讨如何通过创新的营销手段来推动汽车销售和品牌建设。以下是对这一主题的详细分析: 一、市场定位 汽车营销策略的第一步是明确市场定位。这涉及对目标消费者进行深入研究,...

    204-2 浅谈汽车营销策略-论文.zip

    这篇名为“204-2 浅谈汽车营销策略”的论文深入探讨了汽车行业的市场营销战略,涵盖了品牌定位、消费者行为分析、产品推广、销售渠道和售后服务等多个重要方面。以下是对这篇论文内容的详细解读: 一、品牌定位 ...

Global site tag (gtag.js) - Google Analytics