前言
策略模式的主要是定义算法族,分别封装起来,让它们之间可以互相替换,使算法的变化独立于使用算法的客户。它属于行为模式中的一种,我们可以通过一个项目对它进行了解。鸭子项目
一、多种类型鸭子
1.类:鸭子Duck2.行为:飞fly、叫quack,但是每一种鸭子的行为不同。
二、两种方案
1.利用继承提供Duck行为这种方式存在一些问题: 代码在多个子类中重复、运行时行为不易改变、难知道鸭子的全部行为、改变会牵一发动全身,造成其他鸭子不想要的改变。
2.利用接口设计Duck行为
通过设计FlyBehavior、QuackBehavior接口,将鸭子会飞行和呱呱叫的动作“委托”(delegate)给别人处理,而不是定义在Duck类(或子类)内。
三、代码实现
1.封装变化Duck类中的fly/quack会随着鸭子的不同而改变。将这两个行为抽取出来,建立一组新类代表每个行为。
飞行为的接口
public interface Flybehavior {
void fly();
}
2.针对接口编程
不针对实现编程,将鸭子的行为放在分开的类中,此类专门提供某行为接口的实现,鸭子类不需要知道行为的实现细节。
具体行为类
// 不会飞的类
public class FlyNoWay implements Flybehavior {
@Override
public void fly() {
System.out.println("I can't fly!!");
}
}
// 会飞的类
public class FlyWithWings implements Flybehavior {
@Override
public void fly() {
System.out.println("I'm flying!!");
}
}
3.多用组合
少用继承,鸭子的行为不是继承来的,而是和适当的行为对象组合来的。
public abstract class Duck {
// 行为接口的引用,具体实现动态生成
public Flybehavior flybehavior;
public Duck(){}
public abstract void display();
public void performFly(){
flybehavior.fly();
}
public void setFlybehavior(Flybehavior flybehavior){
this.flybehavior=flybehavior;
}
}
// 具体的鸭子类
public class MallardDuck extends Duck {
// 构造方法中,动态实现一种行为类
public MallardDuck(){
flybehavior=new FlyWithWings();
}
@Override
public void display() {
System.out.println("I'm a real Mallard duck");
}
}
// 测试类
public class MainTest {
public static void main(String[] args){
// 鸭子子类
Duck mallard=new MallardDuck();
mallard.performFly();
// 灵活更改鸭子飞的行为
mallard.setFlybehavior(new FlyNoWay());
mallard.performFly();
mallard.display();
}
}
spring 中的策略模式
1.图中展示Spring中Bean的实例化过程,其中涉及到接口InstantiationStrategy,用来实例化策略接口类,它定义了三个实例化接口。 2.SimpleInstantiationStrategy实现了该策略,它主要做一些简单的根据构造函数实例bean的工作,然后CglibSubclassingInstantiationStrategy又继承了SimpleInstantiationStrategy新增了方法注入方式。3.根据cglib生成代理类实例化方法。在AbstractAutowireCapableBeanFactory中管理了该策略的一个对象,默认是CglibSubclassingInstantiationStrategy策略,运行时候可以通过setInstantiationStrategy改变实例化策略。