c# 实现设计模式-策略模式

  现在正在看《Head First设计模式》这本书,收益很大,现在写代码巩固一下,分享给大家。

  说明:本次内容大部分来自这本书中。博主只是在看书后,关上书本,重新实现一遍,巩固知识。

  设计模式就是一些普遍问题的解决方案。

  首先说下书中的前三个设计原则 

   一 、将对象类中容易发生改变的地方提取出来,进行封装。

   二、针对接口编程,而不是对象。

   三、多用组合,少用继承。

   下面就具体例子来进行说明。

    我们针对鸭子来进行设计一个项目,实现一个鸭子的功能。首先分析一下,鸭子肯定都会游泳(天性)。

    然后后面需求发生了变化(项目中经常遇到),有的鸭子可能会飞,有的鸭子不能飞,有的鸭子可以飞很快,有的鸭子可能飞不高。。。。同样,鸭子会叫,嘎嘎叫,但是有些鸭子又不能叫(不要纠结原因,可能哑巴了呢?) 。

    如果按照以往,我们可能有以下两个方法:

    方法一:我们可能就是设计一个基本的鸭子类,Duck,实现3个公共方法,swim(),quack(),fly().然后具体的实现类继承基类,实现方法,现在问题是:飞的方式可能会改变,多种多样,如果这样设计,那么,后面如果需求改变了(鸭子飞的模式改变了),那么,多整个程序的修改是灾难性的,而且容易出错。

    方法二:我们将飞行方法提取出来,设计成接口。然后具体的鸭子实现飞行接口就行,但是这样同样有个问题,如果一个对象声明了100次,同样这个对象的飞行方法后面需求发生了改变,那么,同样的要修改100个地方,想想就觉得恐怖。(这里用到了前面设计原则的第一条和第二条)

   怎么解决?

   策略模式告诉你一些新的经验,解决这些问题。

   第一步:将改变的地方,提取出来。

   鸭子的飞行方法和嘎嘎叫方法,提出来。

   第二步:针对接口编程,而不是对象。

   将飞行方法和嘎嘎叫方法设计成接口。如下:

   /// <summary>
    /// 飞行接口
    /// </summary>
    public interface IFly
    {
         void fly();
       
    }
/// <summary>
    /// 嘎嘎叫方法
    /// </summary>
    public interface IQuack
    {
        /// <summary>
        /// 嘎嘎叫方法
        /// </summary>
        void Quack();
    }

       然后实现飞行接口和嘎嘎叫接口。比如有一个飞的方法类。声明如如下:

 

/// <summary>
    /// 能够飞行的类
    /// </summary>
    public class CanFly : IFly
    {

        public void fly()
        {
            Console.WriteLine("I Can Fly,Great!");
        }
    }
  不能飞的方法
/// <summary>
    /// 不能飞的方法
    /// </summary>
    public class CanNoFly : IFly
    {
        public void fly()
        {
            Console.WriteLine("I Can't Fly");
        }
    }

。。。。。。。

当然还有其他的飞行方法,就不说了。

第三步,使用组合,少用继承。

声明鸭子类,里面包含飞行接口对象和嘎嘎叫对象。

/// <summary>
    /// 鸭子基类  
    /// </summary>
    public abstract class Duck
    {
        /// <summary>
        /// 飞行对象
        /// </summary>
        protected IFly flyBehavor;
        /// <summary>
        /// 嘎嘎叫对象
        /// </summary>
        protected IQuack quackBehavor;
        /// <summary>
        /// 鸭子都会游泳
        /// </summary>
        public void swim()
        {
            //your method
        }
        /// <summary>
        /// 实现飞行方法
        /// </summary>
        public void Fly()
        {
            this.flyBehavor.fly();
        }

        public void Quack()
        {
            this.quackBehavor.Quack();
        }
    }

好了,万事俱备,现在看具体实现,假如我们现在有一只飞天蓝鸭,特别吊,可以蓝天下飞。

/// <summary>
    /// 飞天蓝鸭
    /// </summary>
    public class FlyBlueDuck : Duck
    {
        public FlyBlueDuck()
        {
            flyBehavor = new CanFly();
            quackBehavor = new CanNoQuack();
        }
    }

我们在类初始化里面定义好这种鸭子的飞行方法。然后调用就行。

class Program
    {
        static void Main(string[] args)
        {
            //声明一只飞天鸭
            Duck flyduck = new FlyBlueDuck();
            flyduck.Fly();
            flyduck.Quack();
        }
    }

运行结果:


如果我们想要在运行时修改飞行的方式,比如鸭子受伤了,翅膀坏了,飞不了了,那么我们需要提供一个可以修改飞行方法的入口,具体实现就是在duck类里面添加一个修改飞行接口的变量方法,同样非常简单,具体如下:

/// <summary>
    /// 鸭子基类  
    /// </summary>
    public abstract class Duck
    {
        /// <summary>
        /// 飞行对象
        /// </summary>
        protected IFly flyBehavor;
        /// <summary>
        /// 嘎嘎叫对象
        /// </summary>
        protected IQuack quackBehavor;
        /// <summary>
        /// 鸭子都会游泳
        /// </summary>
        public void swim()
        {
            //your method
        }
        /// <summary>
        /// 实现飞行方法
        /// </summary>
        public void Fly()
        {
            this.flyBehavor.fly();
        }

        public void Quack()
        {
            this.quackBehavor.Quack();
        }
        /// <summary>
        /// 运行时 改变飞行方法
        /// </summary>
        /// <param name="flybehavor"></param>
        public void setFlyMethod(IFly flybehavor)
        {
            this.flyBehavor = flybehavor;
        }

        /// <summary>
        /// 运行时改变飞行方法
        /// </summary>
        /// <param name="quackbehavor"></param>
        public void setQuackMethod(IQuack quackbehavor)
        {
            this.quackBehavor = quackbehavor;
        }
    }

然后调用:

class Program
    {
        static void Main(string[] args)
        {
            //声明一只飞天鸭
            Duck flyduck = new FlyBlueDuck();
            flyduck.Fly();
            flyduck.Quack();
            flyduck.setFlyMethod(new CanNoFly());
            flyduck.Fly();
            flyduck.setQuackMethod(new CanNoQuack());
            flyduck.Quack();
        }
    }

运行结果:


棒极了,我们实现了在运行时修改飞行的方式。

当然,我们也可以实现一种火箭鸭,鸭子可以像火箭一样飞行,具体实现方式就是实现飞行接口,实现火箭飞行类,依照上面的方式,很简单就实现了,而且,对其他地方的代码没有任何影响。

好了,我们整个策略模式大概就是这样了。

嗯,巩固的不错。继续努力,下一个模式,学习观察者模式,学会了也写一个。

源码下载:https://download.csdn.net/download/u013944207/10315530





  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值