zoukankan      html  css  js  c++  java
  • 设计模式第一集——策略模式

      《Head First——设计模式》真是一本太太太好的书了!!!之前一看设计模式就头疼,这本书浅显易懂越看越想看。

      首先,设计模式第一集——策略模式:定义算法族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。

      定义不好理解,举一个例子。

      假如现在要做一个模拟鸭子游戏,里面有各类鸭子。游戏中有各类鸭子,一边游泳(swim)一边嘎嘎叫(quack)。现在需要对原有的游戏代码进行改进,要求:

      1.在新增的游戏中,有些鸭子会飞;

      2.鸭子嘎嘎叫的方式有很多不同,比如有的吱吱叫;

      3.有一种模型鸭,可以动态的改变自己飞行行为(比如具备火箭动力飞行能力)

      针对上面的需求,很容易想到的是设计一个抽象的Duck类,该类里有swim、quack、fly等方法,其它类型的鸭子继承Duck类。这就是我完全不知道设计模式的时候想到的方法,这样设计有很多问题!比如:把fly的方法写到基类中,所有的类型鸭子继承之后都有了fly的能力,但是有些鸭子是不能飞的,就需要把这些鸭子的fly方法覆盖掉,n多个不能飞的鸭子就要覆盖n此,重复代码太多。同理,要求鸭子的嘎嘎叫法也不同,像之前的设计对于很多种鸭子都要重写它们的quack方法。

      那要怎么做?

      原则一:封装变化

      quack和fly的特性是不同鸭子有不同的方式,把他们从Duck的基类中拿出来,单独封装起来,建立一个新类来代表每一行为。这样对quack和fly方法的改变不会影响到其它部分。

      那怎么实现多种fly方式和quack方式呢?

      原则二:针对接口编程,而不针对实现编程

      这个很容易,分别写一个FlyBehavior和QuackBehavior的接口。具体想怎么飞怎么叫,在具体实现中去编吧。在Duck的基类中把之前写死的fly()和quack()方法去掉,改变成委托给FlyBehavior的引用

      public class FlyWithWings implments FlyBehavior{

            public void fly(){

                 System.out.println("用翅膀飞!");

             }

        }

        public abstract class Duck{

           FlyBehavior flyBehavior;

       QuackBehavior quackBehavior;

           public void swim(){……}

           public void performFly(){ flyBehavior.fly();}//委托给飞的行为类实现飞的动作

           public void performQuack(){quackBehavior.quack();}

       }

        最后一个需求很简单,我们要动态的改变鸭子的行为,那在Duck中对鸭子的个个行为设立set()方法,当想让这个鸭子有哪种行为时,set一下就可以了。

      在最后还要提到一个原则三:多用组合,少用继承.FlyBehavior和QuackBehavior从之前的超类中拿出来,以组合的方式完成动作。

      鸭子游戏UML图:

      抽象的Duck类:

     1 package com.duck;
     2 
     3 public abstract class Duck {
     4     FlyBehavior flyBehavior;
     5     QuackBehavior quackBehavior;
     6     
     7     public abstract void display();
     8     
     9     //将飞、呱呱叫的行为委托给行为类
    10     public void performfly(){
    11         flyBehavior.fly();
    12     }
    13     public void performQuack(){
    14         quackBehavior.quack();
    15     }
    16     public void quackBehavior(){
    17         quackBehavior.quack();
    18     }
    19     
    20     public void swim(){
    21         System.out.println("I am swimming");
    22     }
    23     //动态设定行为
    24     public void setFlyBehavior(FlyBehavior fb){
    25         flyBehavior=fb;
    26     }
    27     public void setQuackBehavior(QuackBehavior qb){
    28         quackBehavior=qb;
    29     }
    30 }

      FlyBehavior接口:

     1 package com.duck;
     2 
     3 public interface FlyBehavior {
     4     public void fly();
     5 }
     6 
     7 package com.duck;
     8 
     9 public class FlyNoWay implements FlyBehavior{
    10     public void fly() {
    11     }
    12 
    13 }
    14 
    15 package com.duck;
    16 
    17 public class FlyWithWings implements FlyBehavior{
    18 
    19     @Override
    20     public void fly() {
    21         System.out.println("I am flying");
    22     }
    23 }

    QuackBehavior:

     1 package com.duck;
     2 
     3 public interface QuackBehavior {
     4     public void quack();
     5 }
     6 
     7 package com.duck;
     8 
     9 public class Quack implements QuackBehavior{
    10 
    11     public void quack() {
    12         System.out.println("Quack");
    13     }
    14 
    15 }
    16 
    17 package com.duck;
    18 
    19 public class Squeak implements QuackBehavior{
    20 
    21     public void quack() {
    22         System.out.println("Squeak");
    23         
    24     }
    25 
    26 }

     要实现一个具体的绿头鸭:

    现在嘎嘎叫的行为和飞的行为都是单独的类,这样对以后新增的鸭子可以直接组合想要的行为。将需要新的嘎嘎叫和飞行为的时候,写新的类实现实现。若有其他新的行为产生是,再写新的接口用和新的类具体实现。这样在代码维护的时候不用反复修改代码。

     1 package com.duck;
     2 
     3 public class MallardDuck extends Duck{
     4     
     5     public MallardDuck() {
     6         //绿头鸭的特点是可以呱呱叫和飞行
     7         //因为MallardDuck 继承自 Duck所以它具有quackBehavior和flybehavior实例变量
     8         quackBehavior=new Quack();//呱呱叫
     9         flyBehavior=new FlyWithWings();//
    10     }
    11 
    12     @Override
    13     public void display() {
    14         System.out.println("I am a real Mallard duck");
    15     }
    16 }
  • 相关阅读:
    bzoj1415 NOI2005聪聪和可可
    Tyvj1952 Easy
    poj2096 Collecting Bugs
    COGS 1489玩纸牌
    COGS1487 麻球繁衍
    cf 261B.Maxim and Restaurant
    cf 223B.Two Strings
    cf 609E.Minimum spanning tree for each edge
    cf 187B.AlgoRace
    cf 760B.Frodo and pillows
  • 原文地址:https://www.cnblogs.com/doublesong/p/2613608.html
Copyright © 2011-2022 走看看