zoukankan      html  css  js  c++  java
  • 装饰模式(Decorator)

    装饰模式(Decorator或 Wrapper)(Java IO过滤流用到的正是这个模式):

        之前总是先罗列基本概念再介绍代码,这次先把代码罗列出来再写基本的概念clip_image002

        以上是UML类图,先把基本的代码罗列出来:

    package com.designpatten.decorator;
    interface  Component {
        public void doSomething();
    }
    package com.designpatten.decorator;
    
    public class concreteComponent implements Component{
    
        public void doSomething() {
            System.out.println("功能A");
            
        }
    
    }
    package com.designpatten.decorator;
    
    abstract class Decorator implements Component {
    
        private Component component;
        
        public Decorator (Component component){
            this.component=component;
        }
        public void doSomething() {
            //调用的是传进来的component
            component.doSomething();    
        }
    }
    package com.designpatten.decorator;
    
    public class concreteDecoratorA extends Decorator{
    
        public concreteDecoratorA(Component component) {
            super(component);
        }
        
        public void doSomething(){
            super.doSomething();
            this.doAnotherthing();
        }
        
        public void doAnotherthing(){
            System.out.println("新添加的功能C");
        }
    
    
    }
    package com.designpatten.decorator;
    
    public class concreteDecoratorB extends Decorator {
        
        public concreteDecoratorB(Component component) {
            super(component);
        }
        public void doSomething(){
            super.doSomething();
            this.doAnotherthing();
        }
        
        public void doAnotherthing(){
            System.out.println("新添加的功能B");
        }
    
    }
    //最终的测试类
    package com.designpatten.decorator;
    
    public class decoratorTest {
        public static void main(String[] args) {
            //类似IO流的方式来定义 这里与IO过滤流的使用方式是一致的
            Component component1=new concreteDecoratorA(new concreteDecoratorB(new concreteComponent()));
            component1.doSomething();
            Component component2=new concreteDecoratorA(new concreteComponent());
            component2.doSomething();
            Component component3=new concreteDecoratorB(new concreteComponent());
            component3.doSomething();
        }
    
    }
    
    //输出结果
    /*
    功能A
    新添加的功能B
    新添加的功能C
    功能A
    新添加的功能C
    功能A
    新添加的功能B
    */

    定义:

         所谓装饰类就是把客户端的调用委派到被装饰类中,装饰模式的关键是在于这种扩展是一种完全透明的方式。比如某种装饰的方式:

    Component component2=new concreteDecoratorA(new concreteComponent());

    component2.doSomething();

        调用component2的doSomthing方法,首先是调用其父类(concreteComponent)的doSomething方法,这个是最初版本的doSomething方法,之后再调用扩展的方法(这里有个递归的含义在里面 多层乞嵌套的时候 super.dosomthing()会一直向上递归 直到最初定义的dosomthing()方法),这样就实现了功能的扩展,由于各个concreteComponnet类都是继承component接口,这种扩展可以以嵌套的方式多层地进行。装饰模式可以在不必改变原来类文件和使用继承的情况下,动态地扩展一个对象的功能,他是通过创建一个包装对象用于包裹真实的对象。

    特点:

    1、 装饰模式以对客户端透明的方式来扩展对象的功能,是继承方式的一种替代方案

    2、 装饰模式以对客户透明的方式动态地给对象附加更多的责任,换言之,客户端并不会觉得对象在装饰前与装饰之后有什么不同。

    3、 可以在不创建更多类的前提下,将对象的功能进行扩展。

        就像在IO中 BufferInputstream DataInputstream FileInputstream三个类可以进行组合,但是并没有增加类的数目。比如上面的例子,通过基本的三个类,可以组合出实现功能A 功能B 功能C 以及分别实现功能A 功能C 和功能A和功能B 等等,不同的功能,但是最后并没有增加新的类,仅仅是通过对原有的几个类进行组合而完成的。

    可以看出来几个基本的角色(对应IO来说):

    1、 抽象的构建角色(Component)给出了一个抽象的接口,用来规范准备接收的附加责任对象。

    2、 具体构建角色(concreteComponent)

    3、 装饰角色(Decorator)持有一个构建对象的引用作为属性,并定义一个与抽象构建接口一致的接口,注意:装饰角色会实现抽象构建角色的接口,通过构造函数传递一个具体的构建角色进来。

    4、 具体装饰角色(concreteDecorator)负责给构建角色贴上附加功能。

    装饰模式与代理模式的区别:

        其实,它们的着重点一个在于“增加”职责(装饰者模式),另一个在于“控制”访问(代理模式)。这是它们最本质的区别。使用代理模式,代理和真实对象之间的的关系通常在编译时就已经确定了,而装饰者能够在运行时递归地被构造,可以灵活地以不同的方式进行组合,具体的区别可以参考:

    http://hi.baidu.com/springlie/item/834cb0e3fa778db52e140b48

    http://www.cnblogs.com/jaredlam/archive/2011/11/08/2241089.html

        代理模式无法嵌套调用

        代理模式主要体现在对代理的对象施加控制,并不提供对象本身的增强功能,也就是说在代理模式下,那个先前的预处理的部分,可以修改成为权限控制的模块,如果当前传入进来的类的实例权限不够,就无法往下走,去访问被代理的对象的核心的方法。

        在网上找了一些相关的信息 貌似是这个样子:

        貌似是实现的机制很类似,特别是静态代理与装饰模式,但是它们最终的功能还是相反的。一个是增加功能,一个是权限限制。一说权限判断,就指的是代理模式,一说添加功能,就指得是装饰模式,虽然实现上两者确实很类似,差别主要是意图上的。

    装饰模式与继承的区别:

    1、继承是用来扩展一类对象的功能,需要子类,是静态的,在编译的时候才分配具体的职责,这样会导致很多的子类产生,比较缺乏灵活性。

    2、装饰模式是用来扩展特定对象的功能,并不需要生成新的子类,并且是动态进行的,只需要对已有的对象进行不同的组合,在运行的时候才分配职责,这样可以防止子类过多导致的混乱,并且更加灵活,对与一个给定的对象,可以同时被不同的包装类进行包装。

    3、装饰者模式可以动态地给一个对象增加其他职责。就扩展对象功能来说,装饰者模式比通过继承来生成子类更为灵活。所谓动态是说可以在系统运行时(RunTime)动态给对象增加其它职责而不需要修改代码或重新编译;所谓静态是说必须通过调整代码(DesignTime)才能给对象增加职责,而且系统还需要重新编译。

  • 相关阅读:
    如何分析页面性能?
    Java io包 ByteArrayInputStream&ByteArrayOutStream
    Java io包 inputstream&outputstream
    Java executors创建线程池和使用ThreadPoolExecutor
    Android异步任务处理
    TCP报文格式
    Java 异常
    死锁
    计算机网络-传输层
    Linux 进程同步和通信
  • 原文地址:https://www.cnblogs.com/Goden/p/3901664.html
Copyright © 2011-2022 走看看