知识大全 C# Design Patterns (2) -

Posted

篇首语:于今腐草无萤火,终古垂杨有暮鸦。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 C# Design Patterns (2) -相关的知识,希望对你有一定的参考价值。

C# Design Patterns (2) -   以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  Strategy Pattern (策略模式)

  所谓 Strategy Pattern 的精神 就是将策略 (算法) 封装为一个对象 易于相互替换 如同 USB 设备一样可即插即用 而不是将策略 具体的算法和行为 硬编码在某个类或客户程序中 导至事后的修改和扩展不易

  若有多种「策略」 就将这些个策略 和这些策略的算法 行为 封装在各个类中 并让这些类 去继承某个公用的抽象类或接口 接着在客户程序中 就可动态引用 且易于更换这些不同的「策略」 不会因为日后添加 修改了某一个「策略」 就得重新修改 编译多处的源代码 此即为一种「封装变化点」的做法 将常会变化的部分进行抽象 定义为接口 亦即实现「面向接口编程」的概念 且客户程序 (调用者) 只须知道接口的外部定义即可 具体的实现则无须理会

  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

  - Design Patterns: Elements of Reusable Object Oriented Sofare

  Strategy Pattern 适用的情景

  应用中的许多类 在解决某些问题时很相似 但实现的行为有所差异 比如 不同功能的程序 都可能要用到「排序」算法

  根据运行环境的不同 需要采用不同的算法 比如 在手机 PC 计算机上 因硬件等级不同 必须采用不同的排序算法

  针对给定的目的 存在多种不同的算法 且我们可用代码实现算法选择的标准

  需要封装复杂的数据结构 比如 特殊的加密算法 客户程序仅需要知道调用的方式即可

  同上 算法中的罗辑和使用的数据 应该与客户程序隔离时

     图  这张为很多书籍和文档都曾出现过的 Strategy 经典 Class Diagram

   _Shell aspx cs

  using System;

  using blogs WizardWu sample ;

  //客户程序

  public partial class _ _Shell : System Web UI Page

  

  protected void Page_Load(object sender EventArgs e)

  

  //执行对象

  Context context;

  context = new Context(new ConcreteStrategyA());

  Response Write(context ContextInterface() +

   );

  context = new Context(new ConcreteStrategyB());

  Response Write(context ContextInterface() +

   );

  context = new Context(new ConcreteStrategyC());

  Response Write(context ContextInterface() +

   );

  

  

  namespace blogs WizardWu sample

  

  //抽象算法类 (亦可用接口) 定义了所有策略的公共接口

  abstract class Strategy

  

  //算法需要完成的功能

  public abstract string AlgorithmInterface();

  

  //具体算法类A

  class ConcreteStrategyA : Strategy

  

  //算法A实现方法

  public override string AlgorithmInterface()

  

  return 算法A实现 ;

  

  

  //具体算法类B

  class ConcreteStrategyB : Strategy

  

  //算法B实现方法

  public override string AlgorithmInterface()

  

  return 算法B实现 ;

  

  

  //具体算法类C

  class ConcreteStrategyC : Strategy

  

  //算法C实现方法

  public override string AlgorithmInterface()

  

  return 算法C实现 ;

  

  

  //执行对象 需要采用可替换策略执行的对象

  class Context

  

  Strategy strategy;

  public Context(Strategy strategy)        //构造函数

  

  this strategy = strategy;

  

  //执行对象依赖于策略对象的操作方法

  public string ContextInterface()

  

  return strategy AlgorithmInterface();

  

  

   // end of namespace

  /*

  结行结果:

  算法A实现

  算法B实现

  算法C实现

  */

  上方的「Shell (壳)」示例中 最下方的 Context 类 为一种维护上下文信息的类 让 Strategy 类 (或 IStrategy 接口) 及其子类对象的算法 能运行在这个上下文里

  下方的图 及其代码 为此 Shell 示例和 Strategy Pattern 的一个具体实现示例 我们知道 Linux 和 Windows 操作系统 在文本文件的「换行符」是不同的 前者为「\\n」 后者为「\\r\\n」 若我们要设计一个文本编辑工具 或简易的编程工具 必须要能随时转换这两种不同操作系统的换行符 (假设 NET 已可执行于 Linux 上) 此时我们即不该在客户程序 (如 ASP NET 页面的 Code Behind) 中用硬编码 switch case 的 hard coding 写法 而应如下方示例 以 Strategy Pattern 实现此一功能 并将这些算法 (策略) 各自封装在各个子类中 (如 ASP NET 项目的 App_Code 文件夹中的类 或其他类库项目中的类) 使他们易于组合 更换 便于日后的维护和修改

  图  示例  _Strategy aspx cs 的 Class Diagram 此为 Sybase PowerDesigner 的「Reverse Engineer」功能 所自动产生的图

   _Strategy aspx cs

  using System;

  using blogs WizardWu sample ;

  //客户程序

  public partial class _ _Strategy : System Web UI Page

  

  String strLinuxText = 操作系统 \\n 红帽 Linux  创建的 \\n 文本文件 ;

  String strWindowsText = 操作系统 \\r\\n 微软 Windows 创建的 \\r\\n 文本文件 ;

  protected void Page_Load(object sender EventArgs e)

  

  

  protected void DropDownList _SelectedIndexChanged(object sender EventArgs e)

  

  switch(DropDownList SelectedValue)

  

  case Linux :

  Label Text = CntextInterface(new LinuxStrategy(strWindowsText));

  //Label Text = strWindowsText Replace( \\r\\n \\n );   //未用任何 Pattern 的写法

  break;

  case Windows :

  Label Text = CntextInterface(new WindowsStrategy(strLinuxText));

  //Label Text = strLinuxText Replace( \\n \\r\\n );   //未用任何 Pattern 的写法

  break;

  default:

  Label Text = String Empty;

  break;

  

  

  

  namespace blogs WizardWu sample

  

  //抽象算法类 (亦可用接口) 定义了所有策略的公共接口

  public abstract class TextStrategy

  

  protected String text;

  public TextStrategy(String text)           //构造函数

  

  this text = text;

  

  //算法需要完成的功能

  public abstract String replaceChar();

  

  //具体算法类A

  public class LinuxStrategy : TextStrategy

  

  public LinuxStrategy(String text)          //构造函数

  : base(text)

  

  

  //算法A实现方法

  public override String replaceChar()

  

  text = text Replace( \\r\\n \\n );

  return text;

  

  

  //具体算法类B

  public class WindowsStrategy : TextStrategy

  

  public WindowsStrategy(String text)     //构造函数

  : base(text)

  

  

  //算法B实现方法

  public override String replaceChar()

  

  text = text Replace( \\n \\r\\n );

  return text;

  

  

  //执行对象 需要采用可替换策略执行的对象

  public class ContextCharChange

  

  //执行对象依赖于策略对象的操作方法

  public static String contextInterface(TextStrategy strategy)

  

  return strategy replaceChar();

  

  

   // end of namespace

   

  图  示例 _Strategy aspx cs 的执行结果

  若未用任何 Pattern 的客户程序 可能就如下方的硬编码 将「换行符」和算法 直接写死在 ASP NET 的 Code Behind 里 导至事后的维护和扩展不易

  hard coding

  protected void DropDownList _SelectedIndexChanged(object sender EventArgs e)

  

  switch(DropDownList SelectedValue)

  

  case Linux :

  Label Text = strWindowsText Replace( \\r\\n \\n );

  break;

  case Windows :

  Label Text = strLinuxText Replace( \\n \\r\\n );

  break;

  default:

  Label Text = String Empty;

  break;

  

  

  此外 若用 Simple Factory Pattern (简单工厂模式) 虽然也能解决上述硬编码的问题 但就如我们前一篇帖子「C# Design Patterns ( ) Factory Method」曾经提过的缺点 日后若要添加或修改功能时 仍要修改 重新编译 server side 的「工厂类」 所以在此种情况下 用 Strategy 会是比 Simple Factory 更好的选择

  

  Strategy Pattern 的优点

  简化了单元测试 因为每个算法都有自己的类 可以通过自己的接口单独做测试

  避免程序中使用多重条件转移语句 使系统更灵活 并易于扩展

  高内聚 低偶合

  Strategy Pattern 的缺点

  因为每个具体策略都会产生一个新类 所以会增加需要维护的类的数量

  选择所用具体实现的职责由客户程序承担 并转给 Context 对象 并没有解除客户端需要选择判断的压力

  若要减轻客户端压力 或程序有特殊考量 还可把 Strategy 与 Simple Factory 两种 Pattern 结合 即可将选择具体算法的职责改由 Context 来承担 亦即将具体的算法 和客户程序做出隔离 有关这方面的概念和示例 可参考伍迷的「大话设计模式」一书 [ ]

  

  此外 从行为上来看 State Pattern 和 Strategy Pattern 有点类似 但前者可看作后者的动态版本

  State 看当前是什么状态 就采取什么动作

  Strategy 看需求及情景为何 采用适当的策略

cha138/Article/program/net/201311/12743

相关参考

知识大全 C# Design Patterns (4) - Proxy

C#DesignPatterns(4)-Proxy  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 

炭循环微电解反应器处理腈纶废水的Design-Expert设计优化

[摘要]利用Design-Expert7.1试验设计系统对炭循环微电解反应器处理腈纶废水的试验进行了试验设计和试验结果分析;通过试验设计分析得出了腈纶废水COD去除率与试验影响因素之间的定量关系模型,

炭循环微电解反应器处理腈纶废水的Design-Expert设计优化

[摘要]利用Design-Expert7.1试验设计系统对炭循环微电解反应器处理腈纶废水的试验进行了试验设计和试验结果分析;通过试验设计分析得出了腈纶废水COD去除率与试验影响因素之间的定量关系模型,

炭循环微电解反应器处理腈纶废水的Design-Expert设计优化

[摘要]利用Design-Expert7.1试验设计系统对炭循环微电解反应器处理腈纶废水的试验进行了试验设计和试验结果分析;通过试验设计分析得出了腈纶废水COD去除率与试验影响因素之间的定量关系模型,

知识大全 C#正则表达式整理备忘(2)

C#正则表达式整理备忘(2)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  ()择一匹配C#正则

知识大全 C#清理非托管对象[2]

C#清理非托管对象[2]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  publicclassM

知识大全 C#中的Namespace详解[2]

C#中的Namespace详解[2]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  别名的使用格

知识大全 C# 语言规范--2.2.1 文法表示法

C#语言规范--2.2.1文法表示法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  词法文法和句

知识大全 了解C#特性扩展方法[2]

了解C#特性扩展方法[2]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  按照上面的步骤写你就得

知识大全 C#之不安全代码(2)

C#之不安全代码(2)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  固定的和活动的变量  &a