美文网首页设计模式
浅谈设计模式1——策略模式

浅谈设计模式1——策略模式

作者: 吃根香蕉压压惊 | 来源:发表于2016-05-03 15:45 被阅读98次


    已经想看设计模式好久,但是人生就像用两个灶眼的炉台做酒席,小炒总是优先于炖老汤,最后小炒都结束,开饭了,盼了一年的老汤也没炖成。但是,今天一定要开始炖老汤。所以上午一猛劲,看完了head first的第一张——策略模式。

    进入主题
    说设计模式,我觉得还是先从理论高度阐述一下,然后再娓娓道来比较合适。

    1、背景叙述
    还是想举书中鸭子的示例,毕竟还是比较生动形象。因为鸭子有共同的特征,鸭子有颜色,可以飞、叫。所以定义一个属性和两个方法:

    class Duck
    {
            Color color;
            public void fly()  {println("I can fly"); }
            public void quack() { println("I can quack");}
    }
    

    鸭子又有不同的类别,比如家养的鸭子,野鸭。所以可以将上面的类作为基类,家养鸭和野鸭作为派生类。
    但是,问题出现了,大黄鸭不会飞,可以叫。全聚德烤鸭不会飞,也不会叫。怎么办。

    方法一:使用覆盖(override),在子类中对基类的方法进行修改。即对于不会飞的鸭子,在子类中重写fly()为如下函数。quack()函数同理。

    public void fly(){  ;}
    

    不好:对于fly()还好说,但是某个动作变化比较多就会比较麻烦。比如“烹调”这个动作,光中餐里就有:煎、炒、煮、蒸、炖、烤、焗、烧。而炒里面又有爆炒、小火慢炒等等。那么每次设计一个类,都要重新写一遍代码,岂不太费事?况且还有的可以生着吃,根本不用烹调。

    方法二:采用接口形式,将方法从基类中剥离出来,放到接口中,若子类需要有某个方法,就实现对应接口即可。比如:

    interface Fly
    {
          public void fly();
    }
    class WildDuck implements Fly
    {
        public void fly()
        {
            println("I can fly");
        }
    }
    class  RoastDuck 
    {
          //其他代码,不适用Fly接口
    }
    

    不好:类比较少还行,但是类多了,而且这些类要是都实现同一个操作,那就凄惨了。比如饺子、包子、馒头、花卷都可以蒸熟,那这几个类中“烹调”操作全都要重复实现一遍“蒸”这个操作,岂不累死。

    2、策略模式
    那我们该怎么办?将方法和属性进行剥离,但还不能彻底剥离(接口就是彻底剥离),彻底剥离就体现不出面向对象的特征,面向过程编程就是数据和操作的完全剥离。那么我们该怎么办?先来看看我们需要什么:
    1)统一的接口。也就是说,所有鸭子(不管活的死的,生的熟的),都有统一的接口:fly()和quack(),因为这个是一只鸭子该有的必备技能。
    2)不同的表现形式。虽然每只鸭子"应该"有这样的技能,但是依然要“因鸭而异”。也就是说,调用不同鸭子的fly()和quack()应该执行不同的动作。
    由上面的两点,自然而然想到了“多态”。
    但是,“多态”好像只有“类的多态”,没有方法的多态。其实“多态”就是根据方法的,因为类型的不同,所以展现出不同的功能。
    所以,从上面的分析来看,我们就应该把fly()和quack()两个方法封装到类中,然后用Duck基类来调用装有fly()和quack()的类对象。为了不成为话唠,我觉得直接上代码是个不错选择。

    interface FlyBehave
    {
          public void fly();
    }
    class ReallyFly implements  FlyBehave
    {
          public void fly(){  println("I can fly");}
    }
    class CantFly implements FlyBehave
    {
          public void fly(){   println("i cant fly") ;}
    }
    
    class Duck
    {
          Color  color;
          FlyBehave flybehave;//注意此处,采用接口定义属性,为了实现多态
          
          public Duck(FlyBehave f){ flybehave = f;}
          public void fly() {  flybehave.fly();//多态调用  }
    }
    
    //测试一下
    public class Test
    {
          Duck  WildDuck=new Duck(new ReallyFly());
          WildDuck.fly();//打印显示:I can fly
    }
    

    至此,策略模式阐述完毕。总结一下特点:
    (1)基类提供统一接口
    (2)将基类的方法封装到其属性中,并用接口声明属性,实现方法的多态调用。

    相关文章

      网友评论

        本文标题:浅谈设计模式1——策略模式

        本文链接:https://www.haomeiwen.com/subject/oqtrrttx.html