使用模式的最好方式是:”把模式装进脑子里,然后在你的设计和已有的应用中,寻找何处可以使用它们。”
因为每一种鸭子的外观都不同,所以display()方法是抽象的。Java接口不具有实现代码,所以继承接口无法达到代码的复用。封装、抽象、继承、多态;良好的OO设计必须具备可复用、可扩充、可维护三个特性。
设计原则
找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。即变化的代码需要被抽出来,和其他稳定的代码有所区别。设计原则
针对接口编程,而不是针对实现编程。设计原则
多用组合,少用继承。
“运行时”动态地“改变”行为,这么一来有了继承复用的好处,确没有继承所带来的包袱。
整合鸭子的行为
关键在于,鸭子现在会将飞行和呱呱加的动作“委托”别人处理,而不是使用定义在Duck类内呱呱叫和飞行的方法。
- 首先,在Duck类中“加入两个实例变量”,分别为“flyBehavior”与“quackBehavior”声明为接口类型,每个鸭子对象都会动态的设置这些变量以在运行时引用正确的行为类型。
说明:行为变量被声明为行为”接口”类型;实例变量在运行时持有特定行为的引用。 - 实现performQuack()
public class Duck(){
QuackBehavior quackBehavior;
public void performQuack(){
quackBehavior.quack();
}
}
说明:每只鸭子都会引用实现QuackBehavior接口的对象;鸭子对象不亲自处理叫的行为,而是委托给quackBehavior引用的对象。
- 具体的MallardDuck类
public class MallardDuck extends Duck{
public MallardDuck(){
quakcBehavior = new Quack();
flyBehavior = new FlyWithWings();
}
public void display(){
System.out.println("I'm a real Mallard Duck");
}
}
测试Duck的代码
public abstract class Duck{
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public Duck(){
}
public abstract void display();
public void performFly(){
flyBehavior.fly();
}
public void performQuack(){
quackBehavior.quack();
}
public void swim(){
System.out.println("All ducks float,even decoys!");
}
//动态设定行为
public void setFlyBehavior(FlyBehavior fb){
flyBehavior = fb;
}
public void setQuackBehavior(QuackBehavior qb){
quackBehavior = qb;
}
}
public interface FlyBehavior{
public void fly();
}
public class FlyWithWings implements FlyBehavior{
public void fly(){
System.out.println("I'm flying!");
}
}
public class FlyNoWay implements FlyBehavior{
public void fly(){
System.out.println("I can't fly");
}
}
public interface QuackBehavior{
public void quack();
}
public class Quack implements QuackBehavior{
public void quack(){
System.out.println("Quack");
}
}
public class MuteQuack implements QuackBehavior{
public void quack(){
System.out.println("Slience");
}
}
public class Squeak implements QuackBehavior{
public void quack(){
System.out.println("Squeak");
}
}
public class Test {
public static void main(String[] args){
Duck mallard = new MallardDuck();
mallard.performQuack();
mallard.performFly();
Duck mallard1 = new MallardDuck();
mallard1.setFlyBehavior(new FlyWithWings());
mallard1.performFly();
}
}
封装行为的大局观
把鸭子的行为说成是“一组行为”,把行为想成是“一族算法”,算法代表鸭子能做的事,不同的叫法和飞行法,这样的做法也能很容易用于一群类计算不同州的销售税金。
策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
设计模式可以把你的思考架构的层次提高到模式层面,而不是停留在琐碎的对象上。
设计模式告诉我们如何组织类和对象以解决某种问题;模式不是代码,而是针对设计问题的通用解决方案。