软件开发的一个不变真理

不变的就是变化

驱动改变的因素很多.找出你的应用中需要改变代码的原因

  1. 用户需要新的功能
  2. 需要推出新的活动
  3. 应用改版
  4. 为了更好的性能

继承不能很好的解决问题,因为对象的行为在子类里不断地改变,并且让所有子类都有这些行为是不恰当的. 使用Fooable等接口,只用能实现的类才继承Fooable接口,但是java接口不具有实现代码,所以继承接口无法达到代码的复用.

引出一个设计原则

找出应用中可能需要变化之处,把它独立出来,不要和那些不需要变化的代码混在一起

设计原则

针对接口编程,而不是针对实现编程

假设有很多鸭子,有真鸭,模型鸭,如何实现他们的行为呢?

先定义个一个抽象的Duck类

/**
 * 鸭子的抽象类
 */publicabstractclassDuck{
private String _headColor="yellow";//Duck对象必备的属性public Stringget_headColor() {
return _headColor;
    }

publicvoidset_headColor(String _headColor) {
this._headColor = _headColor;
    }

public IFlyBehavior flyBehavior;//为行为接口类型声明引用变量,所有鸭子子类都继承他们public IFlyBehaviorgetFlyBehavior() {
return flyBehavior;
    }

publicvoidsetFlyBehavior(IFlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
    }

public IQuackBehaviorgetQuackBehavior() {
return quackBehavior;
    }

publicvoidsetQuackBehavior(IQuackBehavior quackBehavior) {
this.quackBehavior = quackBehavior;
    }

public IQuackBehavior quackBehavior;//同上publicDuck(){

    }

publicvoidperformQuack(){
        quackBehavior.quack();//委托给行为类
    }

publicvoidperformFly(){
        flyBehavior.fly();//委托给行为类
    }

publicabstractvoiddisplay();

/**
     * Duck必备的行为
     */publicvoidswim(){
        System.out.println("All ducks float,even decoys!");
    }

}

绿头鸭继承Duck

/**
 * 绿头鸭类
 */publicclassMallardDuckextendsDuck {
publicMallardDuck(){
        quackBehavior=new Quack();//绿头鸭使用Quack类处理叫,所以当performQuack()被调用时,叫的职责被委托给Quack
        flyBehavior=new FlyWithWings();//同理
    }

publicvoiddisplay(){
        System.out.println("I'm a real Mallard duck");
    }
}

模型鸭

/*
* 模型鸭
*/publicclassModelDuckextendsDuck {
publicModelDuck(){
        flyBehavior=new FlyNoWay();//一开始,模型鸭不会飞
        quackBehavior=new Quack();//一开始,模型鸭会呱呱叫
    }
    @Override
publicvoiddisplay() {

    }
}

鸭子的鸣叫行为接口类

/**
 * 叫行为接口类
 */publicinterfaceIQuackBehavior{
publicvoidquack();
}

鸭子的飞行行为接口类

/**
 * 飞行行为接口类
 */publicinterfaceIFlyBehavior{
publicvoidfly();
}

各种实现了飞行行为的实现类

/**
 * 这是飞行行为的实现,给真会飞的鸭子用
 */publicclassFlyWithWingsimplementsIFlyBehavior {
    @Override
publicvoidfly() {
        System.out.println("fly with wings");
    }
}

/**
 * 火箭动力的飞行行为
 */publicclassFlyWithRocketimplementsIFlyBehavior {
    @Override
publicvoidfly() {
        System.out.println("I'm flying with a rocket!");
    }
}

/**
 * 这是飞行行为的实现,给不会飞的鸭子用
 */publicclassFlyNoWayimplementsIFlyBehavior {
    @Override
publicvoidfly() {
        System.out.println("I can't fly!");
    }
}

各种实现了鸣叫行为的实现类

/**
 * 叫的实现,给会呱呱叫的鸭子用
 */publicclassQuackimplementsIQuackBehavior {
    @Override
publicvoidquack() {
        System.out.println("Quack,gua gua gua!");
    }
}

/**
 * 鸭子叫的沉默实现,给不会叫的鸭子用
 */publicclassQuackMuteimplementsIQuackBehavior {
    @Override
publicvoidquack() {
        System.out.println("<<Silence>>");
    }
}

测试我们的鸭子们

publicclassTest {
publicstatic void main(String args[]){
        MallardDuck mallardDuck=new MallardDuck();
        mallardDuck.display();
        mallardDuck.performFly();
        mallardDuck.performQuack();

//搞一只模型鸭
        ModelDuck md=new ModelDuck();
        md.performFly();//第一次调用飞行时,委托给FlyNoWay
        md.setFlyBehavior(new FlyWithRocket());//继承来的设置飞行模式的方法,给予火箭动力
        md.performFly();//现在能飞啦~

    }
}

//输出
Bobble gobble
I'm flying a short distance
gua!gua!gua!
I'm flying a long distance
Bobble gobble
I'm flying a short distance
I'm flying a short distance
I'm flying a short distance
I'm flying a short distance
I'm flying a short distance

项目地址

java设计模式实现 如果觉得有点收获,记得在项目上点star哦!