23种java设计模式之策略模式

在讲策略模式之前我们先讲一个小案例

小明的上司叫小明写一个关于鸭子的项目,对于鸭子,可能有绿头鸭,白头鸭,然后鸭子会飞,会叫,让小明去写,小明心想,这不很简单吗,写一个鸭子超类,然后对于不同的鸭子去继承超类,然后就很快写出了代码。

超类Duck类:

public abstract class Duck {
String name;
public void setName(String name) {
this.name = name;
}
//飞
public abstract void fly();

//叫
public abstract void voice();

public void swim(){
System.out.println(name+"正在游泳!!");
}
}

写一个绿头鸭(GreenHeadDuck)继承Duck,GreenHeadDuck类:

public class GreenHeadDuck extends Duck {
public void fly() {
super.name="GreekHeadDuck";
System.out.println(name+"正在快速飞行");
}


public void voice() {
super.name="GreekHeadDuck";
System.out.println(name+"在嘎嘎叫!!");
}
}

写一个白头鸭(WhiteHeadDuck)继承Duck,WhiteHeadDuck类:

public class WhiteHeadDuck extends Duck {
public void fly() {
super.name="WhiteHeadDuck";
System.out.println(name+"正在快速飞行");
}

public void voice() {
super.name="WhiteHeadDuck";
System.out.println(name+"在嘎嘎叫!!");
}
}

最后执行Test类:

public class Test {
public static void main(String[] args) {
Duck duck=new GreenHeadDuck();
Duck duck1=new WhiteHeadDuck();
duck.fly();
duck.voice();
duck.swim();
duck1.fly();
duck1.voice();
duck1.swim();
}
}

显然,小明这么写没毛病,不过过了几天,上司又发话了,让小明给鸭子添加一个会说话鸭子,小明心想,直接在超类里写个talk方法,然后让后面的子类直接继承,如果不能说话的鸭子就重写个方法覆盖。这样想也没毛病,但是如果鸭子的种类有十几种,上百种的时候,你还得每一个子类去覆盖,想想都可怕,这就相当于超类挖个坑,每个子类都要来填,增加工作量,复杂度为O(2^N),不是好的设计方式。最后小明利用了策略模式来解决这个问题,在父类中,就说飞行,可能有好的飞行啊,漂亮的飞行,各种不同的飞行,对飞行行为写一个接口FlyBehavior 类:

public interface FlyBehavior {
void fly();
}

实现FlyBehavior类的GoodFlyBehavior类:

public class GoodFlyBehavior implements FlyBehavior {
public void fly() {
System.out.println("在完美的飞行");
}
}

然后在超类里面定义:

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


在WhiteHeadDuck类里面实例白头鸭的具体飞行

public WhiteHeadDuck(){
flyBehavior=new GoodFlyBehavior();
}

最后再Test里面调用,这样就可以方便的添加功能。

总结:

策略模式:分别封装行为接口,实现算法族,超类里放行为接口对象,在子类里具体设定行为对象。原则就是:分离变化部分,封装接口,基于接口封装各种功能,此模式让算法的变化独立于算法的使用者。

策略模式的注意点:
1、分析项目中变化部分和不变部分
2、多用组合少用继承;用行为类组合,而不是行为的继承,更有弹性。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值