设计模式之禅之设计模式-策略模式

一:策略模式的定义
        --->是一种比较简单的模式,也叫做政策模式
        --->定义一组算法,将每个算法都封装起来,并且使它们之间可以互换

二:策略模式的三个角色

● Context封装角色
        --->它也叫做上下文角色,起承上启下封装作用,屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化。
● Strategy抽象策略角色
        --->策略、算法家族的抽象,通常为接口,定义每个策略或算法必须具有的方法和属性
● ConcreteStrategy具体策略角色
        --->实现抽象策略中的操作,该类含有具体的算法。

三:策略模式的优点缺点

优点
● 算法可以自由切换
        --->这是策略模式本身定义的,只要实现抽象策略,它就成为策略家族的一个成员,通过封装角色对其进行封装,保证对外提供“可自由切换”的策略。
● 避免使用多重条件判断
        --->如果没有策略模式,我们想想看会是什么样子?一个策略家族有5个策略算法,一会要使用A策略,一会要使用B策略,怎么设计呢?使用多重的条件语句?多重条件语句不易维护,而且出错的概率大大增强。使用策略模式后,可以由其他模块决定采用何种策略,策略家族对外提供的访问接口就是封装类,简化了操作,同时避免了条件语句判断。
● 扩展性良好
        --->这甚至都不用说是它的优点,因为它太明显了。在现有的系统中增加一个策略太容易了,只要实现接口就可以了,其他都不用修改,类似于一个可反复拆卸的插件,这大大地符合了OCP原则

缺点
● 策略类数量增多
        --->每一个策略都是一个类,复用的可能性很小,类数量增多。
● 所有的策略类都需要对外暴露
        --->上层模块必须知道有哪些策略,然后才能决定使用哪一个策略,这与迪米特法则是相违背的,我只是想使用了一个策略,我凭什么就要了解这个策略呢?那要你的封装类还有什么意义?这是原装策略模式的一个缺点,幸运的是,我们可以使用其他模式来修正这个缺陷,如工厂方法模式、代理模式或享元模式。

三:策略模式的使用场景

● 多个类只有在算法或行为上稍有不同的场景。
● 算法需要自由切换的场景。
        --->例如,算法的选择是由使用者决定的,或者算法始终在进化,特别是一些站在技术前沿的行业,连业务专家都无法给你保证这样的系统规则能够存在多长时间,在这种情况下策略模式是你最好的助手。
● 需要屏蔽算法规则的场景。
        --->现在的科技发展得很快,人脑的记忆是有限的(就目前来说是有限的),太多的算法你只要知道一个名字就可以了,传递相关的数字进来,反馈一个运算结果,万事大吉。

四:策略模式的注意事项
       ---> 如果系统中的一个策略家族的具体策略数量超过4个,则需要考虑使用混合模式(比如封装者弄一个map,使用者传一个标识,获取标识对应的策略),解决策略类膨胀和对外暴露的问题,否则日后的系统维护就会成为一个烫手山芋,谁都不想接。
       --->策略模式是一个非常简单的模式。它在项目中使用得非常多,但它单独使用的地方就比较少了,因为它有致命缺陷:所有的策略都需要暴露出去,这样才方便客户端决定使用哪一个策略。例如,在例子中的赵云,实际上不知道使用哪个策略,他只知道拆第一个锦囊,而不知道是BackDoor这个妙计。是的,诸葛亮已经在规定了在适当的场景下拆开指定的锦囊,我们的策略模式只是实现了锦囊的管理,但是我们没有严格地定义“适当的场景”拆开“适当的锦囊”,在实际项目中,我们一般通过工厂方法模式来实现策略类的声明,读者可以参考混编模式。

五:策略模式的例子

【1】策略抽象类

 1 package com.yeepay.sxf.template13;
 2 /**
 3  * 策略的运算的接口
 4  * @author sxf
 5  *
 6  */
 7 public interface Strategy {
 8     //策略模式的运算法则
 9     public void doSomething();
10 }

【2】策略1

 1 package com.yeepay.sxf.template13;
 2 /**
 3  * 策略算法1
 4  * @author sxf
 5  *
 6  */
 7 public class ConcreteStrategy1 implements Strategy{
 8
 9     @Override
10     public void doSomething() {
11         System.out.println("ConcreteStrategy1.doSomething(策略算法1)");
12     }
13
14
15 }

【3】策略2

 1 package com.yeepay.sxf.template13;
 2 /**
 3  * 策略算法2
 4  * @author sxf
 5  *
 6  */
 7 public class ConcreteStrategy2 implements Strategy{
 8
 9     @Override
10     public void doSomething() {
11         System.out.println("ConcreteStrategy2.doSomething(策略算法2)");
12     }
13
14
15 }

【4】策略封装者

 1 package com.yeepay.sxf.template13;
 2 /**
 3  * 策略封装者
 4  * 高层模块的调用非常简单,
 5  *         知道要用哪个策略,产生出它的对象,然后放到封装角色中就完成任务了
 6  * @author sxf
 7  *
 8  */
 9 public class Context {
10
11     private Strategy strategy=null;
12
13     public Context(Strategy strategy){
14         this.strategy=strategy;
15     }
16     //锦囊执行者
17     public void doAnyThing(){
18         strategy.doSomething();
19     }
20 }

【5】客户端测试

 1 package com.yeepay.sxf.template13;
 2 /**
 3  * 客户端
 4  * @author sxf
 5  *
 6  */
 7 public class Client {
 8
 9     public static void main(String[] args) {
10         //声明一个具体的策略
11         Strategy strategy=new ConcreteStrategy1();
12         //将这个策略封装到封装者内部
13         Context context=new Context(strategy);
14         //封装者执行策略错
15         context.doAnyThing();
16         //封装者内部隐藏一群策略,根据不同的条件,执行不同的策略。
17     }
18 }

时间: 2024-10-29 05:02:55

设计模式之禅之设计模式-策略模式的相关文章

设计模式总结篇系列:策略模式(Strategy)

前面的博文中分别介绍了Java设计模式中的创建型模式和结构型模式.从本文开始,将分别介绍设计模式中的第三大类,行为型模式.首先我们了解下分为此三大类的依据. 创建型模式:主要侧重于对象的创建过程: 结构型模式:主要侧重于处理类或对象的组合: 行为型模式:主要侧重于类或对象之间的交互以及职责分配. 首先了解下策略模式的概念:定义了多个算法,并将它们封装起来(一般的是每个算法封装成一个单独的类),让算法独立于客户端而可以单独变化. 具体可以看一下下面的例子(以计算加.减.乘为例): 1. 对加.减.

设计模式 ( 十九 ):Strategy策略模式 -- 行为型

设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能.如查找.排序等,一种常用的方法是硬编码(Hard Coding)在一个类中,如需要提供多种查找算法,可以将这些算法写到一个类中,在该类中提供多个方法,每一个方法对应一个具体的查找算法:当然也可以将这些查找算法封装在一个统一的方法中,通过if…else…或者case等条件判断语句来进行选择.这

设计模式之第8章-策略模式(Java实现)

设计模式之第8章-策略模式(Java实现) “年前大酬宾了啊,现在理发冲500送300,冲1000送500了.鱼哥赶紧充钱啊,理发这事基本一个月一回,挺实惠的啊.不过话说那个理发店的老板好傻啊,冲1000才送500,不如冲两次500,这样可以送600呢.”“这只能说明你不是很笨,但是也算不上聪明.”“啊?难道我想错了?”“这是一种策略,策略,懂?他如果是冲1000送700的话你是不是很大的可能性冲500?而不是1000,但是如果这样的话,在“聪明人”,对,没错,就是你这样的人来说,冲两次500表

设计模式(一)学习----策略模式

策略设计模式:定义一组算法,将每个算法都分装起来,并使他们之间可以互换. 策略模式就是使用的面向对象思想中的继承和多态的机制 策略模式的通用类图: Context类:Strategy类,并且和Strategy类是整体和个体的关系,即聚合关系.对策略角色个体进行封装. Strategy接口:定义这个策略或算法必须有的方法和属性. ConcreteStrategy1,ConcreteStrategy2具体策略角色实现类.实现抽象策略中的方法,该类中含有具体的算法. 上图变成Java代码: 抽象的策略

【设计模式】Java设计模式第零课之策略模式

从今天开始看<<Head First 设计模式>>,打算每学习一章都写一篇笔记,今天的第零篇希望是一个好的开端,能够善始善终.加油. 设计模式入门:策略模式(看实际的需求(情景)是什么,采用适当的策略) 设计原则零:不管当初软件设计的多好,一段时间之后总是成长和改变的,否则软件就会死亡. 设计原则一:找出应用中可能需要变化之处,把他们独立出来,不要和那些不需要变化的代码混在一起 把会变化的部分取出并封装起来,好让其他部分不会受到影响 这样代码引起的不经意后果变少,系统变得更有弹性

《JavaScript设计模式与开发实践》—— 策略模式

策略模式的定义是: 定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换. (1) 使用策略模式计算奖金 经过思考,我们想到了更好的办法--使用策略模式来重构代码.策略模式指的是定义一系列的算法,把它们一个个封装起来.将不变的部分和变化的部分隔开是每个设计模式的主题,策略模式也不例外,策略模式的目的就是将算法的使用与算法的实现分离开来. 一个基于策略模式的程序至少由两部分组成.第一个部分是一组策略类,策略类封装了具体的算法,并负责具体的计算过程. 第二个部分是环境类 Context,

设计模式学习(一)——策略模式

前段时间买了一本书<Head First设计模式>,看了第一章后才对设计模式的概念有少许了解:它其实是开发过程中很多前人的经验与智慧的总结,帮助你在开发时采取更好的方式去设计各个类.方法.以及它们之间的调用.实现方式,让代码保持灵活性的同时又能更好地复用.基于学过一块知识一定要用文字记录.总结.巩固,而不是走马观花的原则,趁最近终于有空,特将前一段时间看的关于“策略模式”的内容总结于此. 场景描述 A公司要做一套模拟鸭子的游戏,游戏中会出现各种鸭子,一边游泳戏水,一边呱呱叫,还有一些会飞. 方

每天一个设计模式(1):策略模式

1.策略模式 问题的提出  一个模拟鸭子的游戏,游戏中出现各种鸭子,原本的设计是:设计了一个鸭子超类,并让各种鸭子继承此超类. 但是要加新功能:比如会飞的鸭子? 并且产品会不断更新. 两种不好的解决方案: 1.继承基类 如果在基类中加上fly()方法,所有的鸭子都会继承,造成其他鸭子不想要的改变,比如玩具鸭子不想要会飞. 原先设计中,鸭子叫的方法也有问题,各种鸭子叫声不一致,橡皮鸭不会叫. 并且每当有新的鸭子子类出现,都需要检查并可能需要覆盖这些行为. 2.继承接口 如果使用接口来定义行为,子类

设计模式实现(二)——策略模式的C++实现

一.策略模式的概念 在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改.这种类型的设计模式属于行为型模式. 在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象.策略对象改变 context 对象的执行算法. 二.例子 (1) Strategy抽象类的实现 1 #ifndef STRATEGY_H 2 #define STRATEGY_H 3 4 class Strategy { 5 public: 6 Strate