我也来学设计模式_策略模式

  设计模式Design Pattern,一个已经被大家聊烂的话题,好多年前都已经看到,但一直没有看懂,可能是自己水平有限,还达不到那个高度。时隔几年,再次捡起,哦,竟然有了那么一点眉目了~
  设计模式的书,也买了好几本了,从最开始的《大话设计模式》,以互动交流的方式进行阐述;《Head First Design Pattern》,Head First系列最经典的设计模式书之一;以及《ASP.NET 设计模式》等等。
  达不到一个层次,看这些东西的确困难,现在翻开来看,竟然也能看懂了,那就慢慢看吧,顺便把自己的心得体验放到这里~
  以上,是为序~~~ 


  今天先来聊的是策略模式Strategy Pattern,先来一段标准的GoF描述:

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

  
  我的理解就是,通过具体的策略类,来实现接口中定义的方法,这些方法在外部看来是一样的,这样,在客户端进行调用的时候,就不需要关注具体策略类的区别,而直接进行正常调用即可。
  
  还是用代码来说明这些事情,先贴上一个标准的类图:
  
  策略模式

  接下来,我们用C#的代码来进行实现:
  

1、 定义IStrategy接口
namespace StrategyPattern
{
    /// <summary>
    /// 策略接口
    /// </summary>
    public interface IStrategy
    {
        /// <summary>
        /// 算法接口
        /// </summary>
        void AlgorithmInterface();
    }
}
2、分别实例化该接口
namespace StrategyPattern
{
    /// <summary>
    /// 策略A
    /// </summary>
    public class StrategyA : IStrategy
    {
        public void AlgorithmInterface()
        {
            Console.WriteLine("算法A中的具体实现");
        }
    }

    /// <summary>
    /// 策略B
    /// </summary>
    public class StrategyB : IStrategy
    {
        public void AlgorithmInterface()
        {
            Console.WriteLine("算法B中的具体实现");
        }
    }

    /// <summary>
    /// 策略C
    /// </summary>
    public class StrategyC : IStrategy
    {
        public void AlgorithmInterface()
        {
            Console.WriteLine("算法C中的具体实现");
        }
    }
}
3、创建调用接口的Context类
namespace StrategyPattern
{
    public class Context
    {
        /// <summary>
        /// 声明接口
        /// </summary>
        protected IStrategy strategy;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="_strategy">注入的参数</param>
        public Context(IStrategy _strategy)
        {
            strategy = _strategy;
        }

        /// <summary>
        /// 具体实现方法
        /// 在里面调用策略中的算法接口
        /// </summary>
        public void DoSomething()
        {
            strategy.AlgorithmInterface();
        }
    }
}
4、客户端进行调用
namespace StrategyPattern
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            //第一个实例,使用了策略A
            Context context1 = new Context(new StrategyA());
            context1.DoSomething();

            //第二个实例,使用了策略B
            Context context2 = new Context(new StrategyC());
            context2.DoSomething();

            Console.Read();
        }
    }
}
5、查看运行结果

这里写图片描述


  以上是对策略模式的具体实现,这里只是最简单的例子,实际使用中,可能会比这更复杂,但只要简单的可以理解,复杂的无非就是多了一下接口和方法而已。
  对该模式的适用场景,主要如下:

  • 多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。
  • 需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。
  • 对客户(Context)隐藏具体策略(算法)的实现细节,彼此完全独立。
策略模式的优缺点

优点:
1、 提供了一种替代继承的方法,而且既保持了继承的优点(代码重用)还比继承更灵活(算法独立,可以任意扩展)。
2、 避免程序中使用多重条件转移语句,使系统更灵活,并易于扩展。
3、 遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。
缺点:
1、 因为每个具体策略类都会产生一个新类,所以会增加系统需要维护的类的数量。
2、必须了解所有的strategy,了解各个strategy之间的不同点,这样才能选择一个合适的strategy。对使用者也有一些挑战。

上述观点仅代表个人意见,大家可对此进行补充讨论。
  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值