HeadFirst策略模式


HeadFirst——策略设计模式

HeadFirst鸭子实例

1.1鸭子超类定义

HeadFirstz中的鸭子实例是这样的,鸭子有游泳,呱呱叫,外观,飞行等方法,且该类是超类,其他鸭子都继承该超类。如下:

 class Duck {
	public void quack(){};//叫声
	public void swim(){};//游泳
	public void display(){};//外形
	public void fly(){};//飞行
}



定义这样一个Duck超类就有问题了。
1.代码在多个子类中重用.
2.很难知道所有鸭子的全部行为.
3.运行时的行为不容易改变.
4.改变一处牵动全身,造成其他鸭子不想要的改变.
这样代码的可维护性就太差,这是继承带来的问题.
这样就引出第一个设计原则: 找出应用中可能需要变化之处,把他们独立起来,不要和那些不需要变化的代码混在一起.

1.2鸭子动态方法提取接口

为了解决上面的问题,我们将鸭子会变化的行为(如:fly,display)提取为接口.如下:

interface FlyBehavior{
	void fly();//飞行
}

interface QuackBehavior{
	void quack();//叫声
}


这是第二个设计原则:针对接口编程,而不是针对实现编程.有了接口以后定义相应的实现方法.如下:

class FlyWithWings implements FlyBehavior{
	@Override
	public void fly() {
		System.out.println("我飞起来了");
	}
}

class FlyNoWay implements FlyBehavior{
	@Override
	public void fly() {
		System.out.println("我不能飞");
	}
}


class Quack implements QuackBehavior{
	@Override
	public void quack() {
		System.out.println("呱呱叫");
	}
}

class Squeak implements QuackBehavior{
	@Override
	public void quack() {
		System.out.println("吱吱叫");
	}
}


这样的设计,可以让飞行和呱呱叫的动作被其他的对象复用,因为这些行为已经与鸭子无关了。
而我们可以添加一些行为,不会影响到既有的行为类,也不会影响“使用”到飞行行为的鸭子类.

1.3整合鸭子的行为

1.3.1首先

在Dock类中"加入两个实例变量",为flyBehavior,quackBehavior,这两个变量是接口类型,在这里使用了面向接口编程的设计原则.另外还有两个执行方法,用于执行飞行和叫声.如下:

class Duck {
	FlyBehavior flyBehavior;
	QuackBehavior quackBehavior;
	public void performQuack(){
		quackBehavior.quack();
	}
	public void performFly(){
		flyBehavior.fly();
	}
	public void swim(){};//游泳
	public void display(){};//外形
}


1.3.2鸭子继承类

当创建MallardDuck实例时,它的构造器会把继承来的quackBehavior对象初始化成Quack类型,并且可以调用performQuack方法调用!


class MallardDuck extends Duck{
		public MallardDuck(){
		flyBehavior = new FlyWithWings();
		quackBehavior = new Quack();
	}
	
}


1.4封装行为的大局观

"有一个"可能比“是一个”更好,每个鸭子都有Fly和Quack行为接口,当将这两个类结合起来使用时比继承优点多,前面已经提到了.这是第三个设计原则:多用组合,少用继承.下图为程序UML图:



策略模式

2.1定义

策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。


2.1优缺点

优点:

1、 策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码转移到父类里面,从而避免重复的代码。

2、 策略模式提供了可以替换继承关系的办法。继承可以处理多种算法或行为。如果不是用策略模式,那么使用算法或行为的环境类就可能会有一些子类,每一个子类提供一个不同的算法或行为。但是,这样一来算法或行为的使用者就和算法或行为本身混在一起。决定使用哪一种算法或采取哪一种行为的逻辑就和算法或行为的逻辑混合在一起,从而不可能再独立演化。继承使得动态改变算法或行为变得不可能。

3、 使用策略模式可以避免使用多重条件转移语句。多重转移语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重转移语句里面,比使用继承的办法还要原始和落后。

缺点:

1、客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。

2、 策略模式造成很多的策略类,每个具体策略类都会产生一个新类。有时候可以通过把依赖于环境的状态保存到客户端里面,而将策略类设计成可共享的,这样策略类实例可以被不同客户端使用。换言之,可以使用享元模式来减少对象的数量。

其他人的策略博客:http://blog.csdn.net/hguisu/article/details/7558249

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值