一、总纲:定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的的变化独立于使用算法的客户
二、需求:将下列程序用策略模式加上飞的功能,要求程序要有弹性
public abstract class Duck {
//鸭子都会叫,提取到基类中
public void quack(){System.out.println("鸭子叫。。");}
//鸭子都会游泳,提取到基类中
public void swim(){System.out.println("鸭子游泳。。");}
//因为每种鸭子的外观不同,所以display是抽象的,给具体实现类实现
public abstract void display();
}
三、想要程序有弹性,便于维护,则至少需要遵循以下三个设计原则
(1)设计原则:找出程序中可能需要改变的部分,将他们独立出来,不和哪些稳定的代码混在一起
(2)设计原则:针对接口(超类)编程,而不是针对实现编程
(3)设计原则:多用组合,少用继承
四、重构之后的思路:将原来Duck中的两组行为类取出来,形成不同的类,彻底与Duck解耦,
新建行为类接口,各自的行为分别实现各自的接口,将接口的引用放入Duck或者其他的任意类,
因为此时行为与其他类没有任何关系。再通过硬编码或者配置文件,Dcuk中接口的引用实例化即可。
用到多态:方法的动态绑定可以让类知道调用他的类型。
五、下面为实现代码
行为类接口及实现类1、
/**
* 飞行类接口:所有飞行的类都实现这个接口
* @author xiaohan
*
*/
public interface FlyBehavior {
void fly();
}
public class FlyNoWings implements FlyBehavior {
@Override
public void fly() {
System.out.println("不会飞");
}
}
public class FlyWithWings implements FlyBehavior {
@Override
public void fly() {
System.out.println("实现飞行");
}
}
行为类接口及实现类2、
/**
* 所有叫的行为都实现这个接口
* @author xiaohan
*
*/
public interface QuackBehavior {
void quack();
}
public class Squeak implements QuackBehavior {
@Override
public void quack() {
System.out.println("橡皮鸭子吱吱叫");
}
}
public class MuteQuack implements QuackBehavior {
@Override
public void quack() {
System.out.println("啥也不会,也不会叫");
}
}
改造之后的基类Duck3、
/*
* 鸭子的超类,包括两个行为类的接口,用来承接不同的实例
*/
public abstract class Duck {
//因为每种鸭子的外观不同,所以display是抽象的,给具体实现类实现
public abstract void display();
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public void performQuack(){
//鸭子对象不亲自处理,而是委托给quackB的对象,我们不需要关心接口对象是什么
//只要对象会呱呱叫就行了
quackBehavior.quack();
}
public void performFly(){
//鸭子对象不亲自处理,而是委托给实现flyB的对象,我们不需要关心接口对象是什么
//只要对象会呱呱叫就行了
flyBehavior.fly();
}
}
这时候如果我们想要一个不会飞也不会叫的模型鸭,就可以这样做
/**
* 模型鸭:继承Duck接口
* @author xiaohan
*
*/
public class ModelDuck extends Duck{
//暂时这样实例化,后面会优化,根据不同的需求实例化不同的类
public ModelDuck(){
quackBehavior = new Quack();
flyBehavior = new FlyNoWings();
}
@Override
public void display() {
System.out.println("模型鸭");
}
}
测试程序5、
/**
* 鸭子模拟器测试
* @author xiaohan
*
*/
public class Test {
public static void main(String[] args) {
Duck modelDuck = new ModelDuck();
modelDuck.display();
modelDuck.performFly();
modelDuck.performQuack();
}
}
到这里基本上实现了鸭子的不同行为类,通过组合的方式,但是如果要动态的改变鸭子的行为,还需要Duck增加一个方法
//这样就可以随时调用这两个方法来改变鸭子的行为
public void setFlyBehavior(FlyBehavior fb){
flyBehavior = fb;
}
public void setQuackBehavior(QuackBehavior qb){
quackBehavior = qb;
}
第二个测试程序
public class Test {
public static void main(String[] args) {
Duck modelDuck = new ModelDuck();
modelDuck.display();
modelDuck.performFly();
modelDuck.setFlyBehavior(new FlyRocketPowered());
modelDuck.performFly();
}
}
策略模式到这几基本结束,上面的程序主要是用来加深理解用的,设计模式不是说只要背会定义就可以的,还是要加深理解。
最后我会贴出一个很简单的示例的连接,对照着看,个人感觉会起到事半功倍的效果。
我是小菜鸟,若有失误,敬请指出,共同前进!!!