第1章:策略模式

1 策略模式

策略模式定义了算法族分别封装起来,让他们之间可以相互替换(实现接口),此模式让算法的变化独立于使用算法的客户(组合+委托)

1.1 应用场景

需要方法的实现独立于客户端代码,即保证客户端代码不变前提下,方法具体执行内容可以任意更换

Duck mallardDuck = new MallardDuck();
//下方代码后,该语句的调用产生不同的结果,即算法间的相互替换
mallardDuck.setFlyBehavior(new FlyNoWay());
mallardDuck.performFly();

1.2 错误解决方案

1.2.1 父类中直接增加方法
package strategy.pattern;

public abstract class Duck1 {
    //组合解决的问题
	//1.所有Duck1中,不会飞或不是quack这么叫的鸭子,都需要重写下面方法,这样重复代码太多,不利于维护
	
	//策略模式解决的问题
	//2.客户端调用同一个类型的子类对象的该方法结果是固定的,例如创建一个Duck1子类,该对象无法完成一会可以飞,一会不能飞
	public void fly(){
		System.out.println("I can fly");
	}
	public void quack(){
		System.out.println("quack");
	}
}

1.2.2 不同子类实现不同包含方法的接口,并重写该方法

FlyBehavior接口中定义抽象方法fly,所有鸭子实现该接口,并重写fly方法,与上面缺点相同

1.3 解决思路

1.3.1 分开变化和不会变化的部分

设计原则:找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起

  1. 分析该问题中,fly与quack对于不同的鸭子子类,行为是不同的,因此应该将该方法的具体实现与鸭子类本身分离开
  2. Duck2
package strategy.pattern;

public abstract class Duck2 {
	Quack quack = new Quack();
	FlyWithWings flyWithWings = new FlyWithWings();
	public void fly(){
		//具体的实现在Quack和FlyWithWings中定义,达到了和Duck2及其子类的分离
		flyWithWings.fly();
	}
	public void quack(){
		quack.quack();
	}
}
1.3.2 面向接口编程

设计原则:针对接口编程,而不是针对实现编程

设计原则:多用组合少用继承

  1. 之前无法动态地指定鸭子子类的行为,也无法为特定鸭子子类指定特定行为
  2. Duck3
package strategy.pattern;

public abstract class Duck3 {
	//1.QuackBehavior、FlyBehavior为接口,此处为面向接口编程
	//使用组合解决了继承带来的代码重复问题
	QuackBehavior quack;
	FlyBehavior flyWithWings;
	public void fly(){
	    //执行的是flyWithWings变量指向的真正的对象的fly方法
		flyWithWings.fly();
	}
	public void quack(){
		quack.quack();
	}
	//2.可以指定具体行为对应类,可以动态的指定鸭子子类的行为,也可以为特定鸭子子类指定特定行为
	public void setQuack(QuackBehavior quack) {
		this.quack = quack;
	}
	public void setFlyWithWings(FlyBehavior flyWithWings) {
		this.flyWithWings = flyWithWings;
	}
}

1.4 类图

image

1.5 代码

  1. FlyBehavior:接口
package strategy.pattern;

public interface FlyBehavior {
	void fly();
}

  1. FlyNoWay:实现类
package strategy.pattern;

public class FlyNoWay implements FlyBehavior {
	@Override
	public void fly() {
		System.out.println("I cant fly");
	}
}

  1. FlyWithWings:实现类
package strategy.pattern;

public class FlyWithWings implements FlyBehavior {
	@Override
	public void fly() {
		System.out.println("I'm flying");
	}
}

  1. QuackBehavior:接口
package strategy.pattern;

public interface QuackBehavior {
	void quack();
}

  1. Quack:实现类
package strategy.pattern;

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

  1. Squeak:实现类
package strategy.pattern;

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

  1. MuteQuack:实现类
package strategy.pattern;

public class MuteQuack implements QuackBehavior{
	@Override
	public void quack() {
		System.out.println("Silence");
	}
}

  1. Duck
package strategy.pattern;

public abstract class Duck {
	//使用策略模式实现鸭子的各种行为,即鸭子的行为封装在一组类中,可以轻易的扩充与改变
	FlyBehavior flyBehavior;
	QuackBehavior quackBehavior;
	public abstract void display();
	public void swim(){
		System.out.println("All ducks float,even decoys");
	}
	public void performFly(){
		flyBehavior.fly();
	}
	public void performQuack(){
		quackBehavior.quack();
	}
	//提供两个set方法,可以动态修改鸭子的行为
	public void setFlyBehavior(FlyBehavior flyBehavior) {
		this.flyBehavior = flyBehavior;
	}
	public void setQuackBehavior(QuackBehavior quackBehavior) {
		this.quackBehavior = quackBehavior;
	}
}

  1. MallardDuck:绿头鸭,Duck的一个实现类
package strategy.pattern;

public class MallardDuck extends Duck{
	@Override
	public void display() {
		System.out.println("I'm a real Mallard duck");
	}
	//初始化时,顺便初始化绿头鸭的所有行为
	public MallardDuck(){
		flyBehavior = new FlyWithWings();
		quackBehavior = new Quack();
	}
}

  1. MallarDuckSimulator:测试类
package strategy.pattern;

public class MallarDuckSimulator {
	public static void main(String[] args) {
		Duck mallardDuck = new MallardDuck();
		mallardDuck.performFly();
		mallardDuck.performQuack();
		mallardDuck.setFlyBehavior(new FlyNoWay());
		//前后同一个对象mallardDuck调用同一个方法performFly,打印的内容不同,即可以在运行时改变行为
		mallardDuck.performFly();
	}
}

posted @ 2019-05-09 13:51  含低调  阅读(106)  评论(0)    收藏  举报