设计模式——行为型模式之借助策略模式(Strategy Pattern)减少使用不必要的if-else if -else和switch-case(三)
2017-11-14 14:13
453 查看
引言
前一篇文章[设计模式——行为型模式之通过中介者模式实现各模块之间的解耦 [(http://blog.csdn.net/crazymo_/article/details/73527482)总结行为型模式中的中介者模式,通过中介者模式我们可以让各模块专注于自己的核心工作,二把交互等次要问题交给中介者,实现一定程度的解耦,今天就接着总结另一种简单而又有效的行为型模式,相信大家对于if-else if-else 应该再也熟悉不过,也肯定曾经想过如何去减少使用不必要的if-else if-else 和switch这样的条件语句,学习了策略模式之后,你会发现原来代码还可以更简洁。一、策略模式概述
策略模式(Strategy Pattern)也有叫做政策模式(Policy Pattern)的 是一种比较简单的行为型模式——定义一组算法,将每个算法都封装起来,并且使它们之间可以互换(Define a family of algorithms,encapsulate each one,and make them interchangeable)。简而言之,首先定义一组算法继承同一接口或者抽象类,然后将算法封装到一个上下文类中,最后通过上下文类去调用算法而非算法自身的实现类。所以通常策略模式的主要参与角色:Conext上下文封装策略类、Strategy抽像策略类、ConreteStrateg具体抽象类。二、策略模式的优点和缺点及可用场景
1、策略模式的优点
结构清晰,使用简单,代码简捷易读易扩展高内聚低耦合
封装可以更为彻底,数据分离
策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码移到父类里面,从而避免代码重复。
使用策略模式可以避免使用if-else if-else、switch-case等多重条件语句。大量多重条件语句不易维护,而且代码也不够简洁,它把采取哪一种算法的逻辑与行为的逻辑实现在一起,统统列在一个多重条件语句里面,比使用继承的办法还要原始和落后。
2、策略模式的缺点
由于策略模式把每个具体的策略实现都单独封装成为类,如果备选的策略很多的话,那么对象的数目就会很可观。所有的策略类都必须对客户端完全可见,这意味着客户端得对这些策略思想完全理解,并由客户自行决定使用哪一个策略类,从一定程度上说增加了客户端的成本。
3、策略模式的可用场景及注意事项
当一组算法对应一个任务,并且程序可以在运行时灵活的选择其中一个算法,策略模式是很好的选择。需要安全的封装平等的多种不同类型操作
当同一抽象类拥有很多具体子类时且程序运行的时候需要动态决定使用哪一具体类时
策略模式的重心不是如何实现算法,而是关注如何组织、调用这些算法,从而让程序结构更灵活,具有更好的维护性和扩展性。
策略模式中各个策略算法的平等性。对于一系列具体的策略算法,大家的地位是完全一样的,正因为这个平等性,才能实现算法之间可以相互替换。所有的策略算法在实现上也是相互独立的,相互之间是没有依赖的。
运行时策略的互斥性,策略模式在运行的每一个时刻只能使用这组被封装算法中的某一个,虽然可以动态地在不同的策略实现中切换,但是同时只能使用一个。
策略的抽象实现,当所有的具体策略类都有一些公有的行为。此时根据设计原则应把这些公有的行为放到共同的抽象策略角色Strategy类里面。
三、策略模式的实现
策略模式本质就是对已知的实现同一任务的一组算法进行统一封装,从而把使用算法的调用和算法实现本身分割开来,再把算法的调用委派到统一的ContextStrategy对象管理,客户端通过ContextStrategy来间接调用算法。策略模式的通用UML类图如下:ContextStrategy角色:持有一个Strategy的引用,统一管理策略的调用
Strategy抽象策略角色:这是一个抽象角色,是基于面向对象设计原则考虑的,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的公共接口。
ConcreteStrategy具体策略角色:具体的算法或行为实现类
以我们日常生活的移动支付为例,我们常常在第三方APP中调用微信、支付宝、银联卡完成支付,接下来按步骤一步步实现
1、实现Strategy抽象策略
//从调用微信、支付宝、银联卡可以抽出一个公共的策略接口,同时也是为了实现定义中的互换 public interface PayStrategy { public void pay(float money); }
2、实现ContextStrategy角色
public class ContextStrategy { private PayStrategy strategy; public ContextStrategy(){ } public void payout(float money){ strategy.pay(money);//调用策略 } public void setStrategy(PayStrategy strategy){ this.strategy=strategy;//设置策略类 } }
3、实现具体的策略
public class AliPayStrategy implements PayStrategy { @Override public void pay(float money) { //调用支付宝的接口具体代码 略... if(money<=200){ System.out.println("通过调用支付宝的接口"+"直接支付了"+money); }else{ System.out.println("通过调用支付宝的接口"+"输入密码验证再支付了"+money); } } }
public class WeChatPayStrategy implements PayStrategy { @Override public void pay(float money) { //调用微信的接口略。。。。 System.out.println("通过调用微信支付的接口支付了"+money); } }
4、测试
public class MainStrategyClient { public static void main(String[] args) { ContextStrategy strategy=new ContextStrategy(); strategy.setStrategy(new AliPayStrategy()); strategy.payout(1000f); strategy.setStrategy(new WeChatPayStrategy()); strategy.payout(20f); } }
源码传送门
相关文章推荐
- 架构 之 使用子类多态 and 使用state模式(使用面向对象技术替代switch-case和if-else)
- 大量if else 或者switch case可以采用的设计模式-----状态模式
- 求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句
- 求1+2+…+n, 要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句(A?B:C)。
- 【九度1506】求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
- 不使用乘除法,for,while,if,else,switch,case,条件判断语句(A?B:C) 实现:1+2+....+n
- 求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case 等关键字以及条件判断语句
- 求1+2+3+...+n,要求不能使用乘除法,for,while,if,else,switch,case等关键字以及条件判断语句
- 求 1+2+3+..n不能使用乘除法、 for 、 while 、 if 、 else 、 switch 、 case 等关键字以及条件判断语句
- 求1+2+…+n 要求不能使用 乘 除 法、for、while、if、else、switch、case等关键字以及条件判断语句
- 【练习】题目:求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case 等关键字以及条件判断语句
- 题目:求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句(A?B:C)。
- PHP 不用求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句(A?B:C)
- 使用面向对象技术替代switch-case和if-else
- 每天学习一算法系列(12) (求1+2+…+n,不能使用乘除法,for、while、if 、else、switch、case 等关键字以及条件判断语句)
- 求1+2+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句
- 求1+2+3+...+n,要求不能使用乘除法,for,while,if,else,switch,case等关键字以及条件判断语句
- 求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句(A?B:C)
- 使用虚函数,减少累赘的if/else/switch
- 条件分支结构(switch-case)(if-else if-else) 2011.05.09