设计模式实例——基于命令模式的事件处理框架
来源:互联网 发布:园林设计效果图软件 编辑:程序博客网 时间:2024/06/05 21:06
在面向对象程序设计中,命令模式是一种很常用的模式。
定义:通常情况下,行为的发送者与接收者之间是一种紧耦合,命令模式就是将一组行为封装成对象,实现二者之间的松耦合。
角色定义:
Command:命令封装对象,可以在其中存储一些有关行为信息和数据。
Invoker:实际的命令发送者,它相当于一个调度中心。
Receiver:事件的接收者,也就是实际做事的那个对象。
Client:客户端,它创建出命令。
今天我们基于命令模式来做一个简单的事件处理模型。总体思路就是用一个队列去保存这些命令,然后有一个线程去检测这个队列,当这个队列中有命令时,则取出来实现它。
首先,我们新建一个Command的接口
public interface ICommand { void execute();}
然后再定义一个Receiver,实际做工作的那个对象。这个类有两个行为,一个是上传文件,一个是获取网络数据。
public class HttpWorker extends Worker{ public void uploadFile() { System.out.println("HttpWorker->uploadFile"); } public void getNetworkData() { System.out.println("HttpWorker->getNetworkData"); }}
public abstract class HttpCommand implements ICommand{ protected HttpWorker httpWorker; public HttpCommand() { super(); httpWorker = new HttpWorker(); }}
public class UploadFileCommand extends HttpCommand { @Override public void execute() { httpWorker.uploadFile(); }}
public class GetNetworkDataCommand extends HttpCommand { @Override public void execute() { httpWorker.getNetworkData(); }}
public class EventWorker { private Queue<ICommand> commandQueue; private WorkerThread workerThread; private Object lock; public void start() { lock = new Object(); commandQueue = new LinkedBlockingQueue<>(); workerThread = new WorkerThread(); workerThread.start(); } public void add(ICommand command) { synchronized (commandQueue) { System.out.println("add a command"); commandQueue.add(command); synchronized (lock) { lock.notify(); } } } public void remove(ICommand command) { synchronized (commandQueue) { commandQueue.remove(command); } } public void stop() { workerThread.setStart(false); //在停止的时候,有可能工作线程在等待,所以要notify一下 synchronized (lock) { lock.notify(); } commandQueue.clear(); commandQueue = null; workerThread = null; lock = null; } private class WorkerThread extends Thread { private boolean isStart = false; public void setStart(boolean b) { isStart = b; } @Override public synchronized void start() { isStart = true; super.start(); } //这种写法会出现死锁,注意!!!// public void run() {// System.out.println("EventWorkerThread work!");// while(true) {// synchronized (commandQueue) {// if(!isStart) break;// if(commandQueue.isEmpty()) {// System.out.println("queue is empty->wait\n\n");// synchronized (lock) {// try {// lock.wait();// } catch (InterruptedException e) {// e.printStackTrace();// }// }// } else {//// ICommand c = commandQueue.poll();// if(c != null) {// c.execute();// }// }// }// }// System.out.println("EventWorkerThread stop!");// } public void run() { System.out.println("EventWorkerThread work!"); while(true) { //如果停止循环则退出 if(!isStart) break; //线程同步,先获取commandQueue的锁 synchronized (commandQueue) { //如果命令队列不为空,则取出顶部的消息 if(!commandQueue.isEmpty()) { ICommand c = commandQueue.poll(); if(c != null) { c.execute(); } //继续循环 continue; } } //如果队列为空,是进行等待 synchronized (lock) { try { System.out.println("queue is empty->wait\n\n"); lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } System.out.println("EventWorkerThread stop!"); } }}
上面主要的代码都做了注释,大家都能看懂它的工作原理。就是做一个队列,然后有一个线程不停的去检测这个队列,如果有命令就执行,反之,等待。当添加一个命令时,则notify检测线程继续工作。
在多线程中,一定要注意线程的同步,否则会出现脏数据,还有就是锁的运用,不然会出现死锁等一些问题,而且这些问题都不容易查出来,所以在多个线程操作同一个数据时一定要加锁。
下来就是客户端对象,客户端是创建命令的地方。
public class Client { public static void main(String[] args) throws InterruptedException { EventWorker eventWorker = new EventWorker(); eventWorker.start(); ICommand uploadFileCommand = new UploadFileCommand(); ICommand getNetworkDataCommand = new GetNetworkDataCommand(); Thread.sleep(3000); for(int i = 0; i < 10; i++) { if(i % 2 == 0) { eventWorker.add(uploadFileCommand); } else { eventWorker.add(getNetworkDataCommand); } Thread.sleep(2000); } eventWorker.stop(); }}
好了,这个框架就算大概完成了,这只是一个很简单的例子,在实际工作中,可能要比这复杂的多。运用模式可以使我们的代码更加高效和可维护,但是也不要滥用模式,23种设计模式没有谁好谁坏,适合的才是最好的。
1 0
- 设计模式实例——基于命令模式的事件处理框架
- 基于事件的设计模式
- C#中的异步调用及异步设计模式(三)——基于事件的异步模式
- C#中的异步调用及异步设计模式(三)——基于事件的异步模式
- C#中的异步调用及异步设计模式(三)——基于事件的异步模式
- C#中的异步调用及异步设计模式(三)——基于事件的异步模式
- 设计模式—命令模式
- 设计模式—命令模式
- 设计模式—命令模式
- 设计模式—命令模式
- 设计模式——命令设计模式
- JDBC学习之路(五)基于MVC框架的JDBC异常与设计模式处理
- java设计模式----模版模式+内部类+设计时间事件处理框架
- 《GOF设计模式》—原型(Prototype)—Delphi源码示例:基于实例的原型管理器
- Henry手记—使用Template Method设计模式的.NET事件处理机制(一)
- Henry手记—使用Template Method设计模式的.NET事件处理机制(二)
- 基于事件的监听,消息订阅设计模式的实现框架,ERP,OA,复杂,灵活多变的项目的福音
- 每日设计模式——命令模式
- 浅谈sar指令在整数除法中的优化
- Android中的信号强度上报与显示完整流程()
- linux TOP命令详解
- mysq 日期相减
- 100天土鸡饲养计划(70)
- 设计模式实例——基于命令模式的事件处理框架
- mysql数据库分表实现
- CVPR2015跟踪11---CMT跟踪算法分析
- VC++ ^是什么运输符
- 删除数据库的所有表
- Linux后台进程管理以及ctrl+z(挂起)、ctrl+c(中断)、ctrl+\(退出)和ctrl+d(EOF)的区别
- 从今天开始,记录自己学习laravel的过程
- Zend Studio使用教程之在Docker容器中调试PHP Web应用(一)
- 第八周 OJ 打印数字图形