设计模式-策略模式

转载请注明本文出自1124117571的博客(www.1124117571.iteye.com),谢谢支持!

策略模式(Strategy)行为型模式

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

 

 

 

OO原则:针对接口编程,而不是针对实现编程。

针对接口:指的是制造其它类专门实现接口,由行为类来实现行为接口,指的就是针对超类型编程。

针对实现:指的就是具体实现超类方法或者继承某个接口并且由子类实现。

 

下面就拿Duck例子来说明策略模式:

以前的做法:行为来自Duck超类的具体实现,或是继承某个接口并且由子类自行实现而来;这两种做法都是依赖于“实现”。

新设计:鸭子的子类将使用接口所表示的行为,所以实际的“实现”不会被绑死在鸭子的子类(MallarDuck、RedheadDuck等)中,换句话说,特定的具体行为编写在实现了FlyBehavior与QuackBehavior中。



                 

 

从现在开始,鸭子的行为将被放在分开的类中,此类专门提供某行为接口的实现。这样,鸭子类就不再需要知道行为的实现细节。


下面是我们要使用的例子Duck的UML图:


                             Duck的UML图

 

下面是UML图中每个部分的具体代码:

 

Duck类

 

/*
Duck类
*/
public abstract class Duck
{
	FlyBehavior flyBehavior;
	QuackBehavior quackBehavior;

	public Duck(){}
	
	public abstract void display();

	public void performFly(){
		flyBehavior.fly();
	}

	public void performQuack(){
		quackBehavior.quack();
	}

	public void swim(){
		System.out.println("All ducks float ever decoys!");
	}

	// 通过setter method来设定鸭子的行为,而不是在鸭子构造器内实例化
	public void setFlyBehavior(FlyBehavior fb){
		flyBehavior = fb;
	}

	public void setQuackBehavior(QuackBehavior qb){
		quackBehavior = qb;
	}

}
 

 

FlyBehavior接口与两个行为实现类(FlyWithWings.java与FlyNoWay.java)

 

/*
FlyBehavior接口与两个行为实现类(FlyWithWings.java与FlyNoWay.java)
*/
public interface FlyBehavior
{
	public void fly();
}

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

public class FlyNoWay implements FlyBehavior
{
	public void fly(){
		System.out.println("I can't flying");
	}
}

 

 

 QuackBehavior接口及其三个实现类(Quack.java,MuteQuack.java,Squeak.java)

 

/*
QuackBehavior接口及其三个实现类(Quack.java,MuteQuack.java,Squeak.java)
*/
public interface QuackBehavior
{
	public void quack();
}

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("Sqeak");
	}
}
 

 

MallardDuck类

 

/*
MallardDuck类
绿头鸭使用Quack类来处理呱呱叫,所以当performQuack()被调用的时候,叫的职责被委托给Quack对象,而我们得到的了真正的呱呱叫
*/
public class MallardDuck extends Duck
{
	// 别忘了,因为MallardDuck继承了Duck类,所以具有flyBehavior和quackBehavior实例变量
	public MallardDuck(){	
		quackBehavior = new Quack();	
		flyBehavior = new FlyWithWings();
	}

	public void display(){
		System.out.println("I'm a real Mallard Duck~");
	}
}
 

 

测试类

 

/*
测试类
*/
class MiniDuckSimulator
{
	public static void main(String[] args) 
	{
		Duck mallard = new MallardDuck();
		mallard.performQuack();		// 调用继承来的quackBehavior引用对象的quack()
		mallard.performFly();
	}
}
 

 

结果:



 

下面我们做些变化来展现策略模式的优点

 

创建一个新的鸭子类:模型鸭(ModelDuck.java)

 

/*
创建一个新的鸭子类:模型鸭(ModelDuck.java)
*/
public class ModelDuck extends Duck
{
	public ModelDuck(){
		flyBehavior = new FlyNoWay();
		quackBehavior = new Quack();
	}
	public void display(){
		System.out.println("I'm a model duck");
	}
}
 

 

建立一个新的FlyBehavior类型(FlyRocketPoered.java)

 

/*
建立一个新的FlyBehavior类型(FlyRocketPoered.java)
*/
public class FlyRocketPowered implements FlyBehavior
{
	// 建立了一个利用火箭动力的飞行行为
	public void fly(){
		System.out.println("I'm flying with a rocket!");
	}
}

 

 
对原先的测试进行以下修改:

通过set方法来动态设置需要改变的模块
加上模型鸭(ModelDuck),并使模型鸭拥有火箭动力

 

修改后的测试类
/*
测试类
*/
class MiniDuckSimulator
{
	public static void main(String[] args) 
	{
		Duck mallard = new MallardDuck();
		mallard.performQuack();		// 调用继承来的quackBehavior引用对象的quack()
		mallard.performFly();

		System.out.println("下面是模型鸭的动态添加功能!");
		// 改变测试类,通过set方法来动态设置需要改变的模块
		// 加上模型鸭(ModelDuck),并使模型鸭拥有火箭动力

		Duck model = new ModelDuck();
		model.performFly();
		// 调用继承来的setter方法,把火箭动力飞行的行为设定到模型鸭中。
		model.setFlyBehavior(new FlyRocketPowered());	
		model.performFly();
	}
}

 

实验结果:



 

 

实验总结:

  在运行时想改变鸭子的行为,只需调用鸭子的setter方法即可,从而实现了在运行时动态的改变行为。

 

 

从策略模式中得到的总结:

以上就是策略模式的应用之一,在上面的那个例子中,将FlyBehaviorQuackBehavior等行为的具体实现都封装起来,并且可以相互替换(通过setter方法),此模式让算法的变化独立于使用算法的客户。满足了针对接口编程,而不是针对实现编程,即由行为类(QuackSqueakMuteQuack等)来实现接口(FlyBehaviorQuackBehavior)而不是Duck类来实现行为接口,所以实际的“实现”(RedheadDuckModelDuck等)不会被绑死在鸭子的子类中,从而提高了代码的弹性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值