zoukankan      html  css  js  c++  java
  • 设计模式之——策略模式

    定义:定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

    纯概念不太好理解,让我们来看一个需求:

    现在需要制造一批不同种类的交通工具(包括汽车、摩托车、自行车……),假设所有的交通工具只有两个部分构成:引擎(热力和人力)和轮子(大小等),可以如下实现方法,抽象出交通工具Transport类:

    View Code
     1     public abstract class Transport
     2     {
     3         /// <summary>
     4         /// 引擎
     5         /// </summary>
     6         /// <returns></returns>
     7         public abstract string Engine();
     8 
     9         /// <summary>
    10         /// 轮子
    11         /// </summary>
    12         /// <returns></returns>
    13         public abstract string Wheel();
    14     }

    制造汽车(假设所有的汽车都是一样的,贴上不同的标签就是不同的牌子)、摩托车、自行车类如下所示:(简化了Engine和Wheel的制造方法)

    View Code
     1  1     public class Car:Transport
     2  2     {
     3  3         /// <summary>
     4  4         /// 热动力引擎
     5  5         /// </summary>
     6  6         /// <returns></returns>
     7  7         public override string Engine()
     8  8         {
     9  9             return "Engine For Heat";
    10 10         }
    11 11 
    12 12         /// <summary>
    13 13         /// 特制轮子
    14 14         /// </summary>
    15 15         /// <returns></returns>
    16 16         public override string Wheel()
    17 17         {
    18 18             return "Special wheel";
    19 19         }
    20 20     }
    View Code
     1     public class Motorcycle:Transport
     2     {
     3         /// <summary>
     4         /// 热动力引擎
     5         /// </summary>
     6         /// <returns></returns>
     7         public override string Engine()
     8         {
     9             return "Engine For Heat";
    10         }
    11 
    12         /// <summary>
    13         /// 一般轮子
    14         /// </summary>
    15         /// <returns></returns>
    16         public override string Wheel()
    17         {
    18             return "General wheel";
    19         }
    20     }
    View Code
     1     public class Bicycle:Transport
     2     {
     3         /// <summary>
     4         /// 人力引擎
     5         /// </summary>
     6         /// <returns></returns>
     7         public override string Engine()
     8         {
     9             return "Engine For People";
    10         }
    11 
    12         /// <summary>
    13         /// 一般轮子
    14         /// </summary>
    15         /// <returns></returns>
    16         public override string Wheel()
    17         {
    18             return "General wheel";
    19         }
    20     }

    摩托车(MotorCycle)介于Car和Bicycle之间,引擎和Car一样,Wheel和Bicycle一样,这样实现虽然解决了问题。但是有两个弊端:

    一、出现比较多的重复代码,无法达到重用。而且随着需求变化,出现三轮车(Engine、Wheel和Bicycle一样)、卡车(Engine、Wheel和Car一样)……重复的部分会越来越多。

    二、某一天,相关部门研究发现依靠热力的Engine排放了严重污染大气的尾气,需要用新研制的环保型Engine替换,就得要遍地寻找使用了原先落后技术制造的Engine,逐个更改……这无疑是个噩梦……

    是时候让策略模式出场了,首先定义Wheel和Engine的抽象接口,然后将Wheel和Engine分别实现不同的制造方法,再改变下Transport抽象类:

    IWheel和IEngine的定义:

    View Code
     1     public interface IWheel
     2     {
     3         string CreatWheel();
     4     }
     5 
     6 
     7     public interface IEngine
     8     {
     9         string CreatEngine();
    10     }

    Engine和Wheel分别分开实现各自的系列算法:

    View Code
     1     public class HeatEngine:IEngine
     2     {
     3         public string CreatEngine()
     4         {
     5             return "Engine From Heat";
     6         }
     7     }
     8 
     9 
    10 
    11     public class HuManEngine:IEngine
    12     {
    13         public string CreatEngine()
    14         {
    15             return "Engine From People";
    16         }
    17     }
    View Code
     1     public class SpecialWheel:IWheel
     2     {
     3         public string CreatWheel()
     4         {
     5             return "Special Wheel";
     6         }
     7     }
     8 
     9 
    10     public class GeneralWheel:IWheel
    11     {
    12         public string CreatWheel()
    13         {
    14             return "General Wheel";
    15         }
    16     }

    修改下Transport抽象类:

    View Code
     1     public abstract class Transport
     2     {
     3         public IEngine _engine;
     4         public IWheel _wheel;
     5 
     6         public void SetEngine(IEngine engine)
     7         {
     8             this._engine = engine;
     9         }
    10 
    11         public void SetWheel(IWheel wheel)
    12         {
    13             this._wheel = wheel;
    14         }
    15 
    16         /// <summary>
    17         /// 制造引擎
    18         /// </summary>
    19         /// <returns></returns>
    20         public string Engine()
    21         {
    22             return this._engine.CreatEngine();
    23         }
    24 
    25         /// <summary>
    26         /// 制造轮子
    27         /// </summary>
    28         /// <returns></returns>
    29         public string Wheel()
    30         {
    31             return this._wheel.CreatWheel();
    32         }
    33 
    34         /// <summary>
    35         /// 车外形
    36         /// </summary>
    37         /// <returns></returns>
    38         public abstract string Display();
    39     }

    Car、MotorCycle、Bicycle继承Transport:(因为都类似,只例举其一)

    View Code
    1     public class Bicycle : Transport
    2     {
    3         public override string Display()
    4         {
    5             return "With Blue Color";
    6         }
    7     }

    上述类和接口关系如下:

    如图所示,可以动态扩展不同的Wheel和Engine。例如新增加了电动车,使用ElectricEngine和GeneralWheel,只需要新增一个ElectricEngine继承自IEngine如下:

    View Code
    1     public class ElectricEngine:IEngine
    2     {
    3         public string CreatEngine()
    4         {
    5             return "Engine From Electric";
    6         }
    7     }

    然后客户端引用IEngine的dll,不需要额外改动任何地方即可动态更改:

    View Code
     1         static void Main(string[] args)
     2         {
     3             Transport ts = new Car();
     4             ts.SetEngine(new HeatEngine());
     5             ts.SetWheel(new SpecialWheel());
     6             Console.WriteLine("====================================");
     7             Console.WriteLine(ts.Engine() + " " + ts.Wheel() + " " + ts.Display());
     8             Console.WriteLine("====================================");
     9             Console.WriteLine("Electric Engine :");
    10             ts.SetEngine(new ElecricEngine());
    11             ts.SetWheel(new GeneralWheel());
    12             Console.WriteLine(ts.Engine() + " " + ts.Wheel() + " " + ts.Display());            
    13 
    14             Console.ReadKey();
    15         }

     程序运行结果如下图所示:

    =====================================================

    欢迎大家指正~

  • 相关阅读:
    SPOJ1007 VLATTICE
    hdu 4746Mophues[莫比乌斯反演]
    [Offer收割]编程练习赛13 B.最大子矩阵[枚举]
    [SCOI2011]飞镖[数学模拟]
    2333: [SCOI2011]棘手的操作[离线线段树]
    hdu3507 Print Article[斜率优化dp入门题]
    react 日期
    使用arc进行code review
    css冲突2 要关闭的css在项目代码以外,但是是通过<link>标签引入的css(例如bootstrap):解决方法,在APP.css中使用全局样式
    <svg>标签
  • 原文地址:https://www.cnblogs.com/yangyp/p/3018548.html
Copyright © 2011-2022 走看看