代码改变世界

如何使用策略模式

2013-09-10 16:40  残月星辰  阅读(874)  评论(4编辑  收藏  举报

什么时候能用到策略模式呢?

比如说 你之前代码中肯定或多或少的用到条件判断语句 Switch case和 If else语句,如果使用策略类就可以解开耦合,同时也使维护性和系统的可扩展性大大的增强。

下面举个例子:

如下图代码所示,ClientCode类会增加枚举City的值来调用Travel的不同方法,但是这样做的话会产生很多的判断语句,今天用于测试只列举三个,但在项目中我也看到过十多个,类就会变得很大,维护中改动也会变得很大,要是每次更改一个地方,都要对整个结构进行编译,维护起来比较麻烦。遇到这样的情况,我们就要对它进行重构,剥开耦合。

using System.Windows;

namespace StrategyPatternTest
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            MessageBox.Show(new ClientCode().IsTravelToCity().ToString());
        }
    }

    public enum City
    {
        Bejing,
        Shanghai,
        Suzhou
    }

    public  class ClientCode
    {
        public bool IsTravelToCity()
        {
            var travel = new Travel();
            return travel.IsTravelCity(City.Bejing);
        }
    }

    public class Travel
    {
        public bool IsTravelCity(City city)
        {
            switch (city)
            {
                    case City.Bejing:
                    return GetTravelCityBejing();
                    case City.Shanghai:
                    return GetTravelCityShanghai();
                    case City.Suzhou:
                    return GetTravelCitySuzhou();
                default:
                    return false;
            }
        }

        private bool GetTravelCityBejing()
        {
            return true;
        }
        private bool GetTravelCityShanghai()
        {
            return false;
        }
        private bool GetTravelCitySuzhou()
        {
            return false;
        }
    }
}

使用策略模式对上图进行重构的代码如下:把三个方法提炼成三个类,并继承IGetTravelCity类,调用时候可以通过IEnumerable<IGetTravelCity>来解除上图的Switch Case语句。


using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Linq;
namespace StrategyPatternTest
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            MessageBox.Show(new ClientCode().IsTravelToCity().ToString());
        }
    }

    public interface ITravel
    {
         bool TravelCity(City city);
    }

    public enum City
    {
        Bejing,
        Shanghai,
        Suzhou
    }

    public  class ClientCode
    {
        private Travel _travel;

        public Travel Travel
        {
            get
            {
                return _travel ?? new Travel(new List<IGetTravelCity>()
                    {
                        new GetTravelCityBejing(),
                        new GetTravelCityShanghai(),
                        new GetTravelCitySuzhou()
                    });
            }
        }

        public bool IsTravelToCity()
        {
            return Travel.TravelCity(City.Bejing);
        }
    }

    public class Travel:ITravel
    {
        private IDictionary<City, IGetTravelCity> TraveltoCity { get; set; }

        public Travel(IEnumerable<IGetTravelCity> traveltoCity)
        {
            TraveltoCity = traveltoCity.ToDictionary(v => v.City);
        }


        public  bool TravelCity(City city)
        {
            return TraveltoCity[city].IsTravelCity();
        }
    }

    public interface IGetTravelCity
    {
        City City { get; }
        bool IsTravelCity();
    }
    public class GetTravelCityBejing : IGetTravelCity
    {
        public City City 
        {
            get { return City.Bejing;}
        }
        public bool IsTravelCity()
        {
          return  true;
        }
    }
     public class GetTravelCityShanghai : IGetTravelCity
    {
        public City City 
        {
            get { return City.Shanghai;}
        }
        public bool IsTravelCity()
        {
          return  false;
        }
    }
     public class GetTravelCitySuzhou : IGetTravelCity
    {
        public City City 
        {
            get { return City.Suzhou;}
        }
        public bool IsTravelCity()
        {
          return  false;
        }
    }

}

欢迎园友拍砖,小弟才疏学浅,写此随笔只为交流学习。