设计模式之策略模式

说明:以下内容是学习Head First后自行整理的笔记。内容和程序均来自于该书


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


概念理解起来生硬,下面用一个鸭子的例子说明。

有一个模拟鸭子的游戏。游戏中有各种各样的鸭子,它们可以游泳,呱呱叫。按照之前的设计一般是这样的:有一个鸭子的超类Duck,有swim、quack的方法,然后不同的鸭子类去继承它。

这个时候多了一个需求,要让鸭子会飞,很自然你会在Duck里面去加一个fly方法。

仔细想一想这种设计思路,是不是会存在问题。

1、如果你在Duck里对fly等方法做了实现,这个时候会出现问题,那就是并不是所有的鸭子都是会飞的,比如只有野鸭子会飞,橡皮鸭并不会飞。

2、当然你会说我会把实现放到子类中,超类并不做实现。那么另一个问题自然会出现,那就是如果野鸭子跟水鸭子都是会飞的,而且都是一样的飞法,那fly这个方法不就会被写了两次甚至跟多,这样是不利于维护的。而且如果游戏中有另一个类:鹅,它也是会飞的,那就更加麻烦了。


所以这个时候策略模式就发挥作用了

下图是设计的思路

wKioL1VYNDGR15DKAABFLrezVbA364.gif


下面是代码

Duck.java

package bean;


public abstract class Duck {

	public Duck(){};
	
	FlyBehavior flyBehavior;
	QuackBehavior quackBehavior;
	
	public FlyBehavior getFlyBehavior() {
		return flyBehavior;
	}
	public void setFlyBehavior(FlyBehavior flyBehavior) {
		this.flyBehavior = flyBehavior;
	}
	public QuackBehavior getQuackBehavior() {
		return quackBehavior;
	}
	public void setQuackBehavior(QuackBehavior quackBehavior) {
		this.quackBehavior = quackBehavior;
	}

	public void swim(){
		System.out.println();
	}
	
	public void fly(){
		flyBehavior.fly();
	}
	
	public void quack(){
		quackBehavior.quack();
	}
}

FlyBehavior.java

package bean;

public interface FlyBehavior {

	public void fly();
	
}

FlyWithWings.java

package bean;

public class FlyWithWings implements FlyBehavior {

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

}

FlyNoWay.java

package bean;

public class FlyNoWay implements FlyBehavior {

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

}

QuackBehavior.java

package bean;

public interface QuackBehavior {

	public void quack();
	
}

QuackGaGa.java

package bean;

public class QuackGaGa implements QuackBehavior {

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

}

QuackNoWay.java

package bean;

public class QuackNoWay implements QuackBehavior {

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

}

CleverDuck,java

package bean;

public class CleverDuck extends Duck {

	public CleverDuck(){
		this.flyBehavior = new FlyWithWings();
		this.quackBehavior = new QuackGaGa();
	}
	
}

StupidDuck.java

package bean;

public class StupidDuck extends Duck {

	public StupidDuck(){
		this.flyBehavior = new FlyNoWay();
		this.quackBehavior = new QuackNoWay();
	}
	
}



设计原则:

1、针对接口编程,而不是针对实现编程(这个很好理解)

2、多用组合,少用继承。(如本例中,鸭子的行为不是靠继承得来的,而是通过行为对象的“组合”得来的,这让程序更加的灵活)

你可能感兴趣的:(java,设计模式,策略模式)