`
lovnet
  • 浏览: 6714648 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

(原创)无废话C#设计模式之十五:Strategy

阅读更多

无废话C#设计模式之十五:Strategy

意图

定义一系列的算法,把它们一个一个封装起来,并且使它们可相互替换。本模式使得算法可以独立于它的客户而变化。

场景

在开发程序的时候,我们经常会根据环境不同采取不同的算法对对象进行处理。比如,在一个新闻列表页面需要显示所有新闻,而在一个新闻搜索页面需要根据搜索关键词显示匹配的新闻。如果在新闻类内部有一个ShowData方法的话,那么我们可能会传入一个searchWord的参数,并且在方法内判断如果参数为空则显示所有新闻,如果参数不为空则进行搜索。如果还有分页的需求,那么还可能在方法内判断是否分页等等。

这样做有几个不好的地方,一是ShowData方法太复杂了,代码不容易维护并且可能会降低性能,二是如果还有其它需求的话势必就需要修改ShowData方法,三是不利于重用一些算法的共同部分。由此引入策略模式,把算法进行封装,使之可以灵活扩展和替换。

示例代码

using System;

using System.Collections.Generic;

using System.Text;

using System.Collections;

namespace StrategyExample

{

class Program

{

static void Main(string[] args)

{

Data data = new Data();

data.Add("aaa");

data.Add("bbb");

data.Add("ccc");

data.Add("abc");

data.Show();

data.SetShowDataStrategy(new SearchData("a"));

data.Show();

data.SetShowDataStrategy(new ShowPagedData(2,1));

data.Show();

}

}

abstract class ShowDataStrategy

{

abstract public void ShowData(IList data);

}

class ShowAllData : ShowDataStrategy

{

public override void ShowData(IList data)

{

for (int i = 0; i < data.Count; i++)

{

Console.WriteLine(data[i]);

}

}

}

class ShowPagedData : ShowDataStrategy

{

private int pageSize;

private int pageIndex;

public ShowPagedData(int pageSize, int pageIndex)

{

this.pageSize = pageSize;

this.pageIndex = pageIndex;

}

public override void ShowData(IList data)

{

for (int i = pageSize * pageIndex; i < pageSize * (pageIndex + 1); i++)

{

Console.WriteLine(data[i]);

}

}

}

class SearchData : ShowDataStrategy

{

private string searchWord;

public string SearchWord

{

get { return searchWord; }

set { searchWord = value; }

}

public SearchData(string searchWord)

{

this.searchWord = searchWord;

}

public override void ShowData(IList data)

{

for (int i = 0; i < data.Count; i++)

{

if (data[i].ToString().Contains(searchWord))

Console.WriteLine(data[i]);

}

}

}

class Data

{

private ShowDataStrategy strategy;

private IList data = new ArrayList();

public void SetShowDataStrategy(ShowDataStrategy strategy)

{

this.strategy = strategy;

}

public void Show()

{

if (strategy == null)

strategy = new ShowAllData();

Console.WriteLine(strategy.GetType().ToString());

strategy.ShowData(data);

}

public void Add(string name)

{

data.Add(name);

}

}

}

代码执行结果如下图:

代码说明

l Data类就是环境或者说上下文角色,持有对策略角色的引用。在这里,我们通过一个方法来设置环境使用的策略,你也可以根据需求在构造方法中传入具体策略对象。

l ShowDataStrategy抽象类就是抽象策略角色,它定义了策略共有的接口。

l ShowAllDataShowPagedData以及SearchData类都是具体策略角色,它们实现真正的算法或行为。

l 客户端在调用的时候才决定去使用哪种策略模式。

l 可以看到,由于显示数据由各个具体策略类来实现,使得环境角色的复杂度降低了很多。并且如果以后还需要增加新的显示数据方式的话只需要增加新的具体策略类(实现抽象策略接口)就可以了,环境类的代码不需要做改动。对于各具体策略实现过程中可复用的部分也可以放在抽象策略类中实现。

何时采用

l 从代码角度来说, 如果一个类有多种行为,并且在类内部通过条件语句来实现不同的行为的时候可以把这些行为单独封装为策略类。

l 从应用角度来说,如果系统需要选择多种算法中的一种并且希望通过统一的接口来获取算法的输出的话可以考虑策略模式。

实现要点

l 在环境角色中拥有策略角色的实例。

l 如果策略角色需要使用环境中的数据,一般可以让环境把数据传给所有策略角色,或者可以让环境把自身传给策略角色,前者会带来不必要的通讯开销,后者会使环境和策略角色发生紧密耦合。根据需要选择合适的方式。

l 环境角色可以在客户端没有提供策略角色的时候可以实现模式的策略。

注意事项

l 策略模式的缺点是客户端需要了解具体的策略,因此仅当客户端能做出这样选择的时候才去使用策略模式。

l 过多的策略对象可能会增加系统负担,可以考虑把各种策略角色实现为无状态对象的享元,需要保存的额外状态由环境角色进行统一管理和处理。

分享到:
评论

相关推荐

    无废话C#设计模式系列文章

    无废话C#设计模式系列文章 http://www.cnblogs.com/lovecherry/archive/2007/10/17/927728.html

    无废话C#设计模式

    无废话C#设计模式整理版。

    无废话C#设计模式.doc

    无废话C#设计模式 软件设计模式 .net开发

    无废话C#23种设计模式

    设计模式的原则? l 单一职责:你不希望因为电脑内存损坏而更换CPU吧,同样也不应该让一个类有多种修改的理由。 l 对扩展开放,对修改封闭:你一定不希望电脑只有一个内存槽,加内存就要换主板吧,程序也应该能在...

    C#设计模式.PDF

    完整的C#设计模式PDF版 C#设计模式(1) 4 一、 C# 面向对象程序设计复习 5 二、 设计模式举例 5 三、 先有鸡还是先有蛋? 7 四、 大瓶子套小瓶子还是小瓶子套大瓶子? 8 五、 .net本质 9 C#设计模式(2) 11 一、 ...

    完整版 设计模式:基于C#的工程化实现及扩展

    摘要:电子书籍,C#教程,设计模式 设计模式:基于C#的工程化实现及扩展 pdf全书下载,本书作者以C#重新实现了GOF的模式,同时加入了新近的设计想法,如SOA与Web Services.....等,同时还有相对于其他设计模式而言较新...

    C#设计模式大全

    C#设计模式(1) 一、 C# 面向对象程序设计复习 二、 设计模式举例 三、 先有鸡还是先有蛋? 四、 大瓶子套小瓶子还是小瓶子套大瓶子? 五、 .net本质 C#设计模式(2) 一、 "开放-封闭"原则(OCP) 二、 ...

    新版设计模式手册 - C#设计模式(第二版)

    新版设计模式手册 - C#设计模式(第二版)

    C#设计模式-吕震宇

    设计模式(22)-Strategy Pattern 设计模式(21)-Template Method Pattern 设计模式(20)-Visitor Pattern 设计模式(19)-Observer Pattern 设计模式(18)-Command Pattern 设计模式(17)-Chain of ...

    C#面向对象设计模式纵横谈(视频与源码)

    讲 师:李建忠 上海祝成信息科技... C#面向对象设计模式纵横谈(23):(行为型模式) Strategy 策略模式 C#面向对象设计模式纵横谈(24):(行为型模式) Visitor 访问者模式 C#面向对象设计模式纵横谈(25):设计模式总结

    无废话C#设计模式系列教程

    某位高人撰写的C#演示设计模式的系列文章,本人觉得不错,有意者请下载。

    C#面向对象设计模式纵横谈(23):(行为型模式) Strategy 策略模式

    C#面向对象设计模式纵横谈(23):(行为型模式) Strategy 策略模式

    《c#设计模式》电子书+随书源码

    本书是第一部关于C#和.NET设计模式的权威指导著作,为基于C#语言和Microsoft ® .NET框架的开发人员学习设计模式和应用设计模式提供了一个完整全面的理论框架和大量的详细应用实例。 本书内容覆盖了所有23个经典的...

    无废话设计模式 (C#,PDF格式)

    无废话设计模式:摘录自博客园:http://www.cnblogs.com/lovecherry/

    C#面向对象设计模式纵横谈(25):设计模式总结

    C#面向对象设计模式纵横谈(25):设计模式总结

    GOF之23种设计模式的C#实现:DesignPattern.zip

    用C#语言实现的GOF之23种设计模式。设计模式的简单实现Demo,仅供学习交流用。本人原创代码,部分参考网络资料。环境:win10 64bit;VS2019;

    C#设计模式_设计模式_C#_

    创建型: 1. 单件模式(Singleton Pattern) 2. 抽象工厂(Abstract Factory) 3. 建造者模式(Builder) 4.... 策略模式(Strategy Pattern) 22. 访问者模式(Visitor Pattern) 23. 状态模式(State Pattern)

    c#设计模式 行为型模式 实验报告+源代码

    c#设计模式 行为型模式 包括8个设计模式的实验报告+源代码。实验报告包括实验类图和个人总结的一些小技巧,源代码。包括:职责链模式、命令模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略...

Global site tag (gtag.js) - Google Analytics