标签:
设计原则
找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
设计原则
针对接口编程,而不是针对实现编程。
问:用一个类代表一个行为,感觉似乎有点奇怪。
类不是应该代表某种“东西”吗?类不是应该同时具备
状态“与”行为吗?
答:在OO系统中,是的,类代表的东西一般都
是既有状态(实例变量)又有方法。只是在本例中,碰
巧“东西”是个行为。但是即使是行为,也仍然可以有
状态和方法,例如,飞行的行为可以具有实例变量,记
录飞行行为的属性(每秒翅膀拍动几下、最大高度和速
度等)。
问:Duck是不是也该设计成一个接口?
答:在本例中,这么做并不恰当。如你所见的,
我们已经让一切都整合妥当,而且让Duck成为一个具
体类,这样可以让衍生的特定类(例如绿头鸭)具有
Duck共同的属性和方法。我们已经 从Duck的继承结构中
删除了变化的部分,原先的问题都已经解决了,所以不
需要把Duck设计成接口。
测试Duck的代码
1,输入并编译下面的Duck类(Duck.java)以及两页前的
MallardDuck类(MallardDuck.java)。
public abstract class Duck { FlyBehavior flyBehavior;//为行为接口类型声明两个引 QuackBehavior quackBehavior;//用变量,所有鸭子子类(在同一个zackage中)都继承它们 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!”); } }
2,输入并编译FlyBehavior接口(FlyBehavior.java)与两个行为实现
类(FlyWithWings.java与FlyNoWay.java)。
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”);//这 是 飞 行 行 为 的 实 现 ,给“不会”飞的鸭子用(包括橡皮鸭和诱饵鸭)。 } }
3.输入并编译QuackBehavior接口(QuackBehavior.java)及其三个实现类
(Quack.java、MuteQuack.java、Squeak.java)。
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(“<< Silence >>”); } } public class Squeak implements QuackBehavior { public void quack() { System.out.println(“Squeak”); } }
4,输入并编译测试类(MiniDuckSimulator.java)
public class MiniDuckSimulator { public static void main(String[] args) { Duck mallard = new MallardDuck(); mallard.performQuack();//这会调用MallardDuck继承来的performQuack() 方法,进而委托给该对象的QuackBehavior对象处理(也就是说,调用继承来的quackBehavior引用对象的quack())。 mallard.performFly(); } }
动态设定行为
在鸭子里建立了一堆动态的功能没有用到,就太可惜了!假设我们想在鸭子子类中通
过“设定方法(setter method)”来设定鸭子的行为,而不是在鸭子的构造器内实例化。
1,在Duck类中,加入两个新方法:
public void setFlyBehavior(FlyBehavior fb) { flyBehavior = fb; } public void setQuackBehavior(QuackBehavior qb) { quackBehavior = qb; }
2,制造一个新的鸭子类型:模型鸭(ModelDuck.java)
public class ModelDuck extends Duck { public ModelDuck() { flyBehavior = new FlyNoWay();//一开始,我们的模型鸭是不会飞的。 quackBehavior = new Quack(); } public void display() { System.out.println(“I’m a model duck”); } }
3,建立一个新的FlyBehavior 类型(FlyRocketPowered.java)
public class FlyRocketPowered implements FlyBehavior { public void fly() { System.out.println(“I’m flying with a rocket!”); //没关系,我们建立一个利用火箭动力的飞行行为。 } }
4,改变测试类(MiniDuckSimulator.java),加上模型鸭,并使模型鸭具有火箭动力。
public class MiniDuckSimulator { public static void main(String[] args) { Duck mallard = new MallardDuck(); mallard.performQuack(); mallard.performFly(); Duck model = new ModelDuck(); model.performFly();//第一次调用performFly() 会被委托给flyBehavior对象(也就是FlyNoWay实例),该对象是在模型鸭构造器中设置的。 model.setFlyBehavior(new FlyRocketPowered());//这会调用继承来的setter方法,把火箭动力飞行的行为设定到模型鸭中。哇!模型鸭突然具有了火箭动力飞行能力! model.performFly(); //如果成功了,就意味着模型鸭可以动态地改变它的飞行行为。如果把行为的实现绑死在鸭子类中,可就无法做到这样了。 } }
二,观察者(Observer)模式
标签:
原文地址:http://www.cnblogs.com/FH-cnblogs/p/4306747.html