Strategy

        以下内容学习自《Head First 设计模式》以及 Justin's Tech Blog,由本人概括整理。

        定义: 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.(策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。)

        怎么理解策略模式的定义呢?先大概整理说明一下这个来自head first中Duck的例子。
        场景条件:鸭子都有swim、quack、fly行为,这里假定所有的鸭子都会游泳。
        问题:现在要实现各种不同的鸭子(子类),不同的鸭子有不同的display。
        解决方案:
        1、将Duck设置为抽象类,实现swim、quack、fly方法,抽象display方法。所有的子类都继承自Duck,实现display。
        存在的问题:有的鸭子会叫,有的不会叫。同样的,有的会飞,有的不会飞。所以在抽象类里面实现quack和fly方法不可行。
        2、将quack和fly方法抽离出来,分别作为两个接口的方法,根据鸭子会不会飞、会不会叫独立的实现一个接口或者两个接口。
        存在问题:如果有很多的子类,那么每个子类都需要实现这两个接口,并且有很多子类所表现出来的quack和fly行为一样,这么一来很有可能将quack和fly重复实现了很多次,这是一种冗余,而且也是无谓的工作。
        3、策略模式:接口将系统的不同部分隔离开来(方法的具体实现隔离开),同时又将它们连接在一起(接口的行为放在一起,不同的行为相当于系统的不同部分。)

        先看一个具体的例子:

        定义两个接口,将quack和fly方法抽离出来。
public interface FlyBehavior {
	public Object Fly();//将具体实现抽离出来
}
public interface QuackBehavior {
	public Object Quack();
}


        定义几个类,实现这两个接口。
public class FlyNoWay implements FlyBehavior {
	@Override
	public Object Fly() {  //定义具体的实现
		return "不会飞";
	}
}
public class FlyWithWings implements FlyBehavior {
	@Override
	public Object Fly() {  //有多少方式就有多少实现
		return "我飞啦!";
	}
}

public class Quack1 implements QuackBehavior {
	@Override
	public Object Quack() {
		return "嘎嘎";
	}
}
public class Quack1 implements QuackBehavior {
	@Override
	public Object Quack() {
		return "吱吱";
	}
}


        实现子类继承Duck
public class RedHeadDuck extends Duck {
	public RedHeadDuck(){
		super.setFlyBehavior(new FlyWithWings());//根据不同的需求把实现set到相应的步骤当中。
		super.setQuackBehavior(new Quack1());
	}
	
	@Override
	public Object display() {
		return "我是一只红头鸭";
	}
}
public class RubberDuck extends Duck {
	public RubberDuck() {
		super.setFlyBehavior(new FlyNoWay());
		super.setQuackBehavior(new Quack2());
	}
	
	@Override
	public Object display() {
		return "我是一只橡皮鸭";
	}
}


        运行以及运行结果:
public class Strategy {
	public static void main(String[] args) {
		RedHeadDuck redHeadDuck = new RedHeadDuck();
		RubberDuck rubberDuck = new RubberDuck();
		
		System.out.println(redHeadDuck.display()+","+redHeadDuck.fly()+","+redHeadDuck.quack()); //相同的方法,但由于set了不同的实现,所以表现出了不同的结果
		System.out.println(rubberDuck.display()+","+rubberDuck.fly()+","+rubberDuck.quack());
	}
}

我是一只红头鸭,我飞啦!,嘎嘎
我是一只橡皮鸭,不会飞,吱吱


        这里打个比方,对于一件事情,有相同的步骤。不同的人去做,可能步骤的顺序不一样,每一步的具体实现方法也不一样。我们需要的就是把步骤的具体实现抽离出来,有多少不同的实现,就具体定义多少不同的实现。对于不同的人,只需要对于不同的步骤,选择自己的实现方法就行。
        上例中fly、quack方法相当于“步骤”,FlyNoWay和FlyWithWings相当于步骤的具体实现。根据不同的需要,把实现set到相应的步骤当中。
        这时返回到策略的定义,“算法”在这里指的就是FlyBehavior和QuackBehavior的不同实现。

        策略模式的优点不多说,但是缺点也是显而易见的。 因为每个具体策略类都会产生一个新类,所以会增加系统需要维护的类的数量。

猜你喜欢

转载自paddy-w.iteye.com/blog/1025645