常用開源框架中設計模式使用分析- 裝飾器模式(Decorator Pattern)

weixin_34236497發表於2017-05-25

九、裝飾器模式(Decorator Pattern)

9.1 介紹

裝飾器模式是一種結構性模式,它作用是對物件已有功能進行增強,但是不改變原有物件結構。這避免了通過繼承方式進行功能擴充導致的類體系臃腫。

裝飾器模式是一種結構性模式,它作用是對物件已有功能進行增強,但是不改變原有物件結構。這避免了通過繼承方式進行功能擴充導致的類體系臃腫。

9.2 Spring中BeanDefinitionDecorator

先看下類圖:

5879294-d2b4cce1f7c6af91.png
image.png

如圖ScopedProxyBeanDefinitionDecorator實現了decorate方法用來對scope作用域為request的bean定義進行包裝。
具體時序圖為:

5879294-e807b690844b2e7b.png
image.png
class ScopedProxyBeanDefinitionDecorator implements BeanDefinitionDecorator {

    private static final String PROXY_TARGET_CLASS = "proxy-target-class";


    @Override
    public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext) {
        boolean proxyTargetClass = true;
        if (node instanceof Element) {
            Element ele = (Element) node;
            if (ele.hasAttribute(PROXY_TARGET_CLASS)) {
                proxyTargetClass = Boolean.valueOf(ele.getAttribute(PROXY_TARGET_CLASS));
            }
        }

        // 建立scoped的代理類,並註冊到容器
        BeanDefinitionHolder holder =
                ScopedProxyUtils.createScopedProxy(definition, parserContext.getRegistry(), proxyTargetClass);
        String targetBeanName = ScopedProxyUtils.getTargetBeanName(definition.getBeanName());
        parserContext.getReaderContext().fireComponentRegistered(
                new BeanComponentDefinition(definition.getBeanDefinition(), targetBeanName));
        return holder;
    }

}

關於ScopedProxyBeanDefinitionDecorator幹啥用的那:


  <bean id="lavaPvgInfo" class="com.alibaba.lava.privilege.PrivilegeInfo"
        scope="request">
        <property name="aesKey" value="666" />
        <aop:scoped-proxy />
    </bean>

其實就是處理<aop:scoped-proxy />
的,具體作用是包裝lavaPvgInfo的bean定義為ScopedProxyFactoryBean,作用是實現request作用域bean.

9.3 commons-collections包中ListUtils

5879294-fddd2508eb2c68eb.png
image.png

如圖

ListUtils中的四個方法分別依賴list的四種裝飾器類對List功能進行擴充和限制。
其中FixedSizeList類通過禁止add/remove操作保證list的大小固定,但是可以修改元素內容
其中UnmodifiableList類通過禁用add,clear,remove,set,保證list的內容不被修改
其中SynchronizedList類通過使用Lock 來保證add,set,get,remove等的同步安全
其中LazyList類則當呼叫get方法發現list裡面不存在物件時候,自動使用factory建立物件.

9.4 使用場景

  • 在不改變原有類結構基礎上,新增或者限制或者改造功能時候。

歡迎關注微信公眾號:技術原始積累 獲取更多技術乾貨

5879294-2c414099893f4cbe.png
image.png

相關文章