一、策略模式的书面定义
策略模式定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户.(听起来真的很难懂.书中用的是Duck来做的例子.我自己也想了一个,帮助理解.下面来一起体会一下...)
策略模式就像是花店插花的一个过程.花店都有好多种不同组的花,(每组中的花都有差别).当客户要买一束花的时候,店员进行插花.将每组花按照一个策略插成一整束满足客户需求的产品.嗯,策略模式大概就是这个过程.下面我们把上述的过程和程序联系起来.
上述过程使用到了三类东西.并与程序对应如下
1.花篮(插花的容器). --------------> 抽象类
2.花店装每组花的桶--------------> 接口
3.每一只花. --------------> 接口实现类
那我们为什么要使用这种策略模式,生活的方式简单点不好吗?
1.代码复用性.
2.灵活可扩展.
3.动态组合实例.
书中的例子,以及代码实现:
目标,实现一个modelduck类有一个飞的方法和一个叫的方法.当我们创建这个类的时候可以根据不同的策略动态的得到一个模型鸭实例.
做法分析:
1.将飞与叫这两个行为写成两个不同接口.FlyBehavior拥有fly()和QuackBehavior拥有quack()
package com.hx.strategy;
//飞的行为
public interface IFlyBehavior {
void fly();
}
package com.hx.strategy;
//叫的行为
public interface IQuackBehavior {
void quack();
}
2.写多个实现上述两个行为接口的实现类.实现不同姿势的飞和不同的叫声.
package com.hx.strategy;
//不会飞
public class FlyNoWay implements IFlyBehavior{
@Override
public void fly() {
System.out.println("我不会飞!");
}
}
package com.hx.strategy;
//会飞
public class FlyWithWings implements IFlyBehavior{
@Override
public void fly() {
System.out.println("我正在飞!");
}
}
package com.hx.strategy;
//叫声1
public class Quack implements IQuackBehavior{
@Override
public void quack() {
System.out.println("呱呱叫!");
}
}
package com.hx.strategy;
//叫声2
public class Squeak implements IQuackBehavior{
@Override
public void quack() {
System.out.println("吱吱叫!");
}
}
3.创建抽象类,这个类就是我们的Duck类.设置上述的两个行为接口.并提供相应set方法参数为相应接口类型.以及performFly()和performQuack()方法.分别调用接口的fly()和quack()方法.
package com.hx.strategy;
public abstract class Duck {
IFlyBehavior flyBehavior;
IQuackBehavior quackBehavior;
public Duck(){
}
public abstract void display();
public void performFly(){
flyBehavior.fly();
}
public void performQuack(){
quackBehavior.quack();
}
public void setFlyBehavior(IFlyBehavior flyBehavior){
this.flyBehavior = flyBehavior;
}
public void setFlyBehavior(IQuackBehavior quackBehavior){
this.quackBehavior = quackBehavior;
}
}
4.实现modelDuck类
package com.hx.strategy;
public class ModelDuck extends Duck{
@Override
public void display() {
System.out.println("我是模型鸭!");
}
}
5.测试类;
package com.hx.strategy;
public class Test {
public static void main(String[] args) {
//动态创建具有某功能的鸭子只需要在基类增加set实例的方法就可以:
ModelDuck modelDuck = new ModelDuck();//制造一个会飞会呱呱叫的鸭子
modelDuck.setFlyBehavior(new FlyWithWings());
modelDuck.setFlyBehavior(new Quack());
modelDuck.performFly();
modelDuck.performQuack();
}
}
最后:本章书中提到了三条设计原则:
1.多用组合,少用继承
2.针对接口编程,而不是针对实现编程
3.尽可能的找到程序中会经常发生变化的代码,提取出来,将其与不需变化的代码分离.