`

Head First 之 策略模式

阅读更多
设计原则:
1、找出应用中可能需要变化之处,把它独立出来,不要和那些不需变化的代码混在一起。
2、针对接口编程,而不是针对实现编程。(针对超类型编程)。
3、多用组合,少用继承。


示例程序(此处代码都为书上原码,只不过是本人手输入了一次)
大概讲下:

有套莫伊鸭子的游戏,SimUDuck,游戏中会出现许多鸭子,一边游泳,一边呱呱叫。
一开始,使用了标准的OO技术,设计了一个鸭子超类,并让各种鸭子继承此超类。

在此时,这种设计是对的,但是,如果老板说需要给鸭子增加个飞行的动作,那么此时该如何做呢?

我当时的做法和书中joe做法一样,把飞行动作放入父类,但这样,成了所有的鸭子都会飞,但明显不是所有鸭子都会飞,那么,又改为把飞行动作独立为一个接口,会飞的鸭子实现此接口,但这样同样很麻烦,每只会飞的鸭子都得实现飞行的方法。而且,飞行还有横飞,侧飞,倒飞,显而易见,(鸭子叫同样适合这种理论)这两种设计方法都不适合这里。

下面的代码:

package com.test;

鸭子超类:
public class Duck {
        //此处为组合(把鸭子叫的接口作为类的一个属性)
	private QuackBehavior quackBehavior;
	
	public QuackBehavior getQuackBehavior() {
		return quackBehavior;
	}

	public void setQuackBehavior(QuackBehavior quackBehavior) {
		this.quackBehavior = quackBehavior;
	}

	public Duck(){
		quackBehavior = new Quack();
	}
	
	public void performQuack(){
		quackBehavior.quack();
	}
	
	public static void main(String[] args) {
		Duck duck = new Duck();
		//动态设定鸭子叫的方式(可能嘎嘎,可能叽叽,也可能不会叫)
		duck.setQuackBehavior(new Squeak());
		duck.performQuack();
	}
}


package com.test;

/**
 * 飞行类的接口
 * @author mah
 *
 */
public interface FlyBehavior {
	public void fly();
}


package com.test;

/**
 * 鸭叫接口
 * @author mah
 *
 */
public interface QuackBehavior {
	public void quack();
}


package com.test;

public class FlyNoWay implements FlyBehavior{

	@Override
	public void fly() {
		System.out.println("不会飞");
	}
}


package com.test;

public class FlyWithWings implements FlyBehavior{

	@Override
	public void fly() {
		System.out.println("我飞~~~~");
	}

}


package com.test;
//木头鸭子叫声
public class MuteQuack implements QuackBehavior{

	@Override
	public void quack() {
		System.out.println("不会叫");
	}
}


package com.test;
//鸭子叫声
public class Quack implements QuackBehavior{

	@Override
	public void quack() {
		System.out.println("嘎嘎");
	}
}


package com.test;
//皮鸭子叫声
public class Squeak implements QuackBehavior{

	@Override
	public void quack() {
		System.out.println("叽叽");
	}

}


策略模式抽取算法,并分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户

OK,下一章,观察者模式
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics