现在的位置: 首页 > 综合 > 正文

HeadFirst设计模式笔记:(一)策略模式 —— 封装行为的大局观

2013年01月19日 ⁄ 综合 ⁄ 共 3230字 ⁄ 字号 评论关闭

详细内容参见《HeadFirst设计模式》第一章 1设计模式入门欢迎来到设计模式世界

策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。(原文:The Strategy Pattern defines a family of algorithms,encapsulates each one,and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.)

以会“飞”和会“叫”的鸭子游戏为例。

1. 定义“飞”和“叫”的行为接口。

“飞”行为的接口类,只包含一个抽象的fly()方法。

public interface FlyBehavior {
	public void fly();
}

“叫”行为的接口类,只包含一个抽象的quack()方法。

public interface QuackBehavior {
	public void quack();
}

2. 定义鸭子的抽象基类。

包含“飞”行为和“叫”行为的两个实例变量,以为这两个实例变量的存取方法。抽象的display()方法,供子类去实现。最后,所有的鸭子都会游泳,swim()方法由子类去继承。

public abstract class Duck {
	FlyBehavior flyBehavior;
	QuackBehavior quackBehavior;
 
	public Duck() {
	}
 
	public void setFlyBehavior (FlyBehavior fb) {
		flyBehavior = fb;
	}
 
	public void setQuackBehavior(QuackBehavior qb) {
		quackBehavior = qb;
	}
 
	abstract void display();
 
	public void performFly() {
		flyBehavior.fly();
	}
 
	public void performQuack() {
		quackBehavior.quack();
	}
 
	public void swim() {
		System.out.println("All ducks float, even decoys!");
	}
}

3. 实现一些具体的“飞”行为类。

public class FlyNoWay implements FlyBehavior {
	public void fly() {
		System.out.println("I can't fly");
	}
}
public class FlyWithWings implements FlyBehavior {
	public void fly() {
		System.out.println("I'm flying!!");
	}
}
public class FlyRocketPowered implements FlyBehavior {
	public void fly() {
		System.out.println("I'm flying with a rocket");
	}
}

4. 实现一些具体的“叫”行为类。

public class FakeQuack implements QuackBehavior {
	public void quack() {
		System.out.println("Qwak");
	}
}
public class Quack implements QuackBehavior {
	public void quack() {
		System.out.println("Quack");
	}
}
public class MuteQuack implements QuackBehavior {
	public void quack() {
		System.out.println("<< Silence >>");
	}
}
public class Squeak implements QuackBehavior {
	public void quack() {
		System.out.println("Squeak");
	}
}

5. 实现一些具体的鸭子类。

public class DecoyDuck extends Duck {
	public DecoyDuck() {
		setFlyBehavior(new FlyNoWay());
		setQuackBehavior(new MuteQuack());
	}
	public void display() {
		System.out.println("I'm a duck Decoy");
	}
}
public class MallardDuck extends Duck {
	public MallardDuck() {
	        quackBehavior = new Quack();
                flyBehavior = new FlyWithWings();
	}
	public void display() {
		System.out.println("I'm a real Mallard duck");
	}
}
public class ModelDuck extends Duck {
	public ModelDuck() {
		flyBehavior = new FlyNoWay();
		quackBehavior = new Quack();
	}

	public void display() {
		System.out.println("I'm a model duck");
	}
}
public class RedHeadDuck extends Duck {
 
	public RedHeadDuck() {
		flyBehavior = new FlyWithWings();
		quackBehavior = new Quack();
	}
 
	public void display() {
		System.out.println("I'm a real Red Headed duck");
	}
}
public class RubberDuck extends Duck {
 
	public RubberDuck() {
		flyBehavior = new FlyNoWay();
		quackBehavior = new Squeak();
	}
 
	public void display() {
		System.out.println("I'm a rubber duckie");
	}
}

6. 总结设计原则。

(1)  找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。

(2)  针对接口编程,而不是针对实现编程。“针对接口编程”真正的意思是“针对超类型(supertype)编程”。

(3)  多用组合,少用继承。

7. 整个鸭子游戏系统的类图。

8. 测试代码。

public class MiniDuckSimulator1 {
 
	public static void main(String[] args) {
 
		Duck mallard = new MallardDuck();
		mallard.performQuack();
		mallard.performFly();
   
		Duck model = new ModelDuck();
		model.performFly();
		model.setFlyBehavior(new FlyRocketPowered());
		model.performFly();

	}
}
public class MiniDuckSimulator {
 
	public static void main(String[] args) {
 
		MallardDuck	mallard = new MallardDuck();
		RubberDuck	rubberDuckie = new RubberDuck();
		DecoyDuck	decoy = new DecoyDuck();
 
		ModelDuck	model = new ModelDuck();

		mallard.performQuack();
		rubberDuckie.performQuack();
		decoy.performQuack();
   
		model.performFly();	
		model.setFlyBehavior(new FlyRocketPowered());
		model.performFly();
	}
}

抱歉!评论已关闭.