java 设计模式之策略模式②①
没有人可以左右你的人生,只是很多时候我们需要多一些勇气,去坚定自己的选择。
设计模式学习,近期我会把23种设计模式都写成博客,敬请期待~
—2021/1/27
定义
是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。
项目需求
假设现在有3种鸭子
- 野鸭子(会飞,会游泳)
- 旱鸭子(会飞,不会游泳)
- 玩具鸭子(不会飞,不会游泳)
现在想在不改动原有代码的情况下改变他的状态,
比如说需要改变’飞’的状态,需要吧旱鸭子改为可以飞翔的状态.
这种情况就会吧飞定为一种策略
- 会飞
- 不会飞
然后调用对应飞的策略即可,游泳也是一样的道理,同样也可以定义两种状态
- 会游泳
- 不会游泳
角色分析
UML类图(1.1):
- 算法使用抽象(Duck)角色:算法被引用到这里和一些其它的与环境有关的操作一起 来完成任务。
- 算法具体实现(DryDuck / ToyDuck / WildDuck)角色,Duck具体实现(正常是没有这个角色的!)
- 抽象策略(Fly)角色:规定了所有具体策略角色所需的接口。在 java 它通常由接口 或者抽象类来实现。
- 具体策略(NoFly / CanFly)角色:实现了抽象策略角色定义的接口。
代码实现
Duck(鸭子抽象类):
public abstract class Duck {
//飞翔策略
Fly mFly;
//飞翔方法
public void flyMethod(){
mFly.fly();
};
//游泳
public abstract void swimming();
//改变策略
public void setmFly(Fly mFly) {
this.mFly = mFly;
}
}
将飞翔策略聚合进来~
Fly(飞翔策略抽象):
public interface Fly {
//飞翔
public void fly();
}
NoFly(飞翔策略之不会飞翔):
public class NoFly implements Fly {
@Override
public void fly() {
Log.i("策略模式","不会飞翔");
}
}
CanFly (飞翔策略之会飞翔):
public class CanFly implements Fly{
@Override
public void fly() {
Log.i("策略模式","会飞翔");
}
}
DryDuck(旱鸭子,在构造器中初始化飞翔策略具体实现):
public class DryDuck extends Duck{
public DryDuck() {
//旱鸭子不会飞
mFly = new NoFly();
}
@Override
public void swimming() {
Log.i("策略模式","旱鸭子不会游泳");
}
}
在子类的构造器中给父类的Fly赋值,达到每个类之间的策略不一样的效果
ToyDuck (玩具鸭子,在构造器中初始化飞翔策略具体实现):
public class ToyDuck extends Duck{
public ToyDuck() {
//玩具鸭子
mFly = new NoFly();
}
@Override
public void swimming() {
Log.i("策略模式","玩具鸭子不会游泳");
}
}
WildDuck (野鸭子,在构造器中初始化飞翔策略具体实现):
public class WildDuck extends Duck{
public WildDuck() {
//野鸭子会飞
mFly = new CanFly();
}
@Override
public void swimming() {
Log.i("策略模式","野鸭子会游泳");
}
}
测试代码(客户端):
// 玩具鸭
ToyDuck toyDuck = new ToyDuck();
toyDuck.flyMethod();
//野鸭子
WildDuck wildDuck = new WildDuck();
wildDuck.flyMethod();
//旱鸭子
DryDuck dryDuck = new DryDuck();
dryDuck.flyMethod();
//改变旱鸭子策略 可以飞翔
dryDuck.setmFly(new CanFly());
Log.i("策略模式","旱鸭子改变飞翔策略后 : ");
dryDuck.flyMethod();
Log图(2.1):
这是飞翔的策略,游泳的策略也是一样的!
策略模式在开发中还是非常好用的,个人觉得十分重要!
原创不易,您的点赞就是对我最大的支持~