1、第一个设计原则:找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。该原则几乎是所有设计模式背后的精神所在。
这个原则的另一种思考方式:把会变化的部分取出并封装起来,以便以后可以轻易改动或扩充此部分,二不影响不需要变化的其他部分。
2、第二个设计原则:针对接口编程,而不是针对实现编程。
3、第三个设计原则:多用组合,少用继承
4、策略模式(Strategy Pattern):模拟鸭子
策略模式:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
Duck(鸭子抽象类,组合了 FlyBehavior 和 QuackBehavior)
public abstract class Duck { // 关系 has a protected FlyBehavior flyBehavior;// 封装飞行行为 protected QuackBehavior quackBehavior;// 封装呱呱叫行为 public void performFly() { flyBehavior.fly(); } public void performQuack() { quackBehavior.quack(); } // 动态设定行为 public void setFlyBehavior(FlyBehavior flyBehavior) { this.flyBehavior = flyBehavior; } public void setQuackBehavior(QuackBehavior quackBehavior) { this.quackBehavior = quackBehavior; } public void swim() { System.out.println("所有的鸭子都会游泳"); } public abstract void display(); }
飞行行为(算法)
public interface FlyBehavior { void fly(); } public class FlyWithWings implements FlyBehavior { @Override public void fly() { System.out.println("哈哈。我有翅膀,我会飞。。。"); } } public class FlyNoWay implements FlyBehavior { @Override public void fly() { System.out.println("什么都不做,不会飞"); } }
呱呱叫行为(算法)
public interface QuackBehavior { void quack(); } public class Quack implements QuackBehavior { @Override public void quack() { System.out.println("呱呱叫"); } } public class Squeak implements QuackBehavior { @Override public void quack() { System.out.println("吱吱叫"); } } public class MuteQuack implements QuackBehavior { @Override public void quack() { System.out.println("什么都不做,不会叫"); } }
MallardDuck(一种具体的鸭子类,初始化了 flyBehavior 和 quackBehavior)
public class MallardDuck extends Duck { public MallardDuck() { this.flyBehavior = new FlyWithWings(); this.quackBehavior = new Quack(); } @Override public void display() { System.out.println("MallardDuck display"); } }
测试:
public class Demo02 { public static void main(String[] args) { Duck duck = new MallardDuck(); duck.performFly(); duck.performQuack(); duck.swim(); duck.display();
System.out.println("=========动态改变行为========="); duck.setFlyBehavior(new FlyNoWay()); duck.setQuackBehavior(new MuteQuack()); duck.performFly(); duck.performQuack(); } }
打印结果:
哈哈。我有翅膀,我会飞。。。 呱呱叫 所有的鸭子都会游泳 MallardDuck display =========动态改变行为========= 什么都不做,不会飞 什么都不做,不会叫
5、总结
1)"有一个"关系:每一个鸭子都有一个 FlyBehavior 和 QuackBehavior,好将飞行和呱呱叫委托给它们代为处理。
当你将两个类结合起来使用,就是组合(Composition)。这种做法与“继承”不同的在于,鸭子的行为不是继承来的,而是和适当 行为对象"组合"来的。
2)软件开发完成"前"以及完成"后",何者花费更多时间?
"后"。我们总需要花许多时间在系统的维护和变化上,比原先开发所花的时间更多。所以,我们应该致力于提高软件的可维护性和可扩展性。