设计模式—装饰器模式

1 设计模式介绍

装饰器模式(Decorator Pattern),又叫作包装器模式(Wrapper Pattern),指在不改变原有对象结构的情况下,动态地给对象增加一些额外功能的职责。属于对象结构型模式。

1.1 与代理模式的区别

装饰器模式强调自身功能的扩展,是代理模式的一个特殊应用。

代理模式强调对代理过程的控制。

1.2 装饰器模式的结构

通常情况下,扩展一个类的功能会使用继承方式来实现。但继承具有静态特征,耦合度高,并且随着扩展功能增多,子类会很膨胀。

如果使用组合关系来创建一个包装对象(即装饰对象)来包裹真实对象,并且保持真实对象的类结构不变的前提下,为其提供额外的功能,这就是装饰模式的目标。

装饰器主要包含四个角色:

抽象构件(Component:可以是一个接口或者抽象类,充当装饰类的原始对象,规定了被装饰的行为。

具体构建(Concrete Component:实现/继承Component的一个具体对象,即被装饰对象。通过装饰角色为其添加一些职责。

抽象装饰器(Decorator): 实现/继承Component。其内部必然有一个属性指向Component,可以通过其子类扩展具体组件的功能。

具体装饰器(ConcreteDecorator): Decorator的具体实现类,并给具体构件对象添加附加责任,一般为其特有的功能。

图 装饰器模式UML

需求描述:对前端传递的数据需要对字段进行校验,比如,非空,日期校验等。

public class DecoratorTest {

    /**
     * 校验器
     */
    interface Verifier {
        boolean verify(Object object);
    }

    /**
     * 网络请求校验器
     */
    static class RequestVerifier implements Verifier{

        @Override
        public boolean verify(Object object) {
            return object != null; //非空校验
        }

    }

    /**
     * 校验器装饰器
     */
    static class VerifierDecorator implements Verifier {

        private Verifier verifier;

        public VerifierDecorator(Verifier verifier) {
            this.verifier = verifier;
        }

        @Override
        public boolean verify(Object object) {
            return verifier.verify(object);
        }
    }

    /**
     * 日期校验器
     */
    static class DateVerifierDecorator extends VerifierDecorator {

        public DateVerifierDecorator(Verifier verifier) {
            super(verifier);
        }

        @Override
        public boolean verify(Object object) {
            if(super.verify(object)) return dateVerify(object);
            return false;
        }

        private boolean dateVerify(Object object) {
            return object instanceof Date;
        }
    }

    /**
     * Integer 校验器
     */
    static class IntegerVerifierDecorator extends VerifierDecorator {

        public IntegerVerifierDecorator(Verifier verifier) {
            super(verifier);
        }

        @Override
        public boolean verify(Object object) {
            if(super.verify(object)) return integerVerify(object);
            return false;
        }

        private boolean integerVerify(Object object) {
            return object instanceof Integer;
        }
    }

    public static void main(String[] args) {
        String obj0 = null;
        String obj1 = "hello java";
        Date obj2 = new Date();
        Integer obj3 = 1;

        Verifier requestVerifier = new RequestVerifier();

        Verifier dateVerifier = new DateVerifierDecorator(requestVerifier);
        System.out.println("dateVerifier");
        System.out.println(obj0 + ":" + dateVerifier.verify(obj0));
        System.out.println(obj1 + ":" + dateVerifier.verify(obj1));
        System.out.println(obj2 + ":" + dateVerifier.verify(obj2));
        System.out.println(obj3 + ":" + dateVerifier.verify(obj3));
        System.out.println("----------------------------");

        Verifier integerVerifier = new IntegerVerifierDecorator(requestVerifier);
        System.out.println("integerVerifier");
        System.out.println(obj0 + ":" + integerVerifier.verify(obj0));
        System.out.println(obj1 + ":" + integerVerifier.verify(obj1));
        System.out.println(obj2 + ":" + integerVerifier.verify(obj2));
        System.out.println(obj3 + ":" + integerVerifier.verify(obj3));

//        运行结果:
//        dateVerifier
//        null:false
//        hello java:false
//        Sun Nov 06 11:18:26 CST 2022:true
//        1:false
//        ----------------------------
//        integerVerifier
//        null:false
//        hello java:false
//        Sun Nov 06 11:18:26 CST 2022:false
//        1:true

    }

}

1.3 优缺点

优点:在不改变现有对象结构的情况下,动态地给对象增加一些职责(额外功能)。

缺点:如果对于一个类型装饰的类的扩展功能太多,那么将会产生很多的小类。增加了程序的复杂性,不易排错。

二 java I/O 系统与装饰器模式

编程语言的I/O类库中常使用流这个抽象概念,它代表任何有能力产出数据的数据源对象或是有能力就收数据的接收端。“流”屏蔽了实际的I/O设备中处理数据的细节。

Java类库中的I/O类分成输入和输出两部分,通过继承,任何自InputStream或Reader派生而来的类都含有名为read()的基本方法,用于读取单个字节或者字节数组。但是。我们通常不会用到这些方法,它们之所以存在是因为别的类可以使用它们,以便提供更有用的接口。因此,我们很少使用单一的类来创建流对象,而是通过叠合多个对象来提供所期望的功能。这就是装饰器模式。

图 InputStream 继承结构

需求描述:创建一个缓存读取文件的inputStream。

InputStream is = new FileInputStream(“filePath”);

InputStream bufferIs = new BufferInputStream(is);

三 使用场景

1)当需要给一个现有类添加附加职责,而又不能采用生成子类的方法进行扩充时。例如,该类被隐藏或者该类是终极类或者采用继承方式会产生大量的子类。

2)当需要通过对现有的一组基本功能进行排列组合而产生非常多的功能时,采用继承关系很难实现,而采用装饰器模式却很好实现。

3)当对象的功能要求可以动态地添加,也可以再动态地撤销时。

装饰器模式Decorator Pattern)是一种结构型设计模式,它允许向一个现有的对象添加新的功能,同时又不改变其结构。这种模式通过创建一个装饰类来包装原始的类,从而实现动态地扩展一个对象的功能。装饰类和被装饰类可以独立发展,它们之间没有耦合关系。装饰器模式是继承的一个替代模式,它避免了使用继承来扩展对象功能所带来的静态特性。 在C++中,可以通过使用抽象类和具体类来实现装饰器模式。首先创建一个抽象类(比如Shape)作为基类,然后创建具体的类(比如Circle和Rectangle)作为子类。这些子类实现了抽象类中的纯虚函数(比如draw),分别表示不同的图形。 在使用装饰器模式时,我们可以创建一个装饰类,它也是抽象类的子类,并且它的对象包含一个抽象类对象的指针。装饰类可以在原始对象的基础上添加额外的功能,同时保持原始对象的接口不变。通过使用装饰器模式,我们可以动态地扩展一个对象的功能,而无需修改原始对象的结构。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [C++设计模式装饰器模式](https://blog.youkuaiyun.com/m0_73443478/article/details/129751085)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值