定义算法族,将他们封装其起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户
2.什么情况下使用策略模式?
实现某一个功能有多条途径,每一条途径对应一种算法
将算法的定义与使用分开,也就是将算法的行为和环境分开
3.设计原则
a.找出应用中可能的变化之处,将他们独立出来,和不需要变化的代码分开
b.多用组合,少用继承
c.针对接口编程,不针对实现编程
4.代码情景
模拟鸭子游戏设计:游戏中会出现各种各样的鸭子,他们会游泳,会叫
设计思路:所有鸭子都具有游泳和叫的功能,因此可以设计一个超类,实现这两个方法,然后让不同的鸭子继承该超类,也可以设计一个显示方法,
由于不同的鸭子外观不一样,因此我们可以在超类中设计抽象的显示方法,让不同的子类去实现。
新需求:使鸭子可以飞起来
设计思路:在超类中加上fly()方法,让所有子类去继承,鸭子就可以飞起来了
出现的问题:按上面描述的方式编码之后,鸭子是可以飞起来了,但是橡皮类型的鸭子也开始起飞了,这不合乎逻辑
解决问题:可以让橡皮鸭继承的时候将fly()方法覆盖掉
思考:不同类型的鸭子叫声,飞行方式都不同,假如又出现新类型的鸭子,有需要覆盖哪些方法,显然使用继承的方式大大降低了代码的扩展性,
那么如果将飞和叫全部改为接口,不同类型的鸭子根据需求去实现这几个接口,貌似这样可以解决扩展性问题,但很快我们便会发现,代码的复用性很差,
产生大量的垃圾代码。
显然使用以上的方式是不可取的,需要重构代码。
新方案:将超类中的叫和飞方法从超类中分离出来,设为两个接口并且让特定的类去实现他们,不同类型的鸭子继承超类后调用相应的类的
飞和叫的方法。具体看代码
//飞行为的接口
public interface FlyBehavior {
public void fly();
}//叫行为的接口
public interface QuackBehavior {
public void quack();
}//鸭子的超类
public abstract class Duck {
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public Duck() {
}
//将飞的行为委任给接口,具体调用什么样的实现由具体实现决定,此处为多态
public void performFly() {
flyBehavior.fly();
}
//将叫的行为委任给接口,具体调用什么样的实现由具体实现决定,此处为多态
public void performQuack() {
quackBehavior.quack();
}
}//会飞的鸭子的具体实现类
public class CanFly implements FlyBehavior {
@Override
public void fly() {
System.out.println("我可以飞");
}
}//呱呱叫的鸭子的具体实现类
public class GagaDuack implements QuackBehavior {
@Override
public void quack() {
System.out.println("呱呱呱");
}
}//不会飞类型鸭子的具体实现类
public class Nofly implements FlyBehavior {
@Override
public void fly() {
System.out.println("我不会飞");
}
}//不会叫的鸭子
public class SilenceQuack implements QuackBehavior {
@Override
public void quack() {
System.out.println(".........");
}
}//吱吱叫的鸭子的具体实现类
public class ZhizhiQuack implements QuackBehavior {
@Override
public void quack() {
System.out.println("吱吱吱");
}
}//模型鸭子
public class ModelDuck extends Duck {
public ModelDuck() {
flyBehavior = new Nofly();
quackBehavior = new SilenceQuack();
}
}public class TestApp {
public static void main(String[] args) {
Duck d = new ModelDuck();
d.performFly();
d.performQuack();
}
}原文:http://blog.51cto.com/12222886/2046742