java设计模式-策略模式

java设计模式-策略模式

Java 其它杂项

详细介绍

Policy-mode

Java design mode --Policy mode java设计模式--策略模式

所谓策略模式可以简单的想成:创建一个能够根据所传递的参数对象的不同而具有不同行为的方法。 当然,当你需要装成高大上的样子的话,你可以这样跟你的朋友、上司说:策略模式定义了算法,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

栗子说话:

我们有一个鸭子应用,有各种鸭子,可以游泳,可以叫 当然我们有设计了一个超类,并让各种鸭子都继承自这个超类,然后我们所有的鸭子都具有了 呱呱叫的功能了,如下图:

看上去是可以的,而且很多时候我们都是这样设计的,但是这个时候 有加上了一个 fly() 也就是飞的行为,这有什么困难,超类加上 就ok啦 事情来了,然而并不是所有的鸭子都会飞的,如此继承,那不会飞的鸭子也会飞了,再继续想,有的鸭子咕咕叫,有的呱呱叫,还有的不叫,怎么办,那这样设计就太坑啦

所以我们了解了:使用继承并不能很好的解决这种问题,因为鸭子的行为在子类里不断的改变,并且让所有的子类都有这些行为是不恰当的,你可能会想到用接口,然而java接口不具有实现代码,所有继承接口无法达到代码复用 这就意味着:无论何时需要修改某个行为,你必须得往下追踪并在每一个定义此行为的类中去修改它,而且还容易出错

刚好就有这样一个规则设计用于此情况:找出应用中可能需要变化之处,把他们独立出来,不要和没变化的代码混在一起,也就是把变化的行为提取出来,方便以后可以轻易的扩充和修改而不影响不需要改变的部分。

在此,我们又两个接口,FlyBehavior 和 QuackBehavior 还有他们对应的实现类

把飞行和叫的行为委托给其他人来处理,而不是定义在超类或者是子类里面 定义超类:Duck.java public abstract class Duck { public FlyBehavior flyBehavior; public QuackBehavior quackBehavior;

public Duck() {}

public abstract void display();
public void swim() {
System.out.println("I can swimming");
}

public void performFly() {
flyBehavior.fly();//委托给行为类
}


public void performQuack() {
quackBehavior.quack();//委托给行为类
}

}

俩接口: //所有飞行行为实现 public interface FlyBehavior { public void fly();//fly

} //所有叫行为实现 public interface QuackBehavior { public void quack(); }

然后就是我们具体的实现类了,我们的实现类可以有多个,什么会飞的啊 不会飞的啊,还有呱呱叫的,不会叫的,根据具体行为来实现

将飞行和叫的行为和超类剥离开,让行为对象去叫,去飞,我们只关心该对象如何叫就行

//不会飞 public class FlyNoWay implements FlyBehavior{

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


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

}
//呱呱叫的
public class Quack implements QuackBehavior{


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

}

}

//然后来看下我们的具体的鸭MallardDuck public class MallardDuck extends Duck {

@Override
public void display() {
	// TODO Auto-generated method stub
	System.out.println("I am MallardDuck");
}

public MallardDuck() {
	quackBehavior = new Quack();
	flyBehavior = new FlyWithWings();
}

}

//测试 public class MiniDuckSimulator {

public static void main(String[] args) {
	Duck mallardDuck = new MallardDuck();
	mallardDuck.display();
	mallardDuck.performFly();
	mallardDuck.performQuack();
	mallardDuck.swim();
}

} //output:

I am MallardDuck
I can fly
I can Quack
I can swimming

接下来我们看下如何动态的去改变这些行为

在Duck类中新加方法:

public abstract class Duck {

public FlyBehavior flyBehavior;
public QuackBehavior quackBehavior;


public Duck() {
}


public abstract void display();


public void swim() {
	System.out.println("I can swimming");
}


public void performFly() {
	flyBehavior.fly();// 委托给行为类
}


public void performQuack() {
	quackBehavior.quack();// 委托给行为类
}


public void setFlyBehavior(FlyBehavior flyBehavior) {
	this.flyBehavior = flyBehavior;
}


public void setQuackBehavior(QuackBehavior quackBehavior) {
	this.quackBehavior = quackBehavior;
}

}

修改我们的测试类MiniDuckSimulator

public class MiniDuckSimulator {

public static void main(String[] args) {
	Duck mallardDuck = new MallardDuck();
	mallardDuck.display();
	mallardDuck.performFly();
	mallardDuck.performQuack();
	mallardDuck.swim();

	System.out.println("==========================");

	Duck modelDuck = new ModelDuck();
	modelDuck.performFly();
	modelDuck.performQuack();
	modelDuck.setFlyBehavior(new FlyWithWings());
	modelDuck.performFly();
}

} output:

I am MallardDuck
I can fly
I can Quack
I can swimming

I can't fly
I can Quack
I can fly

改变前:第一次调用performFly()会被委托给flyBehavior对象,setter方法会将会飞的行为设置鸭中,然后鸭就具有了飞行的行为 可以看到,我们鸭子的行为被动态的改变了 在运行时想改变鸭子的行为,只需要调用鸭子的setter方法就可以了 到此 搞定!

csdn传送门:http://blog.csdn.net/flyingzhlunasea/article/details/54928070

推荐源码