策略模式将程序的不变部分保留,可变部分单独拿出,然后封装起来,让今后此功能的扩展和修改更加方便。
此策略强调使用组合而非继承。
案例:
我们想模拟两种鸭子: 普通鸭, 橡胶鸭
我们知道这三种鸭子不可变的是都会游泳(swim),可变的是:能否飞(fly) 和 能否叫(quack)
第一步:我们将可变部分拿出,分别封装为两个接口:flyBehavior 和 quackBehavior
public interface FlyBehavior {
public void fly();
}
----------------------------------分割线----------------------------------------------
public interface QuackBehavior {
public void quack();
}
----------------------------------分割线----------------------------------------------
第二步:
飞行行为(flyBehavior)分为会飞(FlyWithWings)与不会飞(FlyNoWay)
所以我们应该新创建两个新class继承接口flyBehavior:
public class FlyWithWings implements FlyBehavior {
public void fly(){
System.out.println("我会飞");
}
}
----------------------------------分割线----------------------------------------------
public class FlyNoWay implements FlyBehavior {
public void fly(){
System.out.println("我不会飞");
}
}
第三步:
同理鸣叫行为(QuackBehavior)分为会叫(Quack)与不会叫(MuteQuack):
public class Quack implements QuackBehavior{
@Override
public void quack() {
System.out.println("我会叫");
}
}
----------------------------------分割线----------------------------------------------
public class MuteQuack implements QuackBehavior{
@Override
public void quack() {
System.out.println("我不会叫");
}
}
第四步:
建立鸭子父类Duck, 加入两个实例变量 flyBehavior 和 quackBehavior(也就是第一步创建的两个接口)以及两个实例变量的配套方法performFly(), performQuack(),setFlyBehavior,setQuackBehavior。
还有两个不变方法 display() 和 swim()
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;
}
}
第五步:
创建两个class 橡胶鸭(RubberDuck) 和 普通鸭(ModelDuck), 分别继承第四步创建的Duck
public class RubberDuck extends Duck {
public RubberDuck(){
//橡胶鸭不会飞
flyBehavior = new FlyNoWay();
//橡胶鸭会叫
quackBehavior = new Quack();
}
@Override
public void display() {
System.out.println("我是橡胶鸭");
}
}
----------------------------------分割线----------------------------------------------
public class ModelDuck extends Duck{
public ModelDuck(){
//普通鸭会飞
flyBehavior = new FlyWithWings();
//普通鸭会叫
quackBehavior = new Quack();
}
@Override
public void display() {
System.out.println("我是普通鸭");
}
}
第六步:
大功告成!喝口水庆祝一下
第七步 :测试
创建一个class 用于测试
public class MiniDuckSimulator {
public static void main(String[] args) {
Duck rubber = new RubberDuck();
rubber.display();
rubber.performFly();
rubber.performQuack();
System.out.println("-------------------------------------------");
Duck model = new ModelDuck();
model.display();
model.performFly();
//飞行状态改为不会飞
model.setFlyBehavior(new FlyNoWay());
model.performFly();
}
结果:
我是橡胶鸭
我不会飞
我会叫
-------------------------------------------
我是普通鸭
我会飞
我不会飞
第八步:
加入新功能火箭飞行(RocketPoweredFly)
创建新类RocketPoweredFly, 继承接口 FlyBehavior
public class RocketPoweredFly implements FlyBehavior{
@Override
public void fly() {
System.out.println("我可以火箭推动");
}
}
测试:
public class MiniDuckSimulator {
public static void main(String[] args) {
Duck model = new ModelDuck();
model.display();
model.performFly();
//飞行状态改为火箭飞行
model.setFlyBehavior(new RocketPoweredFly());
model.performFly();
}
}
结果:
我是普通鸭
我会飞
我可以火箭推动
本文通过鸭子行为模拟案例,深入解析策略模式的实现原理。策略模式将可变行为封装为独立的策略,使得程序结构更清晰,易于扩展和维护。
&spm=1001.2101.3001.5002&articleId=107294059&d=1&t=3&u=758ea30b195c4cb5bafe98969a70fb9f)

被折叠的 条评论
为什么被折叠?



