装饰器模式(Decorator)

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。使用场景: 1、扩展一个类的功能。 2、动态增加功能,动态撤销。

下面是自己写的测试demo,非常方便的对原先的CircleShape类进行了增强,同时又不改变其结构。

public class Main {
    public static void main(String[] args) {
        Shape shape = new CircleShape();
        shape = new RedShapeDecorator(shape);
        shape = new BlueShapeDecorator(shape);
        shape.draw();
    }

    public interface Shape {
        void draw();
    }

    public static class CircleShape implements Shape {

        @Override
        public void draw() {
            System.out.println("CircleShape drawing");
        }
    }

    public static abstract class ShapeDecorator implements Shape {
        protected Shape delegate;

        public ShapeDecorator(Shape delegate) {
            this.delegate = delegate;
        }

        @Override
        public void draw() {
            this.delegate.draw();
        }
    }

    public static class RedShapeDecorator extends ShapeDecorator {
        public RedShapeDecorator(Shape shape) {
            super(shape);
        }

        @Override
        public void draw() {
            this.delegate.draw();
            this.setRedBorder(this.delegate);
        }

        private void setRedBorder(Shape decoratedShape) {
            System.out.println("Border Color: Red");
        }
    }

    public static class BlueShapeDecorator extends ShapeDecorator {
        public BlueShapeDecorator(Shape shape) {
            super(shape);
        }

        @Override
        public void draw() {
            this.delegate.draw();
            this.setBlueBorder(this.delegate);
        }

        private void setBlueBorder(Shape decoratedShape) {
            System.out.println("Border Color: Blue");
        }
    }
}

输出结果为

CircleShape drawing
Border Color: Red
Border Color: Blue

阅读mybatis3源代码的时候,其对缓存的处理就使用了装饰器模式,通过对各种模式的缓存进行组合,组装出了非常强大的缓存处理功能,比如使用LoggingCache统计缓存的命中率,SynchronizedCache保证线程的安全性

 private Cache setStandardDecorators(Cache cache) {
    try {
      MetaObject metaCache = SystemMetaObject.forObject(cache);
      if (size != null && metaCache.hasSetter("size")) {
        metaCache.setValue("size", size);
      }
      if (clearInterval != null) {
        cache = new ScheduledCache(cache);
        ((ScheduledCache) cache).setClearInterval(clearInterval);
      }
      if (readWrite) {
        cache = new SerializedCache(cache);
      }
      cache = new LoggingCache(cache);
      cache = new SynchronizedCache(cache);
      if (blocking) {
        cache = new BlockingCache(cache);
      }
      return cache;
    } catch (Exception e) {
      throw new CacheException("Error building standard cache decorators.  Cause: " + e, e);
    }
  }

public class LoggingCache implements Cache {

  private final Log log;
  private final Cache delegate;
  protected int requests = 0;
  protected int hits = 0;

  public LoggingCache(Cache delegate) {
    this.delegate = delegate;
    this.log = LogFactory.getLog(getId());
  }

  @Override
  public String getId() {
    return delegate.getId();
  }

  @Override
  public int getSize() {
    return delegate.getSize();
  }

  @Override
  public void putObject(Object key, Object object) {
    delegate.putObject(key, object);
  }

  @Override
  public Object getObject(Object key) {
    requests++;
    final Object value = delegate.getObject(key);
    if (value != null) {
      hits++;
    }
    if (log.isDebugEnabled()) {
      log.debug("Cache Hit Ratio [" + getId() + "]: " + getHitRatio());
    }
    return value;
  }

  @Override
  public Object removeObject(Object key) {
    return delegate.removeObject(key);
  }

  @Override
  public void clear() {
    delegate.clear();
  }

  @Override
  public int hashCode() {
    return delegate.hashCode();
  }

  @Override
  public boolean equals(Object obj) {
    return delegate.equals(obj);
  }

  private double getHitRatio() {
    return (double) hits / (double) requests;
  }

}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容