设计模式(一):设计模式入门

举个例子:现在要设计一个程序模拟各种鸭子,包括玩具鸭和真鸭子。 每个鸭子都具有呱呱叫 quack() 和 飞行 fly() 方法。 我们首先想到的设计方法是

举个例子:现在要设计一个程序模拟各种鸭子,包括玩具鸭和真鸭子。

每个鸭子都具有呱呱叫 quack() 和 飞行 fly() 方法。

我们首先想到的设计方法是 定义一个超类duck,超类实现fly()、quack()方法。然后定义各种鸭子子类去继承超类duck。

但是这样导致的问题是有的鸭子只会quack或fly,而且叫声和飞行方式也分很多种,如果继承两个方法每次都要重写显然不方便,会增加代码长度。

所以,引出设计原则一找出应用中可能需要变化之处,把他们独立出来,不要和那些不需要变化的混合在一起。     设计原则二:针对接口编程,而不是针对实现编程写程序时应该尽可能增加代码的弹性,如果如例子中那样设计,一旦鸭子需要增加新技能,我们都必须到原来的代码中去修改,这种属于静态定义行为,即在代码编写时就决定了对象的行为,这不是我们想要的好的设计。

我们需要的是在程序运行时能够动态改变行为

设计原则三:多用组合,少用继承

于是,我们把fly和quack单独拿出来定义成接口FlyBehavior和QuackBehavior。

1 public interface FlyBehavior {
2     public void fly();
3 }
1 public interface QuackBehavior {
2     public void quack();
3 }

接着在定义quack类和fly类实现接口

public class MuteQuack implements QuackBehavior{
    @Override
    public void quack() {        
        System.out.println("<< Silence >>");    
    }
}


public class Quack implements QuackBehavior{
    @Override
    public void quack() {
        System.out.println("quack!");
    }
}



public class Squeak implements QuackBehavior{
    @Override
    public void quack() {
        System.out.println("squeak!");
    }
}
public class FlyNoWay implements FlyBehavior{
    @Override
    public void fly() {
        System.out.println("i can not fly!");
    }
}



public class FlyWithWings implements FlyBehavior{
    @Override
    public void fly() {
        System.out.println("i am flying!");
    }    
}

然后再定义超类Duck

 1 public abstract class Duck {
 2     public FlyBehavior flybehavior;
 3     public QuackBehavior quackbehavior;
 4     
 5     public abstract void display();
 6     
 7     public void performFly(){
 8         flybehavior.fly();
 9     }
10      
11     public void performQuack(){
12         quackbehavior.quack();
13     }
14     
15     public void swim(){
16         System.out.println("all ducks can swim!");
17     }
18     
19     public void setFlyBehavior(FlyBehavior fb){
20         flybehavior = fb;
21     }
22     
23     public void setQuackBehavior(QuackBehavior qb){
24         quackbehavior = qb;
25     }
26 }

在超类中实例化引用两个行为接口

 

接着定义鸭子具体类继承自超类Duck

 1 public class MallardDuck extends Duck{
 2     public MallardDuck() {
 3         flybehavior = new FlyWithWings();
 4         quackbehavior = new Quack();
 5     }
 6     @Override
 7     public void display() {
 8         // TODO Auto-generated method stub
 9         System.out.println("i am a mallardDuck!");
10     }
11 }

在具体类构造方法中我们将超类的行为引用定义为new FlyWithWings(),new Quack()

实现类

public class test {
    public static void main(String[] args) {
        Duck d = new MallardDuck();
        d.performFly();
        d.performQuack();
        d.display();
    }
}

这样就可以动态的修改鸭子的行为,用setFlyBehavior(FlyBehavior fb)和setQuackBehavior(QuackBehavior qb).