前言:
最近在看<head first 设计模式>,第一章学习的是策略模式,这里记录一下看书的过程。写一下笔记,画个uml图加深印象。也喜欢对学习设计模式的读者有点帮助。
策略模式的概念:
定义了算法族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的用户。
举个例子理解:
此例子来源于《head firsrt 设计模式》。
设计一个模拟鸭子的应用。鸭子的主要动作有叫和飞,不同的具体鸭子类别会有不同的实现形式。并且会不定时的加新的鸭子类。
这里直接一步到位贴上我刚学会画的uml图(发现错误可以指出来噢)
一个duck夫类、两个具体鸭子的子类、两个行为接口、4个行为的具体实现类。
Duck类
public abstract class Duck {
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public Duck(){
}
public void setFlyBehavior(FlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
}
public void setQuackBehavior(QuackBehavior quackBehavior) {
this.quackBehavior = quackBehavior;
}
public abstract void display();
public void performFly(){
flyBehavior.fly();
}
public void performQuack(){
quackBehavior.quack();
}
public void swim(){
System.out.println("All ducks float,even decoys");
}
}
duck类设计成一个抽象类,需要子类实现display方法。注意两个set方法、以及两个perform方法 后面会有大作用。
行为接口interface
public interface FlyBehavior {
void fly();
}
public interface QuackBehavior {
void quack();
}
具体行为的实现类:
实现各自行为接口。
public class FlyWithWings implements FlyBehavior {
@Override
public void fly() {
System.out.println("I'm flying");
}
}
public class FlyNoWay implements FlyBehavior {
@Override
public void fly() {
System.out.println("I can't fly");
}
}
public class Squeak implements QuackBehavior {
@Override
public void quack() {
System.out.println("Squeak");
}
}
public class Quack implements QuackBehavior {
@Override
public void quack() {
System.out.println("Quack");
}
}
具体duck的实现类
public class MallardDuck extends Duck {
public MallardDuck(){
quackBehavior=new Quack();
flyBehavior=new FlyWithWings();
}
@Override
public void display() {
System.out.println("I'm a real Mallard duck");
}
}
public class ModelDuck extends Duck {
public ModelDuck(){
flyBehavior=new FlyNoWay();//初始化不会飞
quackBehavior=new Quack();
}
@Override
public void display() {
System.out.println("I'm a model duck!");
}
两个具体鸭子的代码。主要重写了display方法,并在构造函数的组合了需要的行为实现类。
调用代码:
public class MiniDuckSimulator {
//设计原则:针对接口编程,而不是针对实现编程
//设计原则:多用组合,少用继承
public static void main(String[] args) {
// demo-1
Duck mallard = new MallardDuck();
mallard.performQuack();
mallard.performFly();
// demo-2
Duck model = new ModelDuck();
model.performFly();
model.setFlyBehavior(new FlyRocketPowered());
model.performFly();
}
}
理解例子:
由于经常需要新增具体鸭子类,而且每种鸭子都可能会有不同的行为,所以啊就定一个鸭子的超类,并且成员变量有着两个行为接口,一个是负责叫,一个负责飞。让每个具体的鸭子都实现它。因为行为是有很多变数的。把行为具体抽取出来,实现的行为接口,来表示各种行为方式例如flynoway表示不能飞,flyrocketpowered表示骑着火箭飞行。。。。
最终使用的时候呢只需要初始化具体的鸭子类,然后调用set***behavior方法来动态绑定具体的行为方法即可。最后调用perform***把 行为动作的实现委托给内置的动作类。这样就可以完美的实现了代码复用,以及以后更新新的鸭子可以无需重写太多的代码。
总结:
上面说过策略模式就是定义了算法族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的用户。
其实具体的实现方式就是通过把行为(算法)抽取出来定义一个成接口,并把行为接口组合到类中,这样如果需要定义新的行为(算法),只需要实现行为接口,然后在调用set行为的方法来动态改变行为即可。
简而言之呢就是将变化的部分抽离出来,组合进类中,根据不同的子类,可以“set”不同的行为子类进行,实现动态改变行为