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