设计模式---策略模式

 

今日在学习设计模式,深深地认识了自己的不足之处啊!!也认识到了一句话:“单纯为实现功能的代码不是好代码!”。我们必须要考虑到软件行业“多变”这个老魔头,时刻保持代码的可扩展性。为了丰富自己的羽翼,也为了能够和更多的人一起学习交流,写点东西吧!

策略模式

1、什么是策略模式? 

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

2、策略模式设计原则?

     2.1 封装“变化”,使易于变化的部分独立于不变的部分,以便修改“变化”时,其他部分不受影响。

     2.2针对“接口”编程而非针对实现编程。针对“接口”编程就是针对“超类型”编程,这个“超类型”可以是“接口《interface》“也可以是”抽象类《abstract class》”。

     2.3多用组合,少用继承。可能随着你的编程技术的成熟,你会越来越发现,继承是有弊端的,如:代码在多个子类中重复,运行时的行为不容易改变,

         改变会牵一发动全身等等。 解决这个弊端的好方法之一就是使用组合。

3、如何实现策略模式?

    3.1封装“变化”,针对“接口”编程
     实现策略模式很简单,按照策略模式设计原则,我们应该把基类中易于变化的“东西”拿出来,这一部分封装成“接口”或者“抽象类”。那么我们所谓的“方法族”就是实现这个接口(或抽象类)的具体的类。比如,基类是某游戏中的“鸭子”类,我们知道所有鸭子都可以游泳,但不是所有鸭子都能呱呱叫,比如橡皮鸭子,他只会吱吱叫;也不是所有鸭子都能飞翔,橡皮鸭子就不会飞。又如,在游戏中,我们通常要加入魔幻场景,比如让鸭子借助火箭力量飞起来等。显然要用继承实现不是最好的。我们应该抽象出“飞”的行为,FlyBehavior,这个接口提供一个fly()方法。让那些飞,不会飞,借助火箭飞等等这些方法作为具体类族来实现这个接口。同理,“叫”(QuackBehavior)也是如此。这里就会有人问了,类不是对现实世界的抽象吗?不是把某个“东西”抽象吗?怎么方法也抽象出类了?对了!你说的没错,只不过,在这的这个“东西”就是个行为。

    3.2利用组合

     我们把变化的部分从基类中拿出来了,怎么把它放回去呢?——组合!在鸭子类这个基类中,添加一个FlyBehavior的对象,同理还有QuackBehavior的对象。这样,每个鸭子类的子类就都具有了FlyBehavior和QuackBehavior的对象。我们再给基类鸭子类中添加flyBehavior和quackBehavior的setter方法,以便可以运行时动态设置flyBehavior和quackBehavior。

4、策略模式类图

    每次在着手写代码前画好类图是一个非常好的编程习惯。

    先来看一下通用的策略模式类图:

    

在这里,Strategy就是接口,它定义了一个方法AlgorithmInterface,ConcreteStrageA,ConcreteStrageB,ConcreteStrageC都是具体的策略,要实习这个AlgorithmInterface方法。Context就是我们的基类,他要维护一个Strategy的对象。将来在写客户调用代码时,就可以根据需要来初始化这个Strategy的对象了。

下面我们来看一下刚才跟鸭子有关系的小游戏的类图

5、实现代码:

 1 //定义飞行方法族
 2 
 3 public interface FlyBehavior
 4     {
 5         void fly();
 6     }
 7 
 8 public class FlyWithWings:FlyBehavior
 9     {
10         public void fly()
11         {
12             Console.WriteLine("我有翅膀,可以飞翔");
13         }
14     }
15 class FlyWithRocketPower:FlyBehavior
16     {
17         public void fly()
18         {
19             Console.WriteLine("我可以借助火箭的力量飞翔");
20         }
21     }
22 public class FlyNoWay:FlyBehavior
23     {
24         public void fly()
25         {
26             Console.WriteLine("我不会飞!");
27         }
28     }
 1 //定义“叫”方法族
 2     public interface QuackBehavior
 3     {
 4         void quack();
 5     }
 6 public class MuteQuack:QuackBehavior
 7     {
 8         public void quack()
 9         {
10             Console.WriteLine("我不会叫!");
11         }
12     }
13 public class Quack:QuackBehavior
14     {
15         public void quack()
16         {
17             Console.WriteLine("我会呱呱叫!");
18         }
19     }
20 public class Quack:QuackBehavior
21     {
22         public void quack()
23         {
24             Console.WriteLine("我会呱呱叫!");
25         }
26     }
//鸭子基类
public class Duck
    {
        public FlyBehavior flyBehavior;
        public QuackBehavior quackBehavior;

        public void swim()
        {
            Console.WriteLine("我会游泳");
        }
        public virtual void display()
        {

        }

        public void performFly()
        {
            this.flyBehavior.fly();
        }
        public void performQuack()
        {
            this.quackBehavior.quack();
        }

        public void setFlybehavior(FlyBehavior fly)
        {
            this.flyBehavior = fly;
        }
        public void setQuackbehavior(QuackBehavior quack)
        {
            this.quackBehavior = quack;
        }
    }
//诱饵鸭
     public class DecoyDuck:Duck
    {
         public DecoyDuck()
         {
             this.flyBehavior = new FlyNoWay();
             this.quackBehavior = new Quack();
         }

         public override void display()
         {
             Console.WriteLine("我是诱饵鸭!");
         }
    }
//橡皮鸭
    public class RubberDuck:Duck
    {
        public override void display()
        {
            Console.WriteLine("我是橡皮鸭");
        }

        public RubberDuck()
        {
            this.flyBehavior = new FlyNoWay();
            this.quackBehavior = new Squeak();
        }
    }
//红头鸭
    public class RedheadDuck:Duck
    {
        public override void display()
        {
            Console.WriteLine("我是红头鸭!");
        }

        public RedheadDuck()
        {
            this.flyBehavior = new FlyWithWings();
            this.quackBehavior = new Quack();
        }
    }
//绿头鸭
    public class MallardDuck:Duck
    {
        public override void display()
        {
            Console.WriteLine("我是绿头鸭!");
        }
        public MallardDuck()
        {
            this.flyBehavior = new FlyWithWings();
            this.quackBehavior = new Quack();
        }
    }
//测试代码
    class Program
    {
        static void Main(string[] args)
        {
            Duck redduck = new RedheadDuck();
            redduck.performFly();
            redduck.performQuack();

            redduck.setFlybehavior(new FlyWithRocketPower());
            redduck.performFly();
            Console.ReadKey();
        }
    }

 关于策略模式一书《HEAD FIRST》中的动作冒险游戏代码可以给我发邮件(13623215228@163.com

posted on 2013-03-26 15:12  雨过晴空  阅读(274)  评论(0编辑  收藏  举报

导航