Java 设计模式之策略模式(Strategy Pattern)

本文通过鸭子行为模拟案例,深入解析策略模式的实现原理。策略模式将可变行为封装为独立的策略,使得程序结构更清晰,易于扩展和维护。

策略模式将程序的不变部分保留,可变部分单独拿出,然后封装起来,让今后此功能的扩展和修改更加方便。

此策略强调使用组合而非继承。

 

案例:

我们想模拟两种鸭子: 普通鸭, 橡胶鸭

我们知道这三种鸭子不可变的是都会游泳(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();

    }
}

结果:

我是普通鸭
我会飞
我可以火箭推动

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值