本博文参考自《Head First 设计模式》
这里并不是讲设计模式一些高深概念的,不喜勿喷!!!!!!
策略模式的定义: 策略模式定义了算法族,分别封装起来,让它们独立于使用算法的客户
下面用一个实例来进行说明:
类的结构图:
复制代码:
Duck类:这个类是所有鸭子子类的父类。
package com.wnl.classes;
import com.wnl.interfaces.FlyBehavior;
import com.wnl.interfaces.QuackBehavior;
/**
*
* 设计原则:
*
* 1:分开变化和不变化部分,把变化部分封装起来
* 2:针对接口编程,而不会针对实现编程
* 3:多用组合,少用继承
*
* 策略模式:
* 策略模式定义了算法族,分别封装起来,让它们独立于使用算法的客户
*
* @author Administrator
*
* 学习心得:
*
* 在策略模式中,把变化的业务和不变化的分开,独自封装变化的部分,然后交由具体的子类去实现。
* 在本例,鸭子有不同的种类,不同的行为,不同种类的鸭子对于同一行为的实现又是不一样。所以,为
* 了提高程序的维护性和代码的复用性,我们把行为(变化的)和Duck父类分开,在Duck父类中提供一
* 个实现接口方法的方法(performQuack()、performFly() )方便子类调用。由于具体行为的类实现统一的行为接
* 口,所以子类可以动态调用父类实现接口方法的方法来实现行为。
* 综合的来说,就是子类需要是实现的方法,在父类中不直接实现,委托其它的类来实现。
*
*/
public abstract class Duck {
public QuackBehavior quackBehavior;
public FlyBehavior flyBehavior;
public void performQuack() {
quackBehavior.quack();
};
public void performFly() {
flyBehavior.fly();
}
/**
* 设置改变叫的方法,子类可以动态改变叫的行为
* @param qb QuackBehavior对象
*/
public void setQuackBehavior(QuackBehavior qb){
quackBehavior=qb;
}
/**
* 设置改变飞行的方法,子类可以动态改变飞行的行为
* @param qb FlyBehavior对象
*/
public void setFlyBehavior(FlyBehavior fb){
flyBehavior=fb;
}
/**
* 鸭子的外观
*/
public abstract void display();
public void swim(){
System.out.println("All ducks float, and decoys");
}
}
实现“飞”的行为的接口
把“飞”的动作从Duck类中抽取出来,定义一个”飞”的动作的接口,而具体“飞”的变现,例如“不会飞”,“会飞”、“飞的很慢”等等,由“飞”的动作的不同子类(实现了统一的“飞”的接口)来实现。这样,以后想添加一个具体的“飞”的行为的时候,就可以不用修改Duck类,实现了低耦合。
package com.wnl.interfaces;
public interface FlyBehavior {
public void fly();
}
实现“叫”的行为的接口
把“叫”的动作从Duck类中抽取出来,定义一个”叫”的动作的接口,而具体“叫”的变现,例如“不会叫”,“会叫”、“飞的很大声”等等,由“叫”的动作的不同子类(实现了统一的“叫”的接口)来实现。这样,以后想添加一个具体的“叫”的行为的时候,就可以不用修改Duck类,实现了低耦合。
package com.wnl.interfaces;
public interface QuackBehavior {
public void quack();
}
具体“叫”的行为
package com.wnl.utils;
import com.wnl.interfaces.QuackBehavior;
public class Quack implements QuackBehavior {
@Override
public void quack() {
System.out.println("Quack");
}
}
package com.wnl.utils;
import com.wnl.interfaces.QuackBehavior;
public class MuteQuack implements QuackBehavior {
@Override
public void quack() {
System.out.println("<< Slience >>");
}
}
具体“飞”的行为
package com.wnl.utils;
import com.wnl.interfaces.FlyBehavior;
public class FlyWithWings implements FlyBehavior {
@Override
public void fly() {
System.out.println("I am flying");
}
}
package com.wnl.utils;
import com.wnl.interfaces.FlyBehavior;
public class FlyRocketPower implements FlyBehavior {
@Override
public void fly() {
System.out.println("I am flying with a rocket");
}
}
package com.wnl.utils;
import com.wnl.interfaces.FlyBehavior;
public class FlyNoway implements FlyBehavior {
@Override
public void fly() {
System.out.println("I can not fly");
}
}
具体的鸭子子类
package com.wnl.classes;
import com.wnl.utils.FlyWithWings;
import com.wnl.utils.Quack;
public class MallarDuck extends Duck {
public MallarDuck(){//利用多态向上转型,实例化具体行为
quackBehavior=new Quack();
flyBehavior=new FlyWithWings();
}
@Override
public void display() {
System.out.println("I am a reallyMallarDuck");
}
}
package com.wnl.classes;
import com.wnl.utils.FlyNoway;
import com.wnl.utils.Quack;
public class ModelDuck extends Duck {
public ModelDuck(){//利用多态向上转型,实例化具体行为
quackBehavior=new Quack();
flyBehavior=new FlyNoway();
}
@Override
public void display() {
System.out.println("I am a model duck");
}
}
package com.wnl.classes;
public class ReaheadDuck extends Duck {
@Override
public void display() {
System.out.println("MallarDuck的外观是红头");
}
}
测试类:
package com.test;
import com.wnl.classes.Duck;
import com.wnl.classes.MallarDuck;
import com.wnl.classes.ModelDuck;
import com.wnl.utils.FlyRocketPower;
public class TestDuck {
public static void main(String[] args) {
System.out.println("======MallarDuck======");
Duck mallard = new MallarDuck();
mallard.performQuack();
mallard.performFly();
System.out.println("======ModelDuck======");
Duck model = new ModelDuck();
model.performFly();
model.setFlyBehavior(new FlyRocketPower());
model.performFly();
}
}
输出
至此,所有代码已经完成。从整体上讲,就是抽取变化的部分出来独自封装,这样需求改变的时候,只需要修改抽取出来的代码,父类不会受到影响。整个策略模式可以认为是:抽象出不变的部分,对于需要改变的地方提供一个统一的接口,具体的实现由这个接口的子类去实现。