欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

设计模式-策略模式

程序员文章站 2022-05-04 20:42:57
...
转载请注明本文出自1124117571的博客(www.1124117571.iteye.com),谢谢支持!

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

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

 

 

 

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

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

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

 

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

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

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


设计模式-策略模式
            
    
    博客分类: 设计模式 Java设计模式策略模式 
                 

 

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


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

设计模式-策略模式
            
    
    博客分类: 设计模式 Java设计模式策略模式 
                             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();
	}
}
 

 

结果:


设计模式-策略模式
            
    
    博客分类: 设计模式 Java设计模式策略模式 
 

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

 

创建一个新的鸭子类:模型鸭(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();
	}
}

 

实验结果:


设计模式-策略模式
            
    
    博客分类: 设计模式 Java设计模式策略模式 
 

 

实验总结:

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

 

 

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

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