`

四十五:策略模式

阅读更多
策略模式属于对象的行为模式,其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响客户端的情况下发生变化.

问题描述:
假设现在要对不同地图书进行打折,如对所有教材类图书实行每本一元的折扣,对连环画图书每本7%的折扣,对非教材类的计算机图书3%的折扣,其余图书没有折扣.这个问题如何解决?
解决方案:
(1)所有的业务逻辑都放在客户端里面,客户端利用条件选择语句决定使用哪一个算法,这样的话客户端代码会变得复杂难以维护.
(2)客户端可以利用继承的办法在子类里面实现不同的行为,但是这样会使得环境和行为紧密耦合在一起,强耦合会使两都不能单独深化
(3)使用策略模式把行为和环境割开来,环境类负责维持和查询行为类,各种算法则在具体的策略类(ConcreteStrategy)中提供,由于算法和环境独立开来,算法的增减,修改都不会影响环境和客户端.
策略模式正是解决这个问题的系统化方法,当出现新的折扣或现有的折扣政策出现变化时,只需要实现新的策略类,并在客户端登记即可,策略模式相当于"可插入式的算法"

一:策略模式的结构
这个模式涉及到三个角色:
(A)环境(Context)角色:持有一个Strategy类的引用.
(B)抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现,此角色给出所有的具体策略类所需要的接口。
(C)具体策略(ConcreteStrategy)角色:包装了相关的算法或行为
下面是示意代码:
package cai.milenfan.basic.test; 

public class Context { 
private Strategy strategy; 
//策略方法 
public void contextInterfact(){ 
strategy.strategyInterface(); 
} 
} 


package cai.milenfan.basic.test; 

abstract public class Strategy { 
//策略方法 
public abstract void strategyInterface(); 
} 


package cai.milenfan.basic.test; 

public class ConcreteStrategy extends Strategy{ 
//策略方法 
public void strategyInterface(){ 
//write your algorithm code here 
} 
} 


这里所给出的仅仅是策略模式的最小实现,因此具体策略角色只有一个,一般而言,有意义的策略模式的应用都会涉及到多于一个的具体策略角色。

二:Java语言内部的例子611
(1)AWT中的LayoutManager
java.awt类库需要在运行期间动太地由客户端决定一个Container对象怎么排列它所有的GUI构件,Java语言提供了几种不同的排列方式,包装在不同的类里:BorderLayout,FlowLayout,GridLayout ,GridBagLayout,CardLayout
以上五个类就是具体策略角色,java.awt.Container是环境角色,而java.awt.LayoutManager则提抽象策略角色。
(2)Swing中的Border
........

三:图书折扣的计算
package cai.milenfan.basic.test; 

abstract public class DiscountStrategy 
{ 
     abstract public double calculateDiscount(); 
} 


package cai.milenfan.basic.test; 

public class FlatRateStrategy extends DiscountStrategy{ 
private double amount; 
     private double price = 0; 
     private int copies = 0; 

     public FlatRateStrategy(double price, int copies) 
     { 
         this.price = price; 
         this.copies = copies; 
     } 

     public double getAmount() 
     { 
         return amount; 
     } 

     public void setAmount(double amount) 
     { 
         this.amount = amount; 
     } 

     public double calculateDiscount() 
     { 
return copies * amount; 
     } 

} 


package cai.milenfan.basic.test; 

public class NoDiscountStrategy extends DiscountStrategy{ 
private double price = 0.0; 
     private int copies = 0; 

     public NoDiscountStrategy(double price, int copies) 
     { 
         this.price = price; 
         this.copies = copies; 
     } 

     public double calculateDiscount() 
     { 
return 0.0; 
     } 
} 


package cai.milenfan.basic.test; 

public class PercentageStrategy { 
private double percent = 0.0; 
     private double price = 0.0; 
     private int copies = 0; 

     public PercentageStrategy(double price, int copies) 
     { 
         this.price = price; 
         this.copies = copies; 
     } 

     public double getPercent() 
     { 
         return percent; 
     } 

     public void setPercent(double percent) 
     { 
         this.percent = percent; 
     } 

     public double calculateDiscount() 
     { 
return copies * price * percent; 
     } 
} 



四:在什么情况下应当使用策略模式
(1)如果在一个系统里面有许多类,它们之间的区别仅仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为
(2)一个系统需要动态地在几种算法中选择一种,那么可以包装到一个个的具体算法类里面,而这些具体的算法类都是一个抽象算法类的子类。换言之,这些具体算法均有统一接口,由于多态性原则,客户端可以选择使用任何一个具体算法类.
(3)如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现,如果使用策略模式把这些行为转移到相应的具体策略类里,就可以避免使用难以维护的多重条件选择语句,并体现面向对象设计的概念.

五:策略模式的优缺点
(1)策略模式提供了管理相关算法族的办法,策略类的等级结构定义了一个算法或行为,恰当使用继承可以把公共的代码移到父类里面,从而避免代码重复。
(2)策略模式提供了可以替换继承关系的办法.继承会使动态改变算法变得不可能.
(3)策略模式造成很多的策略类,可以使用享元模式来减少对象的数据.
分享到:
评论

相关推荐

    Head First 设计模式 JAVA源码

    第九讲:策略模式 第十讲:观察者模式 第十一讲:享元模式 第十二讲:代理模式 第十三讲:外观模式 第十四讲:组合模式 第十五讲:桥接模式 第十六讲:适配器模式 第十七讲:解释器模式 第十八讲:中介者...

    “琢璞”系列报告之四十二:公募基金投资者的行为偏差.pdf

    报告“琢璞”系列之四十二专注于公募基金投资者的行为偏差,主要研究了个人投资者在投资决策中的非理性行为和心理偏误。该研究通过分析大量美国个人投资者的经纪账户数据,揭示了行为金融学中的一些关键概念如何影响...

    20210721-国信证券-市场思考随笔之六十四:投资理念,新旧转换,越转越快.pdf

    这四个转变方向分别是:价值投资不等于低估值投资、传统经济周期框架分析股市已经失效、从超预期投资到产业趋势投资、摆脱均值回归思维的束缚。 价值投资不等于低估值投资 在市场中,很多人把价值投资与低估值投资...

    二十二种设计模式.pdf

    无水印、可复制版本 一、原型模式 二、单例模式 ...十五、迭代器模式 十六、备忘录模式 十七、中介者模式 十八、状态模式 十九、观察者模式 二十、策略模式 二十一、模板方法模式 二十二、访问者模式

    设计模式C++版

    (二)策略模式:策略模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,让算法的变化独立于使用它的客户。与工厂模式结合,可以根据策略动态地创建和切换行为。 (三)装饰模式:装饰模式在不改变...

    盘点:电商十种赚钱的运营模式.doc

    这十种模式不仅展示了成功的商业策略,还提供了宝贵的启示,对于寻求创新和发展路径的企业家来说极具参考价值。 ### 模式一:中粮模式——玩转产业链 中粮集团通过整合农业产业链上的各个关键环节(如技术、信息、...

    三十种架构设计模式(上).pdf

    ### 三十种架构设计模式(上) #### 一、引言 随着软件工程的发展与进步,设计模式成为了软件开发人员不可或缺的一部分。它们是基于长期实践经验总结出来的通用解决方案,旨在帮助开发者解决常见问题并提高代码...

    设计模式PPT.rar

    01第一讲简单工厂模式 02第二讲工厂方法模式 03第三讲抽象工厂模式 04第四讲工厂模式在开发中的运用 05第五讲单例模式 06第六讲原型模式 07第七讲建造者模式 08第八讲装饰模式 09第九讲策略模式 10第十讲观察者模式 ...

    Juniper防火墙技术资料 基本原理+管理+高可用性

    第五章:接口模式 第六章:为策略构建块 第七章:策略 第八章:地址转换 第十一章:系统参数 管理 Juniper防火墙初始化配置和操纵 查看系统概要信息 主菜单常用配置选项导航 Configration配置菜单 Networks配置菜单...

    guide_to_php_design_pattern_zh.pdf

    - 第十四章:策略模式 - 第十五章:模板方法模式 - 第十六章:迭代器模式 - 第十七章:观察者模式 - 第十八章:命令模式 - **翻译团队**:本书的中文版由PHPChina成员翻译完成,各章节分别由不同的译者负责。 ...

    长久以来对设计模式的重大误解

    例如,函数式编程中也有类似于策略模式或装饰器模式的思想。 误区三:过度使用设计模式。设计模式是为了提高代码可读性、可维护性和灵活性,但并非所有问题都需要设计模式来解决。滥用设计模式可能导致代码过于复杂...

    C++设计模式

    (二)策略模式 4 策略与工厂结合 6 单一职责原则 6 开放――封闭原则 6 里氏代换原则 7 依赖倒转原则 7 (三)装饰模式 7 (四)代理模式 9 (五)工厂方法模式 11 (六)原型模式 13 (七)模板方法模式 15 迪米特...

    61条面向对象设计的经验原则

    **原则四十五:** 在设计系统时,为常见的操作提供简便快捷的途径。这有助于提高用户的满意度和工作效率。 **原则四十六:** 如果不需要频繁访问某项信息,则无需将其存储在内存中。这样做可以节省资源,并提高系统...

    PHP设计模式介绍.

    通过将算法封装在独立的类中,策略模式允许你在不修改客户端代码的情况下,动态地替换和更改算法。这对于需要在运行时调整行为或性能优化的场景特别有帮助。 #### 第八章:迭代器模式—遍历集合的新视角 迭代器...

    科创板新股申购策略之二十六:迈得医疗报价策略,估值区间6527%~6591%分位理性选择-1115-申万宏源-10页.pdf

    科创板是中国股市中一个独立于现有主板市场的板块,主要面向科技创新型企业,允许尚未盈利的企业上市,强调以科技创新为核心的发展模式。新股申购策略是指投资者针对新上市股票发行过程中的申购行为所采取的一系列...

    面向对象10个设计模式类图和总结

    一、策略模式 定义:定义了一个算法家族,当有一些算法和策略,而且这些算法和策略可以互相替换。 应用条件:有多个算法或策略 案例:商场销售、象棋 类图: * Strategy(策略接口) + ConcreteStrategyA...

    设计模式-状态模式分享ppt

    - **策略模式**:关注的是算法的选择,用户可以根据需要选择不同的算法来解决问题,状态之间的转换是显式的,由用户控制。 #### 八、状态模式在实际项目中的应用案例 假设我们有一个订单系统,订单的状态包括新建、...

    建材行业2019年三季报总结:B模式当前完胜,C模式不要悲观.pdf

    随着2017年《建筑业发展“十三五”规划》的出台,要求到2020年新开工全装修成品住宅面积达到30%。此后,各地政府也相继发布了相应的全装修政策,要求商品住宅项目全部实行全装修。这导致精装房市场的快速扩张,到...

    JAVA技术61条面向对象设计的经验原则.txt

    #### 原则四十五:合理使用抽象类 - **描述**:合理选择何时使用抽象类。 - **应用**:抽象类提供了一种很好的方式来定义共有的行为和状态。 #### 原则四十六:避免过度泛化 - **描述**:避免为了追求通用性而牺牲...

Global site tag (gtag.js) - Google Analytics