这是我参与8月更文挑战的第2天,活动详情查看:8月更文挑战
基础概念
- Component:组件接口,定义了全部组件实现类以及所有装饰器实现的行为
- ConcreteComponent:具体组件实现类)
- Decorator:装饰器,实现了Component的抽象类,内部封装了一个Component对象,方便组合及复用
- ConcreteDecorator:具体装饰器实现类,对某些功能进行增强。
优点
- 灵活性和可扩展性较强,通过装饰器的动态组合,实现不同的需求
- 添加新需求,添加装饰器即可
缺点
- 新需求一旦很多,如果出现嵌套多层的装饰器,就很难维护
代码示例
- Component&ConcreteComponent
//Component
public interface Animal {
void run();
}
//ConcreteComponent
public class People implements Animal {
@Override
public void run() {
System.out.println("people run");
}
}
//ConcreteComponent
public class Tiger implements Animal{
@Override
public void run() {
System.out.println("tiger run");
}
}
- Decorator
//Decorator
public abstract class AnimalDecorator implements Animal {
protected Animal decoratorAnimal;
public AnimalDecorator(Animal decoratorAnimal){
this.decoratorAnimal=decoratorAnimal;
}
@Override
public void run(){
decoratorAnimal.run();
}
}
- ConcreteDecorator
public class AllAnimalDecorator extends AnimalDecorator {
public AllAnimalDecorator(Animal decoratorAnimal) {
super(decoratorAnimal);
}
@Override
public void run(){
decoratorAnimal.run();
doOtherThing();
}
private void doOtherThing(){
System.out.println("im shout");
}
}
Mybatis中的应用
Mybatis中则是省去了Decorator,直接由实现类完成。
这里面
org.apache.ibatis.cache.Cache接口定义了必要的功能(对应Component),其中,除了org.apache.ibatis.cache.impl.PerpetualCache其他基本上都可以看作是装饰器实现类(ConcreteDecorator)。
public class PerpetualCache implements Cache {
private final String id;
private final Map<Object, Object> cache = new HashMap<>();
public PerpetualCache(String id) {
this.id = id;
}
@Override
public String getId() {
return id;
}
@Override
public int getSize() {
return cache.size();
}
@Override
public void putObject(Object key, Object value) {
cache.put(key, value);
}
@Override
public Object getObject(Object key) {
return cache.get(key);
}
@Override
public Object removeObject(Object key) {
return cache.remove(key);
}
@Override
public void clear() {
cache.clear();
}
@Override
public boolean equals(Object o) {
if (getId() == null) {
throw new CacheException("Cache instances require an ID.");
}
if (this == o) {
return true;
}
if (!(o instanceof Cache)) {
return false;
}
Cache otherCache = (Cache) o;
return getId().equals(otherCache.getId());
}
@Override
public int hashCode() {
if (getId() == null) {
throw new CacheException("Cache instances require an ID.");
}
return getId().hashCode();
}
}
其他都大体相同,随便挑一个举例
public class WeakCache implements Cache {
//强引用集合,避免垃圾回收
private final Deque<Object> hardLinksToAvoidGarbageCollection;
//被GC的对象保存进这个队列中
private final ReferenceQueue<Object> queueOfGarbageCollectedEntries;
private final Cache delegate;
private int numberOfHardLinks;
public WeakCache(Cache delegate) {
this.delegate = delegate;
this.numberOfHardLinks = 256;
this.hardLinksToAvoidGarbageCollection = new LinkedList<>();
this.queueOfGarbageCollectedEntries = new ReferenceQueue<>();
}
@Override
public String getId() {
return delegate.getId();
}
@Override
public int getSize() {
removeGarbageCollectedItems();
return delegate.getSize();
}
public void setSize(int size) {
this.numberOfHardLinks = size;
}
@Override
public void putObject(Object key, Object value) {
removeGarbageCollectedItems();
delegate.putObject(key, new WeakEntry(key, value, queueOfGarbageCollectedEntries));
}
@Override
public Object getObject(Object key) {
Object result = null;
@SuppressWarnings("unchecked") // assumed delegate cache is totally managed by this cache
WeakReference<Object> weakReference = (WeakReference<Object>) delegate.getObject(key);
if (weakReference != null) {
result = weakReference.get();
if (result == null) {
delegate.removeObject(key);
} else {
synchronized (hardLinksToAvoidGarbageCollection) {
//如果用到了就使用强引用集合保存下来
hardLinksToAvoidGarbageCollection.addFirst(result);
if (hardLinksToAvoidGarbageCollection.size() > numberOfHardLinks) {
//满了删除最老的
hardLinksToAvoidGarbageCollection.removeLast();
}
}
}
}
return result;
}
@Override
public Object removeObject(Object key) {
removeGarbageCollectedItems();
return delegate.removeObject(key);
}
@Override
public void clear() {
synchronized (hardLinksToAvoidGarbageCollection) {
hardLinksToAvoidGarbageCollection.clear();
}
removeGarbageCollectedItems();
delegate.clear();
}
//删除被GC的对象
private void removeGarbageCollectedItems() {
WeakEntry sv;
while ((sv = (WeakEntry) queueOfGarbageCollectedEntries.poll()) != null) {
delegate.removeObject(sv.key);
}
}
//继承弱引用,缓存的是这个对象
private static class WeakEntry extends WeakReference<Object> {
private final Object key;
//GC的时候会添加进队列中
private WeakEntry(Object key, Object value, ReferenceQueue<Object> garbageCollectionQueue) {
super(value, garbageCollectionQueue);
this.key = key;
}
}
}