策略模式

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

例子来自于《Head First 设计模式》:

产品经理要求我们设计一个鸭子的系统,鸭子的行为有fly和swim,我们肯定会想到设计一个父类Duck,在父类写fly和swim两个方法。其他鸭子比如RedDuck和GreenDuck都继承父类,重写重载或者直接引用父类的方法。这个都很好实现。代码如下:

Duck:

public class Duck {
    public void fly(){
        System.out.println("飞");
    };
    public void swim(){
        System.out.println("游泳");
    }
}
GreenDuck:
public class GreenDuck extends Duck {
}
RedDuck:
public class RedDuck extends Duck {
}

之后几天,产品经理让你写了很多鸭子,YelloDuck,BlackDuck......。这些需求很简单,我们只要创建其他鸭子类,继承Duck父类就可以了。突然有一天,产品经理要求你加入一个橡皮鸭,这时候,我们发现橡皮鸭会swim,但是不会fly,所以我们的设计不对。这时候,有人会想,直接把方法设计成接口,谁要用谁去实现接口。例如:

public interface Fly {
    void fly();
}
public class GreenDuck extends Duck implements Flay{
    @Override
    public void fly() {
        
    }
}

可能目前是满足需求的,突然又有一天,产品经理要求你设计一个铁皮鸭子,此时这个鸭子即不会fly,又不会swim,难道我们又要把swim写成接口。肯定是不可能的,这样需要改的代码太多了,可见我们现在的代码结构非常不灵活。

这个时候就要用到组合。

首先我们把代码会变化的地方独立出来,不要和那些不需要变化的代码混在一起。我们就发现鸭子的很多行为是可能会发生变化的,我们就把行为独立出来,写成一个接口。例如,我们写一个FlyBehavior接口,接口有fly()方法。写一个flyWithWings类和NoFly类实现FlyBehavior接口。而Duck类中的不再需要fly方法,只需要创建一个FlyBehavior的属性,并set封装。其他鸭子子类继续继承Duck父类就可以了。代码如下:

FlyBehavior:

public interface FlyBehavior {
    void fly();
}

FlyWithWings:

public class FlyWithWings implements FlyBehavior{
    @Override
    public void fly() {
        System.out.println("我会用翅膀飞");
    }
}
NoFly:
public class NoFly implements FlyBehavior{
    @Override
    public void fly() {
        System.out.println("我不会飞");
    }
}
Duck:
public class Duck {
    private FlyBehavior flyBehavior;
    
    public void setFlyBehavior(FlyBehavior flyBehavior) {
        this.flyBehavior = flyBehavior;
    }

    public void performFly(){
        flyBehavior.fly();
    }
}
GreenDuck:
public class GreenDuck extends Duck{

}
测试类Main:
public class Main {
    public static void main(String[] args) {
        Duck greenDuck = new GreenDuck();
        greenDuck.setFlyBehavior(new FlyWithWings());
        greenDuck.performFly();
        System.out.println("你的翅膀受到了永久性伤害不能飞了");
        greenDuck.setFlyBehavior(new NoFly());
        greenDuck.performFly();
    }
}

使用这种模式,可以在创建行为的时候决定是什么行为,并且也可以互换行为,这就显得非常灵活。

urm图如下:

FlyBehavior和实现它的类FlyWithWings,NoFly可以理解为一个算法族,FlyWithWings和NoFly就是算法,并且可以互换。这里就体现了组合的一大特点,不用硬编程,在编译的时候就写死类对象类型。我们可以在运行的时候,按需求创建指定的对象。这也就是多态。

我们再简单说另外一个例子:我们设计一个游戏,游戏有王(King)、皇后(Queen)、巨魔(Troller)、骑士(Knight)四个角色,每个用的初始武器不一样,例如:匕首(Knife)、弓箭(BowAndArrow)、斧头(Axe)、宝剑(Sword)。并且会切换武器。用策略模式的话就这么设计:


将使用武器设计成一个算法族,可以自由切换里面的算法。








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值