应用到鸭子类,我们知道duck类内的fly和quack方法会随着鸭子的不同而改变,因此将飞行和呱呱叫行为抽离出来,切每一组类将实现各自的动作 。
文章插图
将和抽离出来也体现出了针对接口编程,而非针对实现编程的原则 。之前我们是由具体的鸭子子类来实现相应的行为,被实现绑的死死的,无法更改行为,现在我们可以依赖于行为接口的实现子类,将相应行为指定给鸭子子类,从而可以更改行为,而不在与实现绑死了 。
比如说Flyable可以有两个相应的实现interface FlyBehavior{void fly();}class FlyWithWings implements FlyBehavior{void fly(){//实现鸭子的飞行动作 。}}class FlyNoWay implements FlyBehavior{void fly(){//什么都不做 。}}//QuackBehavior有三个实现interface QuackBehavior{void quack();}class Quack implements QuackBehavior{void quack(){//嘎嘎叫}}class Squeak implements QuackBehavior{void quack(){//吱吱叫}}class MuteQuack implements QuackBehavior{void quack(){//不叫}}通过这样设计,就可以让呱呱叫的动作 和飞行的动作被其他对象服用了,这些行为已经和鸭子类无关了
现在我们将鸭子基类中加入两个实例变量 。
public abstract class Duck {FlyBehavior flyBehavior;QuackBehavior quackBehavior;abstract public void swim();abstract public void performQuack();abstract public void display();abstract public void performFly();}现在在鸭子的实现类里我们想让鸭子拥有什么样的行为,我们就直接委托给鸭子子类class MallardDuck extends Duck{public MallardDuck (){quackBehavior = new Quack();flyBehavior = new FlyWithWings();}//将该鸭子相对应的行为委托给该鸭子子类public MallardDuck (QuackBehavior quackBehavior,FlyBehavior flyBehavior ){this.quackBehavior = quackBehavior ;this.flyBehavior = flyBehavior ;}public void setFlyBehavior(FlyBehaviorflyBehavior ){this.flyBehavior = flyBehavior ;}public void setQuackBehavior(QuackBehavior quackBehavior){this.quackBehavior = quackBehavior ;}void performQuack(){quackBehavior.quack(); 表现出委托的叫行为的叫声}void performFly(){flyBehavior .fly(); 表现出委托的飞行行为的飞行方法}}
上面的方法是不是就可以解决我们的问题了,再举个例子,比如说我们现在想生产一种飞起来利用火箭动力飞行的模型鸭子 。
class ModelDuck extends Duck{public ModelDuck (){quackBehavior = new Quack();flyBehavior = new FlyNoWay();//一开始我们的模型鸭是不会飞的}//将该鸭子相对应的行为委托给该鸭子子类public ModelDuck (QuackBehavior quackBehavior,FlyBehavior flyBehavior ){this.quackBehavior = quackBehavior ;this.flyBehavior = flyBehavior ;}public void setFlyBehavior(FlyBehaviorflyBehavior ){this.flyBehavior = flyBehavior ;}public void setQuackBehavior(QuackBehavior quackBehavior){this.quackBehavior = quackBehavior ;}void performQuack(){quackBehavior.quack(); 表现出委托的叫行为的叫声}void performFly(){flyBehavior .fly(); 表现出委托的飞行行为的飞行方法}}//定义一种利用火箭飞行行为public class FlyRocketPowered implements FlyBehavior{public void fly(){System.out.println("I'm flying with a rocket");}}现在让我们新建一直模型鸭Duck modelDuck = new ModelDuck();modelDuck.performFly();modelDuck.setFlyBehavior(new FlyRocketPowered ());modelDuck.performFly();执行结果:模型鸭不会飞I'm flying with a rocket"
【HeadFirst设计模式之策略模式】以上的这些就是策略模式了,在本例中是将飞行行为和叫声行为抽离出来,来进行众多实现 。在以组合的方式来实现多种行为的替换,这样就能在运行时更改鸭子的飞行和叫声行式,不再将鸭子子类和飞行叫声绑死,实现灵活替换,这些行为的实现子类就可以看成是算法蔟 。今天的分享就到这里啦 。
- 7 CTF之旅WEB篇--[NPUCTF2020]ReadlezPHP
- java 设计模式之2策略模式
- S32K144调用空指令NOP
- Java多线程之原子操作类
- 《从点子到产品》读书笔记之产品价值和用户痛点
- 二 Elasticsearch 基础之安装
- 【CSDN博客之星】专访陈勇: 敏捷开发现状及发展之路
- LwIP 之二 网络接口 netif(netif.c、ethernetif
- 设计模式考点
- 阿里云镜像仓库 【Docker】Docker之镜像上传