• 装饰器模式


    什么是装饰器模式

      装饰器模式又称包装(Wrapper)模式,能够实现动态的为对象添加功能。是继承关系的一个替代方案,因为可以在不创造子类的情况下将对象的功能加以扩展。

      通常给对象添加新功能,要么直接修改对象添加,要么派生对应的子类添加或者使用对象组合的方式。在面上对象的设计中,我们应该尽量使用对象组合而不是对象继承来扩展。装饰器模式就是基于对象组合的方式,可以很灵活的给对象添加所需要的功能。

    装饰器模式的结构和说明

      -抽象构件角色(Component):给出一个抽象接口,以规范准备接收附加责任对象。

      -具体构件角色(Concrete Component):定义一个将要接收附加责任的类。

      -装饰角色(Decorator):持有一个构件(Component)对象引用,并定义一个与抽象构件接口一致的接口

      -具体装饰角色(Concrete Decorator):负责给构件对象“贴上”附加的责任

                                  

    装饰器模式的特点

      -装饰器对象和真是对象有相同的接口。这样客户端对象就可以和真实对象相同的方式和装饰对象交互。

      -装饰对象包含一个真实对象的引用。

      -装饰对象接收所有来自客户端的请求。它把这些请求转发给真实的对象。

      装饰对象可以在转发这些请求以前或以后增加一些附加功能。这样就确保了在运行时,不能修改给定对象的构件就可以在外部增加附加功能。在面向对象的设计中,通常是通过集成来实现对给定类的功能扩展

    示例:

      步骤:

    1. 写一个组件对象接口 Component.java
    2. 写一个类 ConcreteComponent.java 实现 组件对象接口
    3. 写一个装饰器抽象类 Decorator.java 实现组件接口
    4. 写装饰器具体的实现对象 ConcreteDecorator1.java和ConcreteDecorator2.java

    步骤一:写一个组件对象接口

    package org.burning.sport.design.pattern.decoratorpattern;
    
    /**
     *  @Description: 组件对象接口,可以给这些对象动态的添加职责
     */
    public interface Component {
        public void doSomething();
    }

    步骤二:写一个具体构件角色

    package org.burning.sport.design.pattern.decoratorpattern;
    
    /**
     *  @Description: 具体的组件对象,实现了组件接口。该对象通常就是被装饰器装饰的原始对象,可以给这个对象添加职责
     */
    public class ConcreteComponent implements Component {
        @Override
        public void doSomething() {
            System.out.println("功能A");
        }
    }

    步骤三:写一个装饰器抽象类

    package org.burning.sport.design.pattern.decoratorpattern;
    
    /**
     *  @Description: 所有装饰器的父类,需要定义一个与组件接口一致的接口(主要是为了实现装饰器功能的复用,
     *                 即具体的装饰器A可以装饰另外一个具体的装饰器B,因为装饰器类也是一个Component),并持有一个Component对象,
     *                 该对象其实就是被装饰的对象。如果不实现组件接口类,则只能为某个组件添加单一的功能,
     *                 即装饰器对象不能再装饰其他的装饰器对象
     */
    public abstract class Decorator implements Component {
        /**
         * 持有组件对象
         */
        private Component component;
    
        public Decorator(Component component) {
            this.component = component;
        }
    
        @Override
        public void doSomething() {
            //转发请求给组件对象,可以在转发前后执行一些附加动作
            component.doSomething();
        }
    }

    步骤四:写装饰器具体的实现对象

    package org.burning.sport.design.pattern.decoratorpattern;
    
    /**
     *  @Description: 具体的装饰器类,实现具体要向被装饰对象添加的功能。用来装饰具体的组件对象或者另外一个具体的装饰器对象
     */
    public class ConcreteDecorator1 extends Decorator {
        public ConcreteDecorator1(Component component) {
            super(component);
        }
    
        @Override
        public void doSomething() {
            super.doSomething();
            this.doAnotherThing();
        }
    
        /**
         * 新功能
         */
        private void doAnotherThing() {
            System.out.println("功能B");
        }
    }
    package org.burning.sport.design.pattern.decoratorpattern;
    
    /**
     *  @Description: 具体的装饰器类,实现具体要向被装饰对象添加的功能。用来装饰具体的组件对象或者另外一个具体的装饰器对象
     */
    public class ConcreteDecorator2 extends Decorator{
        public ConcreteDecorator2(Component component) {
            super(component);
        }
    
        @Override
        public void doSomething() {
            super.doSomething();
            this.doAnotherThing();
        }
    
        private void doAnotherThing() {
            System.out.println("功能C");
        }
    }

    步骤五:测试

    package org.burning.sport.design.pattern.decoratorpattern;
    
    /**
     *  @Description: 装饰器模式(包装模式Wrapper)
     *   装饰模式能够实现动态的为对象添加功能,是从一个对象外部来给对象添加功能。
     *   装饰器模式的本质就是动态组合,动态是手段,组合才是目的
     */
    public class ClientMain {
        public static void main(String[] args) {
            //节点流
    //        Component component = new ConcreteComponent();  //首先创建需要被装饰的原始对象(即要被装饰的对象)
            //过滤流
    //        Component component2 = new ConcreteDecorator1(component); //给对象透明的增加功能B并调用
            //过滤流
    //        Component component3 = new ConcreteDecorator2(component2);//给对象透明的增加功能C并调用
    //        component3.doSomething();
    
            Component component1 = new ConcreteDecorator1(new ConcreteDecorator2(new ConcreteComponent()));
    
            component1.doSomething();
    
        }
    }

    https://gitee.com/play-happy/base-project

    参考:

    [1] 博客, http://blog.csdn.net/hust_is_lcd/article/details/7884320

    [2] 博客,http://www.runoob.com/design-pattern/decorator-pattern.html

  • 相关阅读:
    python使用阿里云oss-sdk
    flask-文件上传的使用
    flask-migrate的基本使用
    flask-script的基本使用
    flask-sqlalchemy的基本使用
    alembic的常用参数
    sqlchemy查询的其他操作
    orm层面的删除的注意事项
    C#获取数据库中的Instance
    SOA Demo
  • 原文地址:https://www.cnblogs.com/happyflyingpig/p/7771871.html
Copyright © 2020-2023  润新知