生活所迫呀。
上一期中,我们通过接口(interface)和抽象类(abstract class)理解了如何定义行为规范、如何实现多态等等。然而,在传统的继承方式中,子类通过覆盖方法来改变行为,但这种方式在面对行为切换、行为复用时显得僵硬。因此,我们希望有一种方式,不用继承,也能改变对象的行为,更适合“插件式”的行为结构。
这个时候,就需要一种新的模式委托,把行为交给另一个对象来完成。
首先,我们需要先定义一个接口,来规范要干的事情
1 | public interface FlyBehavior{ |
实现接口的类必须要实现fly这一个动作,我们定义一个实现FlyBehavior接口的类FlyWithWings,来实现有翅膀可以飞的动作:
1 | public class FlyWithWings implements FlyBehavior{ |
我们再定义一个实现FlyBehavior接口的类FlyNoWings,来实现没翅膀不能飞的动作:
1 | public class FlyNoWings implements FlyBehavior{ |
定义玩接口和接口的实现之后,我们定义了两个飞行动作,现在,我们来定义实现飞行动作的对象。
我们定义一个鸭子抽象类:
1 | public abstract class Duck{ |
这里首先声明了一个FlyBehavior类型的引用变量,表示鸭子的飞行行为,当调用performFly()时,实际上调用的是flyBehavior对象的fly()方法。
好的,那么我们可以新建一个子类了:
1 | public class MallardDuck extends Duck{ |
在 MallardDuck 构造函数里,给继承自父类的 flyBehavior 变量赋值为 new FlyWithWings() 实例。这样调用 performFly() 就会调用 FlyWithWings 类的 fly() 方法,实现“飞”的动作。
入口:
1 | public class RunDuck { |
输出: cannot fly!!!
但是,这样还是不够灵活,我们还想要让鸭子具有动态行为。为了实现这个目的,我们只需要在抽象类中加入一个设定方法:
1 | public abstract class Duck{ |
随后,在实现时:
1 | public class RunDuck { |
即可动态设定其行为,输出为:
cannot fly!!!
fly!!!
这种通过组合行为接口的方式实现动态切换行为的设计模式,称为策略模式(Strategy Pattern),是面向对象设计中的重要思想。