给类添加额外职责
- 概念
- 类图
- 代码实例
概念
如果想要给类添加其他逻辑的话,在不改动原来核心功能的情况下,采用装饰者模式,可以动态设定,并且按照想要的顺序来装饰核心功能。满足了开闭原则,如果增加修饰功能只需要扩展抽象装饰类就可以。
例如:人"类"尤其是女性,会使用各种装扮的方式打扮自己,而人的初始容貌是核心功能,可以使用靓丽的衣服或美白化妆品(装饰类)来修饰自己的容貌。
类图
Component:抽象装饰对象
ConcreteComponent:具体的装饰对象
Decorator:抽象装饰类
ConcreteDecorator:具体装饰类
代码实例
场景:
在持久化数据之前进行过滤掉敏感词,以及需要进行加密。 这可以看着是对持久化数据功能进行装饰,因此可以采用装饰者模式,加密装饰器和过滤装饰器,原来持久化的逻辑并不需要改动,这里需要注意修饰的顺序 过滤功能一定是在加密功能之前发生的。
PersistData 接口(Component)
/**
* @author duanyimiao
* @create 2018-09-14 11:54 PM
* @description 持久化数据接口 == Component
**/
public interface PersistData {
boolean persist(String data);
}
PersistDataImpl 具体装饰对象(ConcreteComponent)
/**
* @author duanyimiao
* @create 2018-09-14 11:56 PM
* @description 具体持久化数据的实现 == ConcreteComponent
**/
public class PersistDataImpl implements PersistData {
@Override
public boolean persist(String data) {
System.out.println("persist to database data = "+data);
return true;
}
}
AbstractDecorator 抽象装饰类(Decorator)
/**
* @author duanyimiao
* @create 2018-09-15 12:02 AM
* @description 抽象装饰器 == Decorator
**/
public abstract class AbstractDecorator implements PersistData {
private PersistData persistData;
public void setDecorator(PersistData persistData) {
this.persistData = persistData;
}
@Override
public boolean persist(String data) {
if (persistData != null) {
return persistData.persist(data);
}
return false;
}
}
SensitiveWordFilter 具体装饰类(ConcreteDecorator1)
/**
* @author duanyimiao
* @create 2018-09-15 12:05 AM
* @description 对敏感词进行过滤 == ConcreteDecorator1
**/
public class SensitiveWordFilter extends AbstractDecorator{
private final static String sensitiveWords = "tmd";
@Override
public boolean persist(String data) {
data = data.replace(sensitiveWords,"***");
super.persist(data);
return true;
}
}
EncryptData 具体装饰类(ConcreteDecorator2)
/**
* @author duanyimiao
* @create 2018-09-15 12:06 AM
* @description 对数据进行加密 == ConcreteDecorator2
**/
public class EncryptData extends AbstractDecorator{
@Override
public boolean persist(String data) {
data = data+" been encrypted";
super.persist(data);
return true;
}
}
MainTest 测试类
/**
* @author duanyimiao
* @create 2018-09-15 12:11 AM
* @description
**/
public class MainTest {
public static void main(String[] args) {
PersistData persistData = new PersistDataImpl();
AbstractDecorator encryptData = new EncryptData();
AbstractDecorator filterWords = new SensitiveWordFilter();
encryptData.setDecorator(persistData);
filterWords.setDecorator(encryptData);
//以上的顺序如果颠倒了,就会导致先进行加密再进行过滤,最后持久会,这不符合逻辑
filterWords.persist("tmd nihao tmd");
}
}
输出结果:
persist to database data = *** nihao *** been encrypted