设计模块——策略模式

策略模式是一种行为设计模式,它使你能在运行时改变对象的行为。通过将算法族分离出来,实现了代码的解耦,使得在不修改原有类结构的情况下,能够动态切换不同的算法实现。在动物类的示例中,通过引入FlyBehavior和SwimBehavior接口,解决了动物行为扩展的问题,避免了对所有子类的修改,提高了代码的可维护性和可扩展性。
摘要由CSDN通过智能技术生成

策略模式是什么?

策略模式定义了算法簇,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

策略模式解决什么问题?

如下继承结构中,父类Animal的两个通用方法会被子类(Dog、Duck)继承:

public class Animal{
    public void quack(){
        System.out.println("会叫");
    }

    public void run(){
        System.out.println("会跑");
    }

}

class Dog extends Animal{

}

class Duck extends Animal{

}

如果此时修改需求,需要让Animal会飞和会游泳

解决办法1

在Animal中添加fly()和swim()方法

public class Animal{
   public void quack(){
       System.out.println("会叫");
   }

   public void run(){
       System.out.println("会跑");
   }
   public void fly(){
       System.out.println("会飞");
   }
   public void swim(){
       System.out.println("会游泳");
   }
}

class Dog extends Animal{
   @Override
   public void fly() {

   }
   @Override
   public void swim(){
   }
}

class Duck extends Animal{

}
  • Problem1:所有子类都会拥有这两个方法(包括不会飞和不会游泳的动物)
  • Solution1:让不会飞的动物覆盖fly()方法并置空,不会游泳也同理
  • Problem2:每当有新的动物(如Cat)继承Animal都要检查fly()和swim()方法
  • Progrem3:哪天Dog学会游泳了,得重新修改Dog类源码中的swim()方法

解决办法2

新建flyable和swimable接口,让会飞和会游泳的动物去实现

public class Animal {
    public void quack() {
        System.out.println("会叫");
    }

    public void run() {
        System.out.println("会跑");
    }

}

interface flyable {
    void fly();
}

interface swimmable {
    void swim();
}

class Dog extends Animal {

}

class Duck extends Animal implements flyable, swimmable {

    @Override
    public void fly() {
        System.out.println("会飞");
    }

    @Override
    public void swim() {
        System.out.println("会游泳");
    }
}
  • Progrem1:每当有新的动物(如Cat)都需要考虑实现flyable和swimmable
  • Progrem2:代码变多且实现接口并没有代码复用
  • Progrem3:哪天Dog学会游泳了,得修改Dog类源码实现swimmable并重写swim()方法

策略模式实现

定义算法簇

将不会变化的代码(quark、run)和会变化的代码(fly、swim)拆开,定义FlyBehavior和SwimBehavior接口,让其子类实现会飞/不会飞、会游泳/不会游泳:

interface FlyBehavior{
    void fly();
}
class CanFly implements FlyBehavior{

    @Override
    public void fly() {
        System.out.println("会飞");
    }
}
class NoFly implements FlyBehavior{

    @Override
    public void fly() {
        System.out.println("不会飞");
    }
}

interface SwimBehavior{
    void Swim();
}
class CanSwim implements SwimBehavior{

    @Override
    public void Swim() {
        System.out.println("会游泳");
    }
}
class NoSwim implements SwimBehavior{

    @Override
    public void Swim() {
        System.out.println("不会游泳");
    }
}

采用组合代替继承

Animal内部维护FlyBehavior和SwimBehavior父类实例,暴露公用set方法:

public class Animal {
    private FlyBehavior flyBehavior;
    private SwimBehavior swimBehavior;

    public void quack() {
        System.out.println("会叫");
    }

    public void run() {
        System.out.println("会跑");
    }

    public void performFly(){
        flyBehavior.fly();
    }

    public void performSwim(){
        swimBehavior.Swim();
    }
    public void setFlyBehavior(FlyBehavior flyBehavior) {
        this.flyBehavior = flyBehavior;
    }

    public void setSwimBehavior(SwimBehavior swimBehavior) {
        this.swimBehavior = swimBehavior;
    }
}

针对多态编程

让Dog和Duck在初始化时,使用FlyBehavior和SwimBehavior的子类指定其行为:

class Dog extends Animal {
    public Dog() {
        setFlyBehavior(new NoFly());
        setSwimBehavior(new NoSwim());
    }
}

class Duck extends Animal {
    public Duck() {
        setFlyBehavior(new CanFly());
        setSwimBehavior(new CanSwim());
    }
}

运行时绑定

调用Dog的performSwim()方法时,因为构造函数内设置的是NoSwim()暂时还不会游泳:

Animal dog=new Dog();
dog.performSwim();

当Dog学会游泳时,可在不修改类源码的情况下重新指定其行为:

Animal dog=new Dog();
dog.setFlyBehavior(new CanSwim());
dog.performSwim();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值