目录
一、装饰器模式介绍
1.1 装饰器模式定义
1.2 装饰器模式原理
1.2.1 模式类图
1.2.2 模式角色说明
1.2.3 举例代码
二、装饰器模式的应用
2.1 需求说明
2.2 需求实现
2.2.1 类图
2.2.2 类图说明
2.2.3 具体实现
2.2.3.1 DataLoader类
2.2.3.2 BaseFileDataLoader类
2.2.3.3 DataLoaderDecorator类
2.2.3.4 EncryptionDataDecorator
2.2.3.5 TestDecorator测试类
三、装饰器模式总结
3.1 装饰器模式优点
3.2 装饰器模式缺点
3.3 装饰器模式适用场景
装饰模式(decorator pattern) 的原始定义是:动态的给一个对象添加一些额外的职责。就扩展功能而言,装饰器模式提供了一种比使用子类更加灵活的替代方案。
假设现在有有一块蛋糕,如果只有涂上奶油那这个蛋糕就是普通的奶油蛋糕,这时如果我们添加上一些蓝莓,那这个蛋糕就是蓝莓蛋糕。如果我们再拿一块黑巧克力 然后写上姓名、插上代表年龄的蜡烛,这就是变成了一块生日蛋糕。
在软件设计中,装饰器模式是一种用于替代继承的技术,它通过一种无须定义子类的方式给对象动态的增加职责,使用对象之间的关联关系取代类之间的继承关系。
装饰(Decorator)模式中的角色:
package main.java.cn.test.decorator.V1;
/**
* @author ningzhaosheng
* @date 2024/1/12 18:46:19
* @description 抽象构件类
*/
public abstract class Component {
//抽象方法
public abstract void operation();
}
package main.java.cn.test.decorator.V1;
/**
* @author ningzhaosheng
* @date 2024/1/12 18:46:54
* @description 具体构建类
*/
public class ConcreteComponent extends Component{
@Override
public void operation() {
//基础功能实现(复杂功能通过装饰类进行扩展)
}
}
package main.java.cn.test.decorator.V1;
/**
* @author ningzhaosheng
* @date 2024/1/12 18:47:38
* @description 抽象装饰类-装饰者模式的核心
*/
public class Decorator extends Component {
//维持一个对抽象构件对象的引用
private Component component;
//注入一个抽象构件类型的对象
public Decorator(Component component) {
this.component = component;
}
@Override
public void operation() {
//调用原有业务方法(这里并没有真正实施装饰,而是提供了一个统一的接口,将装饰过程交给子类完成)
component.operation();
}
}
package main.java.cn.test.decorator.V1;
/**
* @author ningzhaosheng
* @date 2024/1/12 18:48:48
* @description 具体装饰类
*/
public class ConcreteDecorator extends Decorator {
public ConcreteDecorator(Component component) {
super(component);
}
@Override
public void operation() {
super.operation(); //调用原有业务方法
addedBehavior(); //调用新增业务方法
}
//新增业务方法
public void addedBehavior() {
//......
}
}
我们以一个文件读写器程序为例, 演示一下装饰者模式的使用。
抽象的文件读取接口DataLoader
具体组件BaseFileDataLoader,重写组件 DataLoader 的读写方法
装饰器DataLoaderDecorator,这里要包含一个引用 DataLoader 的对象实例 wrapper,同样是重写 DataLoader 方法,不过这里使用wrapper 来读写,并不进行扩展。
读写时有加解密功能的具体装饰器EncryptionDataDecorator,它继承了装饰器 DataLoaderDecorator 重写读写方法。
package main.java.cn.test.decorator.V2;
/**
* @author ningzhaosheng
* @date 2024/1/12 18:28:43
* @description 抽象的文件读取接口DataLoader
*/
public interface DataLoader {
String read();
void write(String data);
}
package main.java.cn.test.decorator.V2;
import java.io.File;
import java.io.IOException;
/**
* @author ningzhaosheng
* @date 2024/1/12 18:29:10
* @description 具体实现组件, 重写读写方法
*/
public class BaseFileDataLoader implements DataLoader {
private String filePath;
public BaseFileDataLoader(String filePath) {
this.filePath = filePath;
}
@Override
public String read() {
try {
String result = FileUtils.readFileToString(new
File(filePath), "utf-8");
return result;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
@Override
public void write(String data) {
try {
FileUtils.writeStringToFile(new File(filePath),
data, "utf-8");
} catch (IOException e) {
e.printStackTrace();
}
}
}
package main.java.cn.test.decorator.V2;
/**
* @author ningzhaosheng
* @date 2024/1/12 18:33:23
* @description 装抽象饰者类
*/
public class DataLoaderDecorator implements DataLoader {
private DataLoader wrapper;
public DataLoaderDecorator(DataLoader wrapper) {
this.wrapper = wrapper;
}
@Override
public String read() {
return wrapper.read();
}
@Override
public void write(String data) {
wrapper.write(data);
}
}
package main.java.cn.test.decorator.V2;
import java.util.Base64;
/**
* @author ningzhaosheng
* @date 2024/1/12 18:34:28
* @description 具体装饰者-对文件内容进行加密和解密
*/
public class EncryptionDataDecorator extends DataLoaderDecorator {
public EncryptionDataDecorator(DataLoader wrapper) {
super(wrapper);
}
@Override
public String read() {
return decode(super.read());
}
@Override
public void write(String data) {
super.write(encode(data));
}
//加密操作
private String encode(String data) {
try {
Base64.Encoder encoder = Base64.getEncoder();
byte[] bytes = data.getBytes("UTF-8");
String result = encoder.encodeToString(bytes);
return result;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
//解密
private String decode(String data) {
try {
Base64.Decoder decoder = Base64.getDecoder();
String result = new String(decoder.decode(data),
"UTF-8");
return result;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
package main.java.cn.test.decorator.V2;
/**
* @author ningzhaosheng
* @date 2024/1/12 18:36:41
* @description 测试类
*/
public class TestDecorator {
public static void main(String[] args) {
String info = "name:tom,age:15";
DataLoaderDecorator decorator = new
EncryptionDataDecorator(new BaseFileDataLoader("demo.txt"));
decorator.write(info);
String data = decorator.read();
System.out.println(data);
}
}
好了,本次分享就到这里,欢迎大家继续阅读《设计模式》专栏其他设计模式内容,如果有帮助到大家,欢迎大家点赞+关注+收藏,有疑问也欢迎大家评论留言!