`
runfeel
  • 浏览: 904406 次
文章分类
社区版块
存档分类
最新评论

请求发送者与接收者解耦——命令模式(五)

 
阅读更多

6 请求日志

请求日志就是将请求的历史记录保存下来,通常以日志文件(Log File)的形式永久存储在计算机中。很多系统都提供了日志文件,例如Windows日志文件、Oracle日志文件等,日志文件可以记录用户对系统的一些操作(例如对数据的更改)。请求日志文件可以实现很多功能,常用功能如下:

(1) “天有不测风云”,一旦系统发生故障,日志文件可以为系统提供一种恢复机制,在请求日志文件中可以记录用户对系统的每一步操作,从而让系统能够顺利恢复到某一个特定的状态;

(2) 请求日志也可以用于实现批处理,在一个请求日志文件中可以存储一系列命令对象,例如一个命令队列;

(3) 可以将命令队列中的所有命令对象都存储在一个日志文件中,每执行一个命令则从日志文件中删除一个对应的命令对象,防止因为断电或者系统重启等原因造成请求丢失,而且可以避免重新发送全部请求时造成某些命令的重复执行,只需读取请求日志文件,再继续执行文件中剩余的命令即可。

在实现请求日志时,我们可以将命令对象通过序列化写到日志文件中,此时命令类必须实现java.io.Serializable接口。下面我们通过一个简单实例来说明日志文件的用途以及如何实现请求日志:

Sunny软件公司开发了一个网站配置文件管理工具,可以通过一个可视化界面对网站配置文件进行增删改等操作,该工具使用命令模式进行设计,结构如图6所示:

6 网站配置文件管理工具结构图

现在Sunny软件公司开发人员希望将对配置文件的操作请求记录在日志文件中,如果网站重新部署,只需要执行保存在日志文件中的命令对象即可修改配置文件。

本实例完整代码如下所示:

import java.io.*;
import java.util.*;

//抽象命令类,由于需要将命令对象写入文件,因此它实现了Serializable接口
abstract class Command implements Serializable {
	protected String name; //命令名称
	protected String args; //命令参数
	protected ConfigOperator configOperator; //维持对接收者对象的引用
	
	public Command(String name) {
		this.name = name;
	}
	
	public String getName() {
		return this.name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public void setConfigOperator(ConfigOperator configOperator) {
		this.configOperator = configOperator;
	}
	
    //声明两个抽象的执行方法execute()
	public abstract void execute(String args);
	public abstract void execute();
}

//增加命令类:具体命令
class InsertCommand extends Command {
	public InsertCommand(String name) {
		super(name);
	}
	
	public void execute(String args) {
		this.args = args;
		configOperator.insert(args);
	}
	
	public void execute() {
		configOperator.insert(this.args);
	}
}

//修改命令类:具体命令
class ModifyCommand extends Command {
	public ModifyCommand(String name) {
		super(name);
	}
	
	public void execute(String args) {
		this.args = args;
		configOperator.modify(args);
	}
	
	public void execute() {
		configOperator.modify(this.args);
	}
}

//省略了删除命令类DeleteCommand

//配置文件操作类:请求接收者。由于ConfigOperator类的对象是Command的成员对象,它也将随Command对象一起写入文件,因此ConfigOperator也需要实现Serializable接口
class ConfigOperator implements Serializable {
	public void insert(String args) {
		System.out.println("增加新节点:" + args);
	}
	
	public void modify(String args) {
		System.out.println("修改节点:" + args);
	}
	
	public void delete(String args) {
		System.out.println("删除节点:" + args);
	}
}

//配置文件设置窗口类:请求发送者
class ConfigSettingWindow {
    //定义一个集合来存储每一次操作时的命令对象
	private ArrayList<Command> commands = new ArrayList<Command>();
	private Command command; 

    //注入具体命令对象
	public void setCommand(Command command) {
		this.command = command;
	}
	
    //执行配置文件修改命令,同时将命令对象添加到命令集合中
	public void call(String args) {
		command.execute(args);
		commands.add(command);
	}
	
    //记录请求日志,生成日志文件,将命令集合写入日志文件
	public void save() {
		FileUtil.writeCommands(commands);
	}
	
    //从日志文件中提取命令集合,并循环调用每一个命令对象的execute()方法来实现配置文件的重新设置
	public void recover() {
		ArrayList list;
		list = FileUtil.readCommands();
		
		for (Object obj : list) {
			((Command)obj).execute();
		}
	}
}

//工具类:文件操作类
class FileUtil {
    //将命令集合写入日志文件
	public static void writeCommands(ArrayList commands) {
		try {
			FileOutputStream file = new FileOutputStream("config.log");
			//创建对象输出流用于将对象写入到文件中
    		ObjectOutputStream objout = new ObjectOutputStream(new BufferedOutputStream(file));
			//将对象写入文件
    		objout.writeObject(commands);
    		objout.close();
    		}
    	catch(Exception e) {
    			System.out.println("命令保存失败!");	
    			e.printStackTrace();
    	    }
	}
	
    //从日志文件中提取命令集合
	public static ArrayList readCommands() {
		try {
			FileInputStream file = new FileInputStream("config.log");
			//创建对象输入流用于从文件中读取对象
    		ObjectInputStream objin = new ObjectInputStream(new BufferedInputStream(file));
			
			//将文件中的对象读出并转换为ArrayList类型
    		ArrayList commands = (ArrayList)objin.readObject();
    		objin.close();
    		return commands;
    		}
    	catch(Exception e) {
    			System.out.println("命令读取失败!");
    			e.printStackTrace();
    			return null;	
    	    }		
	}
}

编写如下客户端测试代码:

class Client {
	public static void main(String args[]) {
		ConfigSettingWindow csw = new ConfigSettingWindow(); //定义请求发送者
		Command command; //定义命令对象
		ConfigOperator co = new ConfigOperator(); //定义请求接收者
		
        //四次对配置文件的更改
		command = new InsertCommand("增加");
		command.setConfigOperator(co);
		csw.setCommand(command);
		csw.call("网站首页");
		
		command = new InsertCommand("增加");
		command.setConfigOperator(co);
		csw.setCommand(command);
		csw.call("端口号");
		
		command = new ModifyCommand("修改");
		command.setConfigOperator(co);
		csw.setCommand(command);
		csw.call("网站首页");
		
		command = new ModifyCommand("修改");
		command.setConfigOperator(co);
		csw.setCommand(command);		
		csw.call("端口号");
		
		System.out.println("----------------------------");
		System.out.println("保存配置");
		csw.save();
			
		System.out.println("----------------------------");	
		System.out.println("恢复配置");
		System.out.println("----------------------------");	
		csw.recover();	
	}
}

编译并运行程序,输出结果如下:

增加新节点:网站首页

增加新节点:端口号

修改节点:网站首页

修改节点:端口号

----------------------------

保存配置

----------------------------

恢复配置

----------------------------

增加新节点:网站首页

增加新节点:端口号

修改节点:网站首页

修改节点:端口号

【作者:刘伟 http://blog.csdn.net/lovelion

分享到:
评论

相关推荐

    design-pattern-java.pdf

    请求发送者与接收者解耦——命令模式(二) 请求发送者与接收者解耦——命令模式(三) 请求发送者与接收者解耦——命令模式(四) 请求发送者与接收者解耦——命令模式(五) 请求发送者与接收者解耦——命令模式...

    Java设计模式 版本2

    设计模式之代理模式,请求的链式处理——职责链模式,请求发送者与接收者解耦——命令模式,自定义语言的实现——解释器模式,遍历聚合对象中的元素——迭代器模式,协调多个对象之间的交互——中介者模式,撤销功能...

    责任链模式

    这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。 在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给...

    设计模式可复用面向对象软件的基础.zip

    5.12.4 对发送者和接收者解耦 229 5.12.5 总结 231 第6章 结论 232 6.1 设计模式将带来什么 232 6.2 一套通用的设计词汇 232 6.3 书写文档和学习的辅助手段 232 6.4 现有方法的一种补充 233 6.5 重构的目标 233 6.6 ...

    23种设计模式入门到精通详解.txt

    单例模式:某个类只能有一个实例,提供一个全局的...责任链模式:将请求的发送者和接收者解耦,使的多个对象都有处理这个请求的机会。 迭代器模式:一种遍历访问聚合对象中各个元素的方法,不暴露该对象的内部结构。

    php设计模式之职责链模式定义与用法经典示例

    这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。 在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给...

    C#设计模式之行为型模式详解

    责任链模式:为请求创建一个接收者对象的链,对请求的发送者和接收者进行解耦,大部分用于web中吧。。 Task中的continuewith和微软的tpl数据流应该是类似这种模式的实现吧 using System; using System.Collections...

    《设计模式》中文版(23个设计模式的介绍与运用)

    5.12.4 对发送者和接收者解耦 229 5.12.5 总结 231 第6章 结论 232 6.1 设计模式将带来什么 232 6.2 一套通用的设计词汇 232 6.3 书写文档和学习的辅助手段 232 6.4 现有方法的一种补充 233 6.5 重构的目标 233 6.6 ...

    设计模式--C++

    5.12.4 对发送者和接收者解耦 229 5.12.5 总结 231 第 6 章 结论 232 6.1 设计模式将带来什么 2326.2 一套通用的设计词汇 232 6.3 书写文档和学习的辅助手段 232 6.4 现有方法的一种补充 233 6.5 重构的目标 233 6.6...

    GOLF设计模式(C++语言版)

    5.12.4 对发送者和接收者解耦 229 5.12.5 总结 231 第6章 结论 232 6.1 设计模式将带来什么 232 6.2 一套通用的设计词汇 232 6.3 书写文档和学习的辅助手段 232 6.4 现有方法的一种补充 233 6.5 重构的目标 ...

    设计模式(.PDF)

    5.12.4 对发送者和接收者解耦 229 5.12.5 总结 231 第6章 结论 232 6.1 设计模式将带来什么 232 6.2 一套通用的设计词汇 232 6.3 书写文档和学习的辅助手段 232 6.4 现有方法的一种补充 233 6.5 重构的目标 233 6.6 ...

    Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides23种设计模式

    5.12.4 对发送者和接收者解耦 229 5.12.5 总结 231 第6章 结论 232 6.1 设计模式将带来什么 232 6.2 一套通用的设计词汇 232 6.3 书写文档和学习的辅助手段 232 6.4 现有方法的一种补充 233 6.5 重构的目标 233 6.6 ...

    《国外写的,翻译版本》设计模式

    5.12.4 对发送者和接收者解耦 229 5.12.5 总结 231 第6章 结论 232 6.1 设计模式将带来什么 232 6.2 一套通用的设计词汇 232 6.3 书写文档和学习的辅助手段 232 6.4 现有方法的一种补充 233 6.5 重构的目标 233 6.6 ...

    设计模式文档

    5.12.4 对发送者和接收者解耦 229 5.12.5 总结 231 第6章 结论 232 6.1 设计模式将带来什么 232 6.2 一套通用的设计词汇 232 6.3 书写文档和学习的辅助手段 232 6.4 现有方法的一种补充 233 6.5 重构的目标 233 6.6 ...

    RxBus:RxBus for Android,通过RxBus来实现事件的通知和订阅,简化应用组件间的通信,解耦事件的发送者和接收者,避免复杂和容易出错的依赖和生命周期的问题

    RxBus for Android通过RxBus来实现事件的通知和订阅,简化应用组件间的通信,解耦事件的发送者和接收者,避免复杂和容易出错的依赖和生命周期的问题.1.依赖方式Dependency1.1Maven&lt;dependency&gt; &lt;groupId&gt;...

    设计模式 design pattern

    5.12.4 对发送者和接收者解耦 229 5.12.5 总结 231 第6章 结论 232 6.1 设计模式将带来什么 232 6.2 一套通用的设计词汇 232 6.3 书写文档和学习的辅助手段 232 6.4 现有方法的一种补充 233 6.5 重构的目标 233 6.6 ...

    JAVA经典设计模式大全

    5.12.4 对发送者和接收者解耦 229 5.12.5 总结 231 第6章 结论 232 6.1 设计模式将带来什么 232 6.2 一套通用的设计词汇 232 6.3 书写文档和学习的辅助手段 232 6.4 现有方法的一种补充 233 6.5 重构的目标 ...

    设计模式___

    5.12.4 对发送者和接收者解耦 229 5.12.5 总结 231 第6章 结论 232 6.1 设计模式将带来什么 232 6.2 一套通用的设计词汇 232 6.3 书写文档和学习的辅助手段 232 6.4 现有方法的一种补充 233 6.5 重构的目标 233 6.6 ...

    设计模式(Design.Patterns.CHN)

    5.12.4 对发送者和接收者解耦 229 5.12.5 总结 231 第6章 结论 232 6.1 设计模式将带来什么 232 6.2 一套通用的设计词汇 232 6.3 书写文档和学习的辅助手段 232 6.4 现有方法的一种补充 233 6.5 重构的目标 233 6.6 ...

    软件设计师必读的书-设计模式

    5.12.4 对发送者和接收者解耦 229 5.12.5 总结 231 第6章 结论 232 6.1 设计模式将带来什么 232 6.2 一套通用的设计词汇 232 6.3 书写文档和学习的辅助手段 232 6.4 现有方法的一种补充 233 6.5 重构的目标 233 6.6 ...

Global site tag (gtag.js) - Google Analytics