设计模式-行为型-策略模式

策略模式(Strategy):

  策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理。策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。用一句话来说,就是:“准备一组算法,并将每一个算法封装起来,使得它们可以互换”。

策略模式的角色:  

  

  1)环境类(Context):采用组合或聚合的方式维护一个对Strategy对象的引用。

  2)抽象策略类(Strategy):定义所有支持的算法的公共接口。Context使用这个接口来调用某ConcreteStrategy定义的算法。

  3)具体策略类(ConcreteStrategy):实现Strategy接口。

案例:

  某商场销售系统采用三种收费逻辑:正常收费;返现收费(满300返20);打折收费(打8折)。

 1 internal class Program
 2 {
 3     private static void Main(string[] args)
 4     {
 5         CashContext cashContext = new CashContext(new CashNormal());
 6         Console.WriteLine(cashContext.GetResult(200));
 7         CashContext cashContext2 = new CashContext(new CashRebate(0.8));
 8         Console.WriteLine(cashContext2.GetResult(200));
 9         CashContext cashContext3 = new CashContext(new CashReturn(300, 20));
10         Console.WriteLine(cashContext3.GetResult(300));
11     }
12 }
13
14 /// <summary>
15 /// 环境类Context
16 /// </summary>
17 public class CashContext
18 {
19     private CashSuper cs;
20
21     public CashContext(CashSuper cashSuper)
22     {
23         this.cs = cashSuper;
24     }
25
26     public double GetResult(double money)
27     {
28         if (cs != null)
29         {
30             return cs.AcceptCash(money);
31         }
32         return 0;
33     }
34 }
35
36 /// <summary>
37 /// 收费系统,相当于Strategy
38 /// </summary>
39 public interface CashSuper
40 {
41     double AcceptCash(double money);
42 }
43
44 /// <summary>
45 /// 正常收费
46 /// </summary>
47 public class CashNormal : CashSuper
48 {
49     public double AcceptCash(double money)
50     {
51         return money;
52     }
53 }
54
55 /// <summary>
56 /// 打折收费
57 /// </summary>
58 public class CashRebate : CashSuper
59 {
60     private double moneyRebate = 1d;
61
62     public CashRebate(double moneyRebate)
63     {
64         this.moneyRebate = moneyRebate;
65     }
66
67     public double AcceptCash(double money)
68     {
69         return money * moneyRebate;
70     }
71 }
72
73 /// <summary>
74 /// 返现收费
75 /// </summary>
76 public class CashReturn : CashSuper
77 {
78     private double moneyCondition = 0.0d;
79     private double moneyReturn = 0.0d;
80
81     public CashReturn(double moneyCondition, double moneyReturn)
82     {
83         this.moneyCondition = moneyCondition;
84         this.moneyReturn = moneyReturn;
85     }
86
87     public double AcceptCash(double money)
88     {
89         double result = money;
90         if (money >= moneyCondition)
91             result = money - Math.Floor(money / moneyCondition) * moneyReturn;
92         return result;
93     }
94 }

策略模式的优缺点:

  优点:

    1)策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码转移到父类里面,从而避免重复的代码。

    2)策略模式提供了可以替换继承关系的办法。继承可以处理多种算法或行为。如果不是用策略模式,那么使用算法或行为的环境类就可能会有一些子类,每一个子类提供一个不同的算法或行为。但是,这样一来算法或行为的使用者就和算法或行为本身混在一起。决定使用哪一种算法或采取哪一种行为的逻辑就和算法或行为的逻辑混合在一起,从而不可能再独立演化。继承使得动态改变算法或行为变得不可能。

    3)使用策略模式可以避免使用多重条件转移语句。多重转移语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重转移语句里面,比使用继承的办法还要原始和落后。

  缺点:

    1)客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。

    2)策略模式造成很多的策略类,每个具体策略类都会产生一个新类。有时候可以通过把依赖于环境的状态保存到客户端里面,而将策略类设计成可共享的,这样策略类实例可以被不同客户端使用。换言之,可以使用享元模式来减少对象的数量。

策略模式的应用场景:

  1)一个系统需要动态地在几种算法中选择一种时,可将每个算法封装到策略类中。

  2)一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现,可将每个条件分支移入它们各自的策略类中以代替这些条件语句。

  3)系统中各算法彼此完全独立,且要求对客户隐藏具体算法的实现细节时。

  4)系统要求使用算法的客户不应该知道其操作的数据时,可使用策略模式来隐藏与算法相关的数据结构。

  5)多个类只区别在表现行为不同,可以使用策略模式,在运行时动态选择具体要执行的行为。

策略模式与工厂模式的区别?

  从结构上看,策略模式和工厂模式都是子类继承抽象父类,通过传入参数到容器类(工厂模式的factory类,策略模式的Content类),选择对应的类进行行为操作。但是我们都知道工厂模式是创建型设计模式,而策略模式则是行为型设计模式。那两者到底有什么区别呢?

  1)工厂模式是用来创建对象,策略模式是让一个对象在许多行为中选择一种行为。

  2)关注点不一样,一个关注对象的创建,一个关注的是行为封装。

  3)解决不同的问题:工厂模式是创建型的设计模式,它接受指令,创建出符合要求的实例;它主要解决的是资源的统一分发,将对象的创建完全独立出来,让对象的创建和具体的使用客户无关。主要应用在多数据库选择,类库文件加载等。策略模式是为了解决的是策略的切换与扩展,更简洁的说是定义策略族,分别封装起来,让他们之间可以相互替换,策略模式让策略的变化独立于使用策略的客户。

  4)工厂相当于黑盒子,策略相当于白盒子。

策略模式与桥接模式的区别?

  在桥接模式中,Abstraction通过聚合的方式引用Implementor。策略模式中,Context也使用聚合的方式引用Strategy抽象接口。从两者的结构图可以看出,在这两种模式中,都存在一个对象使用聚合的方式引用另一个对象的抽象接口的情况,而且该抽象接口的实现可以有多种并且可以替换。可以说两者在表象上都是调用者与被调用者之间的解耦,以及抽象接口与实现的分离。但两者存在一定的区别:

  1)在形式上,在桥接模式中不仅Implementor具有变化(ConcreateImplementior),而且Abstraction也可以发生变化(RefinedAbstraction),而且两者的变化是完全独立的,RefinedAbstraction与ConcreateImplementior之间松散耦合,它们仅仅通过Abstraction与Implementor之间的关系联系起来。而在策略模式中,并不考虑Context的变化,只有算法的可替代性。

  2)在语意上,桥接模式强调Implementor接口仅提供基本操作,而Abstraction则基于这些基本操作定义更高层次的操作。而策略模式强调Strategy抽象接口的提供的是一种算法,一般是无状态、无数据的,而Context则简单调用这些算法完成其操作。

  3)桥接模式中不仅定义Implementor的接口而且定义Abstraction的接口,Abstraction的接口不仅仅是为了与Implementor通信而存在的,这也反映了结构型模式的特点:通过继承、聚合的方式组合类和对象以形成更大的结构。在策略模式中,Startegy和Context的接口都是两者之间的协作接口,并不涉及到其它的功能接口,所以它是行为模式的一种。行为模式的主要特点就是处理的是对象之间的通信方式,往往是通过引入中介者对象将通信双方解耦,在这里实际上就是将Context与实际的算法提供者解耦。

  所以相对策略模式,桥接模式要表达的内容要更多,结构也更加复杂。桥接模式表达的主要意义其实是接口隔离的原则,即把本质上并不内聚的两种体系区别开来,使得它们可以松散的组合,而策略在解耦上还仅仅是某一个算法的层次,没有到体系这一层次。从结构图中可以看到,策略的结构是包容在桥接结构中的,桥接中必然存在着策略模式,Abstraction与Implementor之间就可以认为是策略模式,但是桥接模式一般Implementor将提供一系列的成体系的操作,而且Implementor是具有状态和数据的静态结构。而且桥接模式Abstraction也可以独立变化。

参考:https://blog.csdn.net/donnie88888888/article/details/52751328

  https://blog.csdn.net/basycia/article/details/50478245

  http://www.blogjava.net/wangle/archive/2007/04/25/113545.html

原文地址:https://www.cnblogs.com/az4215/p/11617422.html

时间: 2024-08-26 16:51:18

设计模式-行为型-策略模式的相关文章

[设计模式-行为型]策略模式(Strategy)

一句话 在一个类的对象中维护策略的类的对象. 看起来和状态模式很类似. 概括 解析 STRATEGY-跟不同类型的MM约会,要用不同的策略,有的请电影比较好,有的则去吃小吃效果不错,有的去海边浪漫最合适,但目的都是为了得到MM的芳心,我的追MM锦囊中有好多Strategy哦. 策略模式:策略模式针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换.策略模式使得算法可以在不影响到客户端的情况下发生变化.策略模式把行为和环境分开.环境类负责维持和查询行为类,各种算法在具

设计模式 ( 十八 ) 策略模式Strategy(对象行为型)

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

设计模式实现C++ --策略模式Strategy(对象行为型)

1.问题 出行旅游:我们可以有几个策略可以考虑:可以骑自行车,汽车,做火车,飞机.每个策略都可以得到相同的结果,但是它们使用了不同的资源.选择策略的依据 是费用,时间,使用工具还有每种方式的方便程度. 2.解决方案 策略模式:定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换.本模式使得算法可独立于使用它的客户而变化. 策略模式把对象本身和运算规则区分开来,其功能非常强大,因为这个设计模式本身的核心思想就是面向对象编程的多形性的思想. strategy模式类图: 3.应用场景 1. 

【转】设计模式 ( 十八 ) 策略模式Strategy(对象行为型)

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

从“假如有以下几种价格10,20,50,请你代码实现将他们排序输出”看着设计模式中的策略模式

今天重温了一下策略模式,将自己的一些感悟与大家分享...本人只是技术渣渣,所理解的东西的难免会有很大的局限性甚至是错误,还请各位带着批判的眼光去看待....不喜请勿吐槽 定义:策略模式属于设计模式中的对象行为型模式,它将用到的算法单独抽象成一个单独的类.通常,我们在多个类完成同一件事情,仅仅完成的方式不同时,我们可以考虑使用这种设计模式. 举例:相信,很多人在看到"假如有以下几种价格10,20,50,请你代码实现将他们排序输出"这种题目的时候,很快就写出了以下代码,写之前还不忘了问一下

设计模式进阶(一) 策略模式

摘自<Design Paterns_Elements of Reusable Object-Oriented Software> 上一系列偏重于入门,从本篇开启进阶系列,着重于设计模式的适用情景. 回顾入门系列 设计模式入门(一)  策略模式 1  Intent Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary

JAVA设计模式(16):行为型-策略模式(Strategy)

场景 某个市场人员接到单后的报价策略(CRM系统中常见问题)报价策略很复杂,可以简单做如下分类: 普通客户小批量报价 普通客户大批量报价 老客户小批量报价 老客户大批量报价 具体选用哪个报价策略,这需要根据实际情况来确定.这时候,我们采用策略模式即可. 我们先采用条件语句处理 public class Test { public double getPrice(String type,double price){ if(type.equals("普通客户小批量")){ System.o

设计模式第二站--策略模式

从简单工厂模式出发,现在到达第二站:策略模式.那么什么是策略模式,它作为设计模式的第二站和第一站又有怎样的联系或者区别,它的理解和学习能否让我们用到和联系到第一站?怎么个关联法? 别急!下面我们就一起探究,康忙,北鼻! 一.什么是策略模式(Stragety)?          按照书本上的定义来说,策略模式定义了算法家族,分别封装起来,让它们之间可以互相替换:此模式让算法的变化,不会影响到使用算法的用户. 既然是定义都比较抽象,那么就先通过它的结构图来认识一下这个神秘的事物. 也许还是有些抽象

设计模式(一):策略模式

一.设计背景 现实生活中,我们要做一件事情或者完成某项工作,往往有很多种途径.比如我们出游,可以选择坐汽车,坐火车,土豪点的选择是坐飞机.还有我们现在线下的支付方式也有了很多种选择,以前在外面忘了带钱的话可能一瓶水都难以买到,现在只要我们手机在身上,可以用微信或者支付宝. 在软件设计层面,我们把各种支付方式叫做策略.如果不考虑设计模式的话,我们可能会在一个类中用if..else方式来选择支付方式,即 if(type == 1){ //微信支付 }else if(type == 2){ // 支付