标签:装饰者模式
关于日志消息,我们需要将其输出到屏幕或者是日志文档内,于是我们会写几个类:
但是问题在于,如果我们要对这两个输出类增加条件,比如“将信息转为大写”,“将信息转换成html格式输出”,那么两个类都要被该写成四个类才满足需求。如果要求更多,那么类的数目增加的会非常快。此时应该使用装饰者模式。
import java.io.*;
import java.util.*;
//接口ILogger
interface ILogger{
void log(String msg);//抽象的输出方法,但是未指定输出位置,由其相应的实现类来决定
}
//ConsoleLogger,实现了接口,用于将信息输出到屏幕
class ConsoleLogger implements ILogger{
public void log(String msg){
System.out.println(msg);
}
}
//FileLogger,实现了接口,用于将信息输出到日志文件
class FileLogger implements ILogger{
public void log(String msg){
DataOutputStream dos = null;
try{
dos = new DataOutputStream(new FileOutputStream("/home/lpp/tmp/log.txt", true));
dos.writeBytes(msg + "\n");
dos.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
//抽象类Decorator,实现了接口ILogger
//实现接口的原因:虽然需求分析变化了,但无论怎么变,它终究还是一个日志类,所以Decorator要派生自接口ILogger
abstract class Decorator implements ILogger{
protected ILogger logger;
public Decorator(ILogger logger){
this.logger = logger;
}
}
//子类Uplogger,用于将日志信息包装成大写的
class UpLogger extends Decorator{
public UpLogger(ILogger logger){
super(logger);
}
public void log(String msg){
msg = msg.toUpperCase(); //覆写log方法,在其中加入相应的包装语句
logger.log(msg);
}
}
//子类XMLLogger,用于将日志信息包装成html格式写入日志文件
class XMLLogger extends Decorator{
public XMLLogger(ILogger logger){
super(logger);
}
public void log(String msg){
String s = "<msg>\n" +
"<content>" + msg + "</content>\n" +
"<time>" + new Date().toString() + "</time>\n" +
"</msg>\n";
logger.log(s);
}
}
//主类Test
public class Test{
public static void main(String[] args) throws Exception{
// ILogger obj = new FileLogger(); //新建一个FileLogger对象
ILogger obj = new ConsoleLogger(); //新建一个ConsoleLogger对象
ILogger newObj = new XMLLogger(obj); //将对象包装一下
// ILogger newObj = new UpLogger(obj); //包装对象
String s[] = {"how", "are", "you"}; //待处理的信息
for(int i = 0; i < s.length; i++){
newObj.log(s[i]); //调用包装后的对象,输出包装后的信息到相应位置
Thread.sleep(1000);
}
System.out.println("End");
}
}
通过包装,再进行增加了特定功能的特定输出就会变得非常简单!
标签:装饰者模式
原文地址:http://blog.csdn.net/puppylpg/article/details/46443533