策略模式

策略模式定义一系列算法,分别封装起来,让他们之间可以相互转换,策略模式可以让算法的变化独立于使用算法的客户。

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
public abstract class Duck {
private FlyBehavior flyBehavior;
private QuackBehavior quackBehavior;
public Duck() {
this.flyBehavior=new FlyBehaviorDefualtImpl();
this.quackBehavior=new QuackBehaviorDefaultImpl();
}
public void performFly(){
this.flyBehavior.fly();
}
public void performQuack(){
this.quackBehavior.quack();
}
public void swim(){
log.info("All ducks float, event decoys");
}
abstract void display();
public void setFlyBehavior(FlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
}
public void setQuackBehavior(QuackBehavior quackBehavior) {
this.quackBehavior = quackBehavior;
}
}

定义了一个抽象的鸭子基类,它有最基本的四个方法,执行飞的行为方法performFly(),执行叫的行为方法performQuack(),还有游泳和显示方法。
不同的鸭子子类显示行为不同,所以这里设置成abstract的。所有的鸭子都可以游泳。这里直接定义好一个具体的方法swim,但是鸭子的飞和叫方法,不同的
子类是不同、,虽然这里也可以将这两个方法设计成抽象的方法,由具体的子类去实现,但是当鸭子的子类非常多的时候,各自都需要重新实现飞和叫的方法。这里
为了复用而使用继承,并不完美。因为你很难知道以后这个抽象基类会新增什么其他的抽象方法,那样所有的具体子类都需要实现这个抽象方法。运行时的行为也不容易改变,
这里可以使用策略模式将变化的部分单独封装起来,好让其他部分不受影响,这里有一个设计原则

找出应用中可能需要变化的地方,把他们独立出来,不要和那些不需要变化的代码混在一起。

可以将鸭子的行为单独的放在分开的类中,此类专门提供某行为接口实现,这样鸭子类就不再需要知道行为的实现细节。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public interface FlyBehavior {
void fly();
}
public class FlyBehaviorDefualtImpl implements FlyBehavior {
@Override
public void fly() {
log.info("I'am flying !");
}
}
public class FlyNoWayBehaviorImpl implements FlyBehavior {
@Override
public void fly() {
log.info("I canot fly!");
}
}

这样设计的好处是可以动态的改变鸭子的行为,只需要set不同的behavior实现就行了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static void main(String[] args) {
Duck duck=new MallardDuck();
log.info("默认行为>>>>>>>.");
duck.display();
duck.performFly();
duck.performQuack();
log.info("动态改变行为>>>>>>>.");
duck.setFlyBehavior(new FlyNoWayBehaviorImpl());
duck.setQuackBehavior(new MuteQuackBehaviorImpl());
duck.display();
duck.performFly();
duck.performQuack();
}