原文 第21章 策略模式(Strategy Pattern)

策略模式

导读:策略模式看完之后,大多数人都会感觉有点混了,包括我,感觉策略模式是一种OO思想的体现(纯属个人拙见)。

概述:

 

    策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

抽象策略角色: 策略类,通常由一个接口或者抽象类实现。

具体策略角色:包装了相关的算法和行为。

环境角色:持有一个策略类的引用,最终给客户端调用。

结构图:

 

    

 

    代码举例:商品打折

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
    /// <summary>
    /// Strategy抽象类 抽象策略角色
    /// </summary>
    abstract class Strategy
    {
        public abstract double Sale();
    }
    /// <summary>
    /// 具体策略角色:包装了相关的算法和行为。
    /// </summary>
    class ConereteStrategyA : Strategy
    {
        private double price;
        public ConereteStrategyA(double price)
        {
            this.price = price;
        }
        public override double Sale()
        {
            //商品打9折
            return price * 0.9;
        }
    }
    /// <summary>
    /// 具体策略角色:包装了相关的算法和行为。
    /// </summary>
    class ConereteStrategyB : Strategy
    {
        private double price;
        public ConereteStrategyB(double price)
        {
            this.price = price;
        }
        public override double Sale()
        {
            //商品打8折
            return price * 0.8;
        }
    }
    /// <summary>
    /// 环境角色:持有一个策略类的引用,最终给客户端调用
    /// </summary>
    class Context
    {
        private Strategy strategy;
        public Context(Strategy strategy)
        {
 
            this.strategy = strategy;
        }
 
        public double Sale()
        {
            return strategy.Sale();
        }
    }

客户端调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    class Program
    {
        static void Main(string[] args)
        {
            //打9折
            Context c1 = new Context(new ConereteStrategyA(10));
            double price = c1.Sale();
            Console.WriteLine(price);
            Console.ReadLine();
            //打八折
            Context c2 = new Context(new ConereteStrategyB(10));
            double price2 = c2.Sale();
            Console.WriteLine(price2);
            Console.ReadLine();
        }
    }

优缺点:

 优点:

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

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

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

 缺点:

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

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

适用场景:

 

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

2、 需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。

3、 对客户隐藏具体策略(算法)的实现细节,彼此完全独立。


设计模式系列文章入口:http://www.diyibk.com/post/39.html

第21章 策略模式(Strategy Pattern)的更多相关文章

  1. 设计模式(一):“穿越火线”中的“策略模式”(Strategy Pattern)

    在前段时间呢陆陆续续的更新了一系列关于重构的文章.在重构我们既有的代码时,往往会用到设计模式.在之前重构系列的博客中,我们在重构时用到了“工厂模式”.“策略模式”.“状态模式”等.当然在重构时,有的地 ...

  2. 设计模式 - 策略模式(Strategy Pattern) 具体解释

    策略模式(Strategy Pattern) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26577879 本文版权全 ...

  3. HeadFirst设计模式读书笔记(1)-策略模式(Strategy Pattern)

    策略模式(Strategy Pattern): 定义了了算法簇,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户端. 第一个设计原则:找出应用中可能需要变化之处,把他们独立 ...

  4. 乐在其中设计模式(C#) - 策略模式(Strategy Pattern)

    原文:乐在其中设计模式(C#) - 策略模式(Strategy Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 策略模式(Strategy Pattern) 作者:webabc ...

  5. 反馈法学习设计模式(一)——策略模式Strategy Pattern

    简介(Introduction) 之前学习Java8实战时,遇到一个很好的策略模式示例.便想着借着这个示例结合反馈式的方法来,学习策略设计模式,也以便后面反复琢磨学习. 首先我们通过练习,逐步写出符合 ...

  6. 8.6 GOF设计模式四: 策略模式… Strategy Pattern

    策略模式… Strategy Pattern  在POS系统中,有时需要实行价格优惠, 该如何处理?  对普通客户或新客户报全价  对老客户统一折扣5%  对大客户统一折扣10%  注:课件 ...

  7. 二十四种设计模式:策略模式(Strategy Pattern)

    策略模式(Strategy Pattern) 介绍定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换.本模式使得算法的变化可独立于使用它的客户. 示例有一个Message实体类,对它的操作有 ...

  8. 设计模式系列之策略模式(Strategy Pattern)

    意图:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换. 主要解决:在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护. 何时使用:一个系统有许多许多类,而区分它 ...

  9. 十一个行为模式之策略模式(Strategy Pattern)

    定义: 定义一系列的算法,将每一个算法封装起来,并使它们之间可以相互替换,让算法具有可扩展性和对立性. 结构图: Context:环境类,算法的使用者.对外提供了算法使用的接口,并且持有一个抽象算法类 ...

随机推荐

  1. 玩转Web之Json(三)-----easy ui怎么把前台显示的dataGird中的所有数据序列化为json,返回到后台并解析

    最近做一个项目时,需要在dataGird中插入<input>,即文本输入框,当点击提交时,需要把文本框里填的数据返以及其他列的一些信息以json数组的格式返回到后台,虽然我实现了该功能,但 ...

  2. Android SDK 和 Eclipse ADT 离线安装 教程

    因为google 被限制,就是FQ后,下载的速度依旧非常慢,让人非常崩溃啊,所以这里就分享一下离线安装android SDK 和eclipse ADT 离线安装方法. 安装之前首先已经确保java s ...

  3. 创建Material Design风格Android应用--自定义阴影和裁剪视图

    之前已经写过通过应用主题和使用ListView, CardView,应用Material Design样式,同一时候都都能够通过support library向下兼容.今天要写的阴影和视图裁剪.无法向 ...

  4. .Net中获取打印机的相关信息

    原文:.Net中获取打印机的相关信息 新项目中牵涉到对打印机的一些操作,最重要的莫过于获取打印机的状态,IP等信息,代码量不大,但是也是自己花了一点时间总结出来的,希望能帮助需要的朋友. Printe ...

  5. Jquery简介选择的

    前言 Jquery一个js相框(程序代码相结合)这是一个程序开发过程中的半成品:分类似该框架EXTJS. 依赖库:jquery-XXX.js 语法:$() 正文 5择器 id选择器 $("# ...

  6. Linux平台下裸设备的绑定:

    Linux平台下裸设备的绑定: 运用RAW绑定 方法一 raw的配置(1) [root@qs-dmm-rh2 mapper]# cat /etc/rc.local #!/bin/sh # # This ...

  7. Oracle 闪回表实验

    工:闪回表实验 1.结构测试表flb_test,数据不小于10000行: TEST_USER1@PROD>create table flb_test(id number,dd date); Ta ...

  8. Gas Station [leetcode] 两个解决方案

    因为gas的总数大于cost总时间.你将能够圈住整个城市. 第一溶液: 如果一開始有足够的油.从位置i出发.到位置k时剩余的油量为L(i,k). 对随意的k.L(i,k)依据i的不同,仅仅相差常数. ...

  9. NodeJS常用模块介绍

    收集了NodeJS开发中常用的一些模块. MVC框架 - Express Express 是轻量灵活的Nodejs Web应用框架,它可以快速地搭建网站.Express框架建立在Nodejs内置的Ht ...

  10. Zen Coding 快速编写HTML/CSS代码的实现

    在本文中我们将展示一种新的使用仿CSS选择器的语法来快速开发HTML和CSS的方法.它由Sergey Chikuyonok开发. 你在写HTML代码(包括所有标签.属性.引用.大括号等)上花费多少时间 ...