策略设计模式
在我们进行软件设计过程中,千变万化的业务需求总是绕的人们心烦,有时会因为某个功能的修改,而是我们不得不大费周折.那么在软件设计中有没有什么方法能使我们改变这种被动的局势呢?
策略模式(Strategy Pattern)是不可否认的改变这种被动局势的有力武器.
我们首先来看看下面的例子吧.
Tom所在的公司接到一个这样的项目:做一套模拟鸭子游戏的系统.游戏中会出现各种鸭子,但这些鸭子都具备各自不同的叫唤方式,不同的飞行方式.面对如果之多不同种类的鸭子,我们该如何设计这个项目呢?
庆幸的是每种鸭子都具备飞行的能力,那么首先,定义一个飞行的接口.
/**
* 定义飞行接口
* @author Administrator
*
*/
public interface Fly {
public void fly();
}
有一种鸭子具备”展翅高飞”的飞行方式,该怎么办呢?
public class FlyImpl implements Fly{
@Override
public void fly() {
System.out.println("第一种飞行方式:展翅高飞");
}
}
但是另一种鸭子具备”直冲云霄”的飞行方式,又该怎么办呢?
public class FlyImpl2 implements Fly {
@Override
public void fly() {
System.out.println("第二种飞行方式:直冲云霄");
}
}
很好,这样做的话,不管有多少种鸭子的飞行方式,我们只需实现Fly 接口就可以了.
然后,鸭子还具有各种不同的叫声.那么和上面一样.
/**
* 定义叫声的接口
* @author Administrator
*
*/
public interface Quack {
public void quack();
}
下面,让鸭子可以有”呱呱”的叫声
public class QuackImpl implements Quack{
@Override
public void quack() {
System.out.println("第一种叫声:呱呱叫");
}
}
我们还要让他有”咕咕”的叫声.
public class QuackImpl2 implements Quack {
@Override
public void quack() {
System.out.println("第二种叫声:咕咕叫");
}
}
现在我们该组装各种不同种类的鸭子了:
/**
* 组装鸭子
* @author Administrator
*
*/
public class Duck {
private Fly fly;
private Quack quack;
public Fly getFly() {
return fly;
}
public void setFly(Fly fly) {
this.fly = fly;
}
public Quack getQuack() {
return quack;
}
public void setQuack(Quack quack) {
this.quack = quack;
}
public void duck(){
fly.fly();
quack.quack();
}
public static void main(String[] args) {
//组装成一个会”展翅高飞”又有”咕咕”叫声的鸭子
Fly f = new FlyImpl();
Quack q = new QuackImpl2();
Duck d = new Duck();
d.setFly(f);
d.setQuack(q);
d.duck();
//组装成一个会”直冲云霄”又有”呱呱”叫声的鸭子
Fly f = new FlyImpl();
Quack q = new QuackImpl2();
Duck d = new Duck();
d.setFly(f);
d.setQuack(q);
d.duck();
}
}
这样,我们可以很轻松的组装成各种不同种类的鸭子了.
现在我们来总结下,什么是策略模式。
定义:定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
那么设计这种模式我们应该遵守哪些设计原则呢?
1) 找出应用之中可能变化的地方,把它们独立出来,不要和那些不需要变化的代码混在一起。
2) 针对接口编程,而不是针对实现编程。
3) 多用组合,少用继承。