11.装饰者模式

目录

1.概念

1.1模式的定义

1.2 优缺点以及使用场景

2. Demo

3.模式在开源软件中的应

3.1java.io.BufferedReader 类

3.2 springframework...TransactionAwareCacheDecorator

3.3 org.apache.ibatis.cache.*.BlockingCache 类


  在现实生活中,常常需要对现有产品增加新的功能或美化其外观,如房子装修、相片加相框等。在软件开发过程中,有时想用一些现存的组件。这些组件可能只是完成了一些核心功能。但在不改变其结构的情况下,可以动态地扩展其功能。所有这些都可以釆用装饰模式来实现。

1.概念

1.1模式的定义

装饰者模式(Decorator):在不改变现有对象结构的情况下,动态的给该对象增加一些指责(即增加额外功能)。装饰者模式提供了比继承更有弹性的替代方案(扩展原有对象的功能)。

1.2 优缺点以及使用场景

优点:

  1. 继承的有力补充,比继承灵活,在不改变原有对象的情况下给对象扩展功能;
  2. 通过使用不同的装饰类以及这些装饰类的排列组合,可以实现不同的效果;
  3. 符合开闭原则。

缺点:

  1. 会出现更多的代码,更多的类,增加程序的复杂性;
  2. 动态装饰时,多层装饰时会更复杂。

使用场景:
  1. 扩展一个类的功能或给一个类添加附加职责时;
  2. 动态的给一个对象添加功能,这些功能也可以在动态的撤销。

2. Demo

Demo类图如下

package com.example.myalgorithm.designPattern;

public class A9Decorator {
    private interface Dao{
        void issue(String data);
    }

    public static class OriginaCouponDao implements Dao{
        @Override
        public void issue(String data) {
            System.out.println("原始数据存储:"+data);
        }
    }

    public static class DecoratorDao implements Dao{
        private Dao decoratorDa0;
        public DecoratorDao(Dao decoratorDa0) {
            this.decoratorDa0 = decoratorDa0;
        }
        @Override
        public void issue(String data) {
            decoratorDa0.issue(data);
        }
    }

    //装饰对象1
    public static class TargetCouponDao extends DecoratorDao{
        public TargetCouponDao(Dao decoratorDa0) {
            super(decoratorDa0);
        }
        @Override
        public void issue(String data) {
            super.issue(data);
            System.out.println("新数据写入" + data);
        }

    }
    //装饰对象2
    public static class SyncCouponDao extends DecoratorDao{
        public SyncCouponDao(Dao decoratorDa0) {
            super(decoratorDa0);
        }
        @Override
        public void issue(String data) {
            super.issue(data);
            System.out.println("数据同步给其他业务方" + data);
        }
    }

    public static void main(String[] args) {
        Dao originalCouponDao = new OriginaCouponDao();
        originalCouponDao.issue("用户领取第1张卡券");

        Dao targetCouponDao = new TargetCouponDao(originalCouponDao);
        targetCouponDao.issue("用户领取第2张卡券");

        Dao syncCouponDao = new SyncCouponDao(targetCouponDao);
        syncCouponDao.issue("用户领取第3张卡券");

    }

}

运行效果如下

原始数据存储:用户领取第1张卡券
原始数据存储:用户领取第2张卡券
新数据写入用户领取第2张卡券
原始数据存储:用户领取第3张卡券
新数据写入用户领取第3张卡券
数据同步给其他业务方用户领取第3张卡券

3.模式在开源软件中的应

3.1java.io.BufferedReader 类

public class BufferedReader extends Reader {
    private Reader in;
    public BufferedReader(Reader in, int sz) {
        super(in);
        if (sz <= 0)
            throw new IllegalArgumentException("Buffer size <= 0");
        this.in = in;
        cb = new char[sz];
        nextChar = nChars = 0;
    }
}  

其实在 java.io 包下大量运用了装饰者模式,在 IO 的读取写我们经常会 new ObjectInputStream(new FileInputStream()) 这种的都是装饰者模式下的应用。

3.2 springframework...TransactionAwareCacheDecorator

public class TransactionAwareCacheDecorator implements Cache {
    private final Cache targetCache;
    public TransactionAwareCacheDecorator(Cache targetCache) {
        Assert.notNull(targetCache, "Target Cache must not be null");
        this.targetCache = targetCache;
    }
}   

3.3 org.apache.ibatis.cache.*.BlockingCache 类

public class BlockingCache implements Cache {

  private long timeout;
  private final Cache delegate;
  private final ConcurrentHashMap<Object, ReentrantLock> locks;

  public BlockingCache(Cache delegate) {
    this.delegate = delegate;
    this.locks = new ConcurrentHashMap<Object, ReentrantLock>();
  }

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

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

  @Override
  public void putObject(Object key, Object value) {
    try {
      delegate.putObject(key, value);
    } finally {
      releaseLock(key);
    }
  }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值