码迷,mamicode.com
首页 > 其他好文 > 详细

策略模式

时间:2014-05-10 06:27:07      阅读:431      评论:0      收藏:0      [点我收藏+]

标签:des   blog   class   code   tar   ext   

一、概念

策略模式(Strategy):它定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法的变化不会影响到使用算法的客户。(原文:The Strategy Pattern defines a family of algorithms,encapsulates each one,and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.)

bubuko.com,布布扣

图1 策略模式类图

 优点:

  1、 简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。
  2、 避免程序中使用多重条件转移语句,使系统更灵活,并易于扩展。
      3、 遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。

  缺点:
  1、 因为每个具体策略类都会产生一个新类,所以会增加系统需要维护的类的数量。
      2、 在基本的策略模式中,选择所用具体实现的职责由客户端对象承担,并转给策略模式的Context对象。(这本身没有解除客户端需要选择判断的压力,而策略模式与简单工厂模式结合后,选择具体实现的职责也可以由Context来承担,这就最大化的减轻了客户端的压力。)

参考阅读:
1. 2.

二、我的理解

其实这个策略模式和简单工厂模式一样,仅仅是对面向对象继承中常用的Override技术的一种应用。简单工厂模式中有一个工厂类,负责根据输入参数的不同来生成不同的子类,并将生成的子类作为基类返回(这样可以让客户端在使用的时候很方便)。客户端只需要调用工厂类创建一个基类的实例,然后调用这个实例的函数来实现自己的功能。而策略模式中的Context类的功能基本上就是对工厂类的强化版本,它也负责根据输入参数来生成不同的类,只是它并不返回生成类,而是将生成类所实现的功能接口包装一次,提供给客户。这样对客户来说,他们只需要知道这一个Context类就可以完成他们想要的功能,而不必再知道其他的信息。

三、策略模式与简单工厂模式结合的代码实现

下面以一个简单的商场收银系统为例,演示一下策略模式与简单工厂模式结合的使用。我将这个系统用两个工程实现。一个工程实现商场计费的业务功能,另一个工程用于实现POS机上的界面,也就是客户端。

首先介绍第一个工程:

1. 实现计费功能的基类(这里用抽象类实现): 

bubuko.com,布布扣
1 namespace ColinSong.DesignPattern.Strategy
2 {
3 public abstract class BillingAlgorithm
4     {
5 public abstract double getBillingResult(double price, int quantity);
6     }
7 }

2. 实现具体计费功能的子类:

     2.1 实现打折计费的子类:     

bubuko.com,布布扣
1 namespace ColinSong.DesignPattern.Strategy
2 {
3 public class BillingStrategy_Rebate:BillingAlgorithm
4     {
5 double discounts;
6 public BillingStrategy_Rebate(double discounts)
7         {
8 if (discounts < 0.0000001 || discounts >= 1)
9             {
10 this.discounts = 1;
11             }
12 else
13             {
14 this.discounts = discounts;
15             }
16         }
17
18 public override double getBillingResult(double price, int quantity)
19         {
20 return price * quantity * discounts;
21         }
22     }
23 }

     2.2 实现返现计费功能的子类:     

bubuko.com,布布扣
1 namespace ColinSong.DesignPattern.Strategy
2 {
3 public class BillingStrategy_CashReturn:BillingAlgorithm
4     {
5 int CashCondition;
6 int CashReturn;
7 public BillingStrategy_CashReturn(int CashCondition, int CashReturn)
8         {
9 if (CashCondition <= 0)
10             {
11                 CashCondition = 1;
12             }
13 if (CashReturn <= 0)
14             {
15                 CashReturn = 1;
16             }
17 this.CashCondition = CashCondition;
18 this.CashReturn = CashReturn;
19         }
20
21 public override double getBillingResult(double price, int quantity)
22         {
23 double orignal = price * quantity;
24 int n = (int) (orignal / CashCondition);
25 return orignal - CashReturn * n;
26         }
27     }
28 }
29

3. Context类

bubuko.com,布布扣
1bubuko.com,布布扣namespace ColinSong.DesignPattern.Strategy
2bubuko.com,布布扣{
3bubuko.com,布布扣 public class Billing
4bubuko.com,布布扣 {
5bubuko.com,布布扣 //维护一个算法基类的实例
6bubuko.com,布布扣        BillingAlgorithm billingAlgorithm;
7bubuko.com,布布扣
8bubuko.com,布布扣 //简单工厂模式的构造函数
9bubuko.com,布布扣 public Billing(string BillingStrategy)
10bubuko.com,布布扣 {
11bubuko.com,布布扣 switch (BillingStrategy)
12bubuko.com,布布扣 {
13bubuko.com,布布扣 case "打8折":
14bubuko.com,布布扣                    billingAlgorithm = new BillingStrategy_Rebate(0.8);
15bubuko.com,布布扣 break;
16bubuko.com,布布扣 case "满200返40":
17bubuko.com,布布扣                    billingAlgorithm = new BillingStrategy_CashReturn(200, 40);
18bubuko.com,布布扣 break;
19bubuko.com,布布扣 default:
20bubuko.com,布布扣                    billingAlgorithm = new BillingStrategy_Rebate(1);
21bubuko.com,布布扣 break;
22bubuko.com,布布扣            }
23bubuko.com,布布扣        }
24bubuko.com,布布扣 //策略模式的构造函数
25bubuko.com,布布扣 public Billing(BillingAlgorithm billingAlgorithm)
26bubuko.com,布布扣 {
27bubuko.com,布布扣 this.billingAlgorithm = billingAlgorithm;
28bubuko.com,布布扣        }
29bubuko.com,布布扣 //这是策略模式的典型特征
30bubuko.com,布布扣 public double GetResult(double price, int quantity)
31bubuko.com,布布扣 {
32bubuko.com,布布扣 return billingAlgorithm.getBillingResult(price, quantity);
33bubuko.com,布布扣        }
34bubuko.com,布布扣    }
35bubuko.com,布布扣}
36bubuko.com,布布扣

好,算法完成了,下面介绍客户端,界面如图2所示:

bubuko.com,布布扣

图2. 商场收银系统界面

下面看一下,确定按钮后面的代码:

bubuko.com,布布扣Code

Over。O(∩_∩)O

策略模式,布布扣,bubuko.com

策略模式

标签:des   blog   class   code   tar   ext   

原文地址:http://www.cnblogs.com/ajunForNet/p/3719373.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!