java设计模式---策略模式
来源:互联网 发布:住院电子病历软件 编辑:程序博客网 时间:2024/06/13 13:34
所谓策略模式可以简单的想成:创建一个能够根据所传递的参数对象的不同而具有不同行为的方法。
当然,当你需要装成高大上的样子的话,你可以这样跟你的朋友、上司说:策略模式定义了算法,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
栗子说话:
我们有一个鸭子应用,有各种鸭子,可以游泳,可以叫
当然我们有设计了一个超类,并让各种鸭子都继承自这个超类,然后我们所有的鸭子都具有了 呱呱叫的功能了,如下图:
看上去是可以的,而且很多时候我们都是这样设计的,但是这个时候 有加上了一个 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方法就
到此
搞定!
github传送门(code):https://github.com/flyingzh/Policy-mode
- Java设计模式 -- 策略模式
- java设计模式-----策略模式
- java 设计模式-策略模式
- java设计模式--策略模式
- java设计模式-策略模式
- java设计模式-策略模式
- java设计模式--策略模式
- java设计模式---策略模式
- java设计模式---策略模式
- java设计模式---策略模式
- 【Java设计模式】策略模式
- java设计模式--策略模式
- Java设计模式----策略模式
- Java设计模式------------策略模式
- Java设计模式 - 策略模式
- java设计模式---策略模式
- java设计模式-策略模式
- java设计模式----策略模式
- Activity生命周期笔记
- asm更改磁盘名 How to rename ASM disks
- 从阿里、微软、AWS财报看评云计算发展
- linux设备驱动归纳总结(四):4.单CPU下竞态和并发
- mysql引擎的介绍、区别及选择
- java设计模式---策略模式
- 【thinkphp 5 在nginx 环境下路由无法生效(404 500错误 )的解决方法】
- ngxin 反向代理 负载均衡 页面缓存 url重写几读写分离
- 无人机倾斜摄影视频教程
- java中volatile关键字的含义
- Java学习笔记(1)
- websterm快捷键使用记录
- CPU负载
- ThinkPHP中引入七牛SDK