Decorator装饰模式
2024-08-28 17:29:24
动态地给一个对象增加一些额外的职责。就增加功能而言,Decorator模式比生成子类更为灵活。
——《设计模式》GoF
作用:在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
比如,我们现在想设计一个日志类,记录DB日志(或文本日志),要求能够对日志的优先级 和 错误级别进行记录。
也就是对这个日志类添加了记录错误级别 和 优先级的功能。后续还可能增加其他的功能。
public interface Log {
public void write(String logContent);
}
public class DatabaseLog implements Log{ @Override
public void write(String logContent) {
System.out.println("记录DB-Log:" + logContent);
} }
public class TextFileLog implements Log{ @Override
public void write(String logContent) {
System.out.println("记录TextFile-Log:" + logContent);
} }
用于给日志类添加新功能的LogWrapper类:
public abstract class LogWrapper implements Log{
protected Log log; @Override
public void write(String logContent) {
log.write(logContent);
} }
public class LogErrorWrapper extends LogWrapper{
private String errorLevel; public LogErrorWrapper(Log log) {
super();
this.log = log;
} public String getErrorLevel() {
return errorLevel;
} public void setErrorLevel(String errorLevel) {
this.errorLevel = errorLevel;
} @Override
public void write(String logContent) {
logErrorLevel(errorLevel);
super.write(logContent);
} private void logErrorLevel(String errorLevel) {
System.out.println("错误级别:" + errorLevel);
} }
public class LogPriorityWrapper extends LogWrapper{
private String priority; public LogPriorityWrapper(Log log) {
super();
this.log = log;
} public String getPriority() {
return priority;
} public void setPriority(String priority) {
this.priority = priority;
} @Override
public void write(String logContent) {
logPriority(priority);
super.write(logContent);
} private void logPriority(String priority) {
System.out.println("优先级:" + priority);
} }
客户端调用:
public class Client { public static void main(String[] args) {
Log log = new DatabaseLog(); // DB-log
LogErrorWrapper errorWrapper = new LogErrorWrapper(log);// 1级错误级别 DB-log
LogPriorityWrapper priorityWrapper = new LogPriorityWrapper(errorWrapper); // 特别优先 1级错误级别 DB-log errorWrapper.setErrorLevel("1级错误");
priorityWrapper.setPriority("特别优先"); priorityWrapper.write("Hello World!");
}
}
输出结果:
优先级:特别优先
错误级别:1级错误
记录DB-Log:Hello World!
从上面的代码,我们可以看出,DatabaseLog类只拥有最简单的日志打印功能,而LogWrapper类实现了Log且持有Log的引用,而LogWrapper的子类对Log的功能进行了不同的扩展。而且这些扩展的功能对Log是完全透明的。
从调用处,我们可以看到,在LogWrapper(Decorator)子类的构造器中,我们除了传入Log的子类外,同样可以传入LogWrapper自己的子类,这样装饰的功能就能够进行叠加。这也是为什么我们让Decorator抽象类实现Log接口的原因。
因此,如果现在需要加一个功能,我们只需要添加一个功能的装饰子类就可以了,不需要添加其它的子类。它好就好在拥有运行时的灵活性,可以在需要用时随意组合功能,而不需要静态地把各种功能组合写死在代码中。
最新文章
- while用法一例
- IO(四)----对象的序列化
- svn做目录访问控制(AuthzSVNAccessFile)
- 团队开发——冲刺2.a
- C# 截取带路径的文件名字,扩展名,等等 的几种方法
- 全代码实现ios-3
- mkimage command not found
- 上下切换js
- HBase 简介(强烈推荐看)
- Webform用户控件
- Android源码编译常见错误(持续更新)
- 【Django】django 的request和response(转)
- poj2828(线段树查找序列第k小的值)
- 以太坊智能合约介绍,Solidity介绍
- Linux系统(X64)7 安装Oracle11g完整安装图文教程另附基本操作
- 自学之jQuery
- Docker在windows7上的安装
- PHP 传值操作和传地址操作
- Android -- AudioPlayer
- vue.js中请求数据v-for循环使用数据