设计模式之策略者模式

鸭子的父类,所有鸭子都继承自该类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public abstract class Duck {
public FlyBehavior flyBehavior;
public QuackBehavior quackBehavior;
public Duck(){
}
public abstract void display();
/**
* 飞行行为接口
*/
public void performFly(){
flyBehavior.fly();
}
/**
* 叫行为接口
*/
public void performQuack(){
quackBehavior.quack();
}
/**
* 公共方法
*/
public void swim(){
System.out.println("所有鸭子都在水上浮着游泳,即使是诱饵鸭也是");
}
/**
* 动态设置飞行行为
* @param fb
*/
public void setFlyBehavior(FlyBehavior fb){
flyBehavior = fb;
}
/**
*动态设置叫的行为
* @param qb
*/
public void setQuackBehavior(QuackBehavior qb){
quackBehavior = qb;
}
}

行为类接口

1
2
3
4
5
6
7
8
9
10
11
12
public interface FlyBehavior {
/**
* 飞行行为,所有实现该接口都必须重写该方法
*/
public void fly();
}
public interface QuackBehavior {
/**
* 叫行为,所有实现该接口都必须重写该方法
*/
public void quack();
}

具体行为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class FlyNoWay implements FlyBehavior {
@Override
public void fly() {
System.out.println("我不会飞,很尴尬");
}
}
public class FlyRocketPowered implements FlyBehavior {
@Override
public void fly() {
System.out.println("坐着火箭的鸭子,你怕不怕?");
}
}
public class FlyWithWings implements FlyBehavior {
@Override
public void fly() {
System.out.println("我会飞,I'm fly");
}
}
public class MuteQuack implements QuackBehavior {
@Override
public void quack() {
System.out.println("silence 我很安静,不会叫");
}
}
public class Quack implements QuackBehavior {
@Override
public void quack() {
System.out.println("我是会叫的鸭子");
}
}
public class Squeak implements QuackBehavior {
@Override
public void quack() {
System.out.println("我的叫声很尖,可以刺痛你的耳朵");
}
}

模型鸭和绿头鸭

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class ModeDuck extends Duck {
/**
* 初始化构造方法,
* quackBehavior和flyBehavior对象都继承自父类Duck
*/
public ModeDuck(){
flyBehavior = new FlyNoWay();//初始化一个不会飞的鸭子
quackBehavior = new Quack();//初始化会叫
}
@Override
public void display() {
System.out.println("我是一个模型鸭子");
}
}
public class MallardDuck extends Duck {
/**
* 初始化构造方法,
* quackBehavior和flyBehavior对象都继承自父类Duck
*/
public MallardDuck(){
quackBehavior = new Quack();//绿头鸭使用Quack类处理呱呱叫所以当 performQuack被调用时叫的职责被委托给Quack对象,而我们得到了真正的呱呱叫
flyBehavior = new FlyWithWings();//使用FlyWithWings作为其FlyBehavior的类型
}
@Override
public void display() {
System.out.println("我是真的绿头鸭");
}
}

测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Test {
public static void main(String[] args) {
Duck mallard = new MallardDuck();
mallard.performFly();
mallard.performQuack();
mallard.setQuackBehavior(new MuteQuack());
mallard.performQuack();
mallard.display();
Duck model = new ModeDuck();
model.performFly();
model.setFlyBehavior(new FlyRocketPowered());
model.performFly();
}
}

输出

我会飞,I’m fly
我是会叫的鸭子
silence 我很安静,不会叫
我是真的绿头鸭

我不会飞,很尴尬
坐着火箭的鸭子,你怕不怕?

UML

image

可应用场景

  1. 多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。
  2. 需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。
  3. 对客户隐藏具体策略(算法)的实现细节,彼此完全独立。

总结

如果想要新增加一个鸭子就新建一个鸭子类继承Duck类,实现鸭子的行为,如果想要添加鸭子的行为,可直接在Duck类里添加,所有的鸭子都继承自该类,可以动态设置鸭子的飞行和叫的行为。