Head First-策略模式解读

一、概括:


策略模式无论是在大话设计模式中还是在Head First中都是作为前面出现的设计模式,可见它还是相对比较简单的。

策略是行为型的,也就是说它的侧重点在方法上。


二、谈谈认识:


现在通过模拟鸭子的实例,谈谈策略。


第一层:单纯继承


首先,各种鸭子,一边游泳,一边呱呱叫。我们很容易的从中取出类:鸭子;方法:游泳、叫、外观。所以,我们画出来是酱紫的:


代码实现:

/**
 * @author qmx
 * @version 1.0
 * @created 21-九月-2014 15:44:32
 */
public abstract class Duck {

	public Duck(){

	}

	public void display(){

	}

	public void fly(){

	}

	public void queck(){

	}

	public void swim(){

	}

}

子类:(只写一个)


/**
 * @author qmx
 * @version 1.0
 * @created 21-九月-2014 15:44:32
 */
public class MallardDuck extends Duck {

	/**
	 * 外观是绿头
	 */
	public void display(){

	}

}


第二层:加入接口


当然,到这一步我们是不满意的,每一个子类都与父类不同,那就会产生很多的代码。比如我加了一个橡皮鸭,不会飞,却继承了父类中的fly方法。比如加入了一个诱饵鸭,它不会飞也不会叫。为了解决这个问题,我们引入了接口。



光看这个图就挺乱的,我们要记得,接口定义了fly这个方法,但是并没有实现它。MallarDuck和RedheadDuck他们两个fly实现是相同的,这个时候,非要让他们重写接口中的fly方法,这不是又生成了大量的重复代码吗?


因此我们进行进一步整合,通过对父类的引用指向子类对象的方式。


第三层:策略模式



其中要注意的点:

1、各种fly方法继承接口FlyBehavior,封装起来。这样可以达到代码的复用

2、Duck抽象类中添加成员变量为FlyBehavior flyBeHavior。(如果一个类是另一个类中的成员变量,则这两个类的关系是聚合关系)。这样可以抽象类就可以将fly动作委托给FlyBehavior类了。

3、Duck中setFlyBehavior中的局部参数就是FlyBehavior。这样就实现了动态调用,setFlyBehavior中参数得到的是哪一个fly的子类,就可以调用哪一个了。

4、Duck中performQuack方法,应用了委托,直接调用的是该接口FlyBehavior中的子类的fly对象。


代码:

/**
 * @author qmx
 * @version 1.0
 * @created 21-九月-2014 16:47:39
 */
public abstrack class Duck {

	FlyBehavior  flyBehavior;     //成员变量
	QuackBehavior quackBehavior;


	public Duck(){

	}


	public abstract void display(){

	}

	public void performQuack(){
            flyBehavior.fly();        //将fly动作委托给了FlyBehavior类
	}

	public void performQuack(){
	    quackBehavior.quack();

	}

	/**
	 * 
	 * @param fb
	 */
	public void setFlyBehavior(FlyBehavior fb){
	    fyBehavior = fb;             //动态的指向子类对象

	}

	/**
	 * 
	 * @param qb
	 */
	public void setQuackBehavior(QuackBehavior qb){
	    QuackBehavior = qb;
	}

	public void swim(){
	   System.out.println("All ducks float, even decoys!");

	}

}

子类继承父类(只写一个):


/**
 * @author qmx
 * @version 1.0
 * @created 21-九月-2014 16:47:40
 */
public class MallardDuck extends Duck {

    public MallardDuck(){
       flyBehavior = new FlyNoWay();
       quackBehavior = new Quack();

    }


    public void display(){
       System.out.println("I'm a mallard duck!");
    }

}

接口FlayBehavior:

/**
 * @author qmx
 * @version 1.0
 * @created 21-九月-2014 16:47:39
 */
public interface FlyBehavior {

	public void fly();

}

实现接口的FlyRocketPowered(只写一个):


/**
 * @author qmx
 * @version 1.0
 * @created 21-九月-2014 16:47:40
 */
public class FlyWithWings implements FlyBehavior {

	public void fly(){
	    System.out.println("I'm flying with my wings!");
	}

}

这样写客户端调用时:

	    Duck mallard = new MallardDuck();            <pre name="code" class="java">            mallard.performFly();          //为“I'm not fly!”
  mallard.setFlyBehavior(new FlyWithWings()); mallard.performFly(); //为“I'm flying with my wings!”
 


三、总结


之前设计模式中的策略其实在机房收费系统中的结账的时候,用策略+职责链一起用过,在职责链的强大阵容下,策略显得总是有点微小,心想是不是可以不用总结了,看似好像会了,但实际上,这篇博客用java的语言从新再写一边的时候,觉得学习到了很多。


感想就是:知识当你看过一遍觉得你都会了的时候,其实你只回了20%到30%;当你动手做了一遍的时候,其实你会了50%;当你思考了,并且总结了,你会了70%到80%;当你和别人分享你的知识,同时不断交流,你就可以说你是大牛了。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 39
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 39
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值