Head First之策略模式

1、策略模式的定义

策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

2、鸭子设计

2.1 需求

定义绿头鸭,红头鸭,橡胶鸭,诱饵鸭(前俩个都是普通鸭子,外观不同,橡胶鸭不会飞,诱饵鸭不会飞也不会叫)

2.2 设计方式1(一般实现)


这种设计应该说是我们大多数人下意识都会想到的,既通过超类抽取了游泳和外观的方法(继承抽取共性,所有的鸭子都会游泳,所有的鸭子都有外貌,当然fly()方法和quack()方法也可以抽取到父类中,子类重写,但是你要这么写,可能你的上司就要找你谈心让你回炉重造了),又通过接口来实现不同鸭子的不同需求(诱饵鸭不会飞就不实现Flyable接口,橡胶鸭呱呱叫就实现Quackable接口。
当我第一次看到这个设计的时候,觉得没毛病,如果是我的话我也会这么做,可是它实在不是一个值得称赞的设计。

2.3 设计方式2 (优化)


①很明显,这样设计增加了我们的代码量(多了两个类实现接口),但是这样做飞行动作和呱呱叫的动作就可以复用了,不必再被迫关联到鸭子超类。
②此外,我们可以动态增加一些行为,又不会对原有的行为造成影响。

3、代码实现

①实现鸭子的基本逻辑

public abstract class Duck {
	public FlyBehavior flyBehavior;
	public QuackBehavior quackBehavior;
	public Duck() {
		// TODO Auto-generated constructor stub
	}
	
	public abstract void display();
	
	public void performFly() {
		flyBehavior.fly();
	}
	
	public void performQuack() {
		quackBehavior.quack();
	}
	
	public void swim() {
		System.out.println("All ducks float, even decoys!");
	}
	
}
Duck
public interface FlyBehavior {
	public void fly();
}

FlyBehavior
public class FlyNoWay implements FlyBehavior{

	@Override
	public void fly() {
		// TODO Auto-generated method stub
		System.out.println("I can't fly");
	}

}

FlyNoWay
public class FlyWithWings implements FlyBehavior{

	@Override
	public void fly() {
		// TODO Auto-generated method stub
		System.out.println("I can fly");
	}

}

FlyWithWings
public interface QuackBehavior {
	public void quack();
}


QuackBehavior
public interface QuackBehavior {
	public void quack();
}


Quack
public class Squeak implements QuackBehavior{

	@Override
	public void quack() {
		// TODO Auto-generated method stub
		System.out.println("squeak");
	}

}

Squeak
public class MuteQuack implements QuackBehavior{

	@Override
	public void quack() {
		// TODO Auto-generated method stub
		System.out.println("silence");
	}

}
MuteQuack
public class MallardDuck extends Duck{

	public MallardDuck() {
		flyBehavior = new FlyWithWings();
		quackBehavior = new Quack();
	}
	
	public void display() {
		System.out.println("I'm a real Mallard duck");
	}
	
}

MallardDuck

MallardDuck
public class MiniDuckSimulator {
	public static void main(String[] args) {
		Duck mallark = new MallardDuck();
		mallark.performFly();
		mallark.performQuack();
	}
	
}

运行结果

I can fly
Quack

②动态设定鸭子的行为

Duck类中新增set方法

	public void setFlyBehavior(FlyBehavior fb) {
		flyBehavior = fb;
	}
	
	public void setQuackBehavior(QuackBehavior qb) {
		quackBehavior = qb;
	}

定义鸭子类型模型鸭

public class ModelDuck extends Duck {
	public ModelDuck() {
		// TODO Auto-generated constructor stub
		flyBehavior = new FlyNoWay();
		quackBehavior = new Quack();
	}

	@Override
	public void display() {
		// TODO Auto-generated method stub
		System.out.println("I'm a model duck");
		
	}

}
ModelDuck

定义火箭飞行行为

public class FlyRocketPowered implements FlyBehavior {

	@Override
	public void fly() {
		// TODO Auto-generated method stub
		System.out.println("I'm flying with a rocket"); //定义火箭飞行
	}

}
FlyRocketPowered

改变测试类

public class MiniDuckSimulator {
	public static void main(String[] args) {
		Duck mallark = new MallardDuck();
		mallark.performFly();
		mallark.performQuack();
		Duck model = new ModelDuck();
		model.performFly();
		model.setFlyBehavior(new FlyRocketPowered()); //动态设定行为
		model.performFly();
	}
	
}

运行结果

I can fly
Quack
I can't fly
I'm flying with a rocket

设计总览

4.小结

这个是书上的例子,它很全面但是它不好,它讲得不清楚,更不易理解,虽然结合实际但是看了还是让人不知道什么时候用。所以暂时先放在这里,过段时间写篇易理解的。这篇着实难懂,但我还是不会删它,因为理解了策略模式,你只会觉得这篇just so so.

posted @ 2021-02-10 17:49  我的小鱼干嘞  阅读(107)  评论(0编辑  收藏  举报