当前位置: 首页 > news >正文

设计模式——装饰者模式

参考书籍:设计模式之禅——秦小波著,机械工业出版社

1 定义

  动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活。

2 类图

图片来自百度百科

3 代码

(1)Component类

package com.amy.decoratordesign;

/**
 * 抽象构建
 * @author zhujinrong
 *
 */
public abstract class Component {

    /**
     * 抽象方法
     */
    public abstract void Operate();
}

 (2) ConcreteComponent类

package com.amy.decoratordesign;

/**
 * 具体构件
 * @author zhujinrong
 *
 */
public class ConcreteComponent extends Component{

    /**
     * 具体实现
     */
    @Override
    public void Operate() {
        // TODO Auto-generated method stub
        System.out.println("ConcreteComponent-Operate:do something");
    }
}

(3)Decorator类

package com.amy.decoratordesign;

/**
 * 抽闲装饰类
 * 
 * @author zhujinrong
 * 
 */
public abstract class Decorator extends Component {

    /**
     * 构件
     */
    private Component component = null;

    /**
     * 通过构造函数传递被修饰者
     * 
     * @param component
     *            构件
     */
    public Decorator(Component component) {
        this.component = component;
    }

    /**
     * 委托给被修饰者执行
     */
    @Override
    public void Operate() {
        this.component.Operate();
    }
}

(4)ConcreteDecoratorA 类

package com.amy.decoratordesign;

/**
 * 具体装饰类
 * @author zhujinrong
 *
 */
public class ConcreteDecoratorA extends Decorator {

    /**
     * 构造函数
     * @param component 构件
     */
    public ConcreteDecoratorA(Component component) {
        super(component);
        // TODO Auto-generated constructor stub
    }

    /**
     * 定义自己的修饰方法
     */
    private void method1() {
        System.out.println("ConcreteDecoratorA-method1:修饰");
    }
    
    /**
     * 重写父类的Operate方法
     */
    @Override
    public void Operate(){
        this.method1();
        super.Operate();
    }
}

(5)ConcreteDecoratorB类

package com.amy.decoratordesign;

/**
 * 具体装饰类B
 * 
 * @author zhujinrong
 * 
 */
public class ConcreteDecoratorB extends Decorator {

    /**
     * 构造函数
     * 
     * @param component
     *            构件
     */
    public ConcreteDecoratorB(Component component) {
        super(component);
        // TODO Auto-generated constructor stub
    }

    /**
     * 自定义装饰
     */
    private void method1() {
        System.out.println("ConcreteDecoratorB-method1:修饰。");
    }

    /**
     * 重写父类方法
     */
    @Override
    public void Operate() {
        this.method1();
        super.Operate();
    }
}

(6)Client类

package com.amy.decoratordesign;

/**
 * 场景类
 * @author zhujinrong
 *
 */
public class Client {
    /**
     * 程序入口
     * @param args
     */
    public static void main(String[] args) {
        Component component = new ConcreteComponent();

        // 第一次修饰
        component = new ConcreteDecoratorA(component);

        // 第二次修饰
        component = new ConcreteDecoratorB(component);

        // 修饰后运行
        component.Operate();
    }
}

4 执行结果

注意看看这个结果。

4 装饰模式的优缺点

(1)装饰类和被装饰类可以独立发展,而不会相互耦合。换句话说,Component类无须知道Decorator类,Decorator类是从外部来扩展Component类的功能,而Decorator也不用知道具体的构件。

(2)装饰模式是继承关系的一个替代方案。我们看装饰类Decorator,不管装饰多少层,返回的对象还是Component,实现的还是is-a的关系。

(3)装饰模式可以动态地扩展一个实现类的功能,这不需要多说,装饰模式的定义就是如此。

5 装饰模式的缺点

  多层的装饰是比较复杂的。就想剥洋葱一样。

6 使用场景

(1)需要扩展一个类的功能,或给一个类增加附加功能

(2)需要动态地给一个对象增加功能,这些功能可以再动态地撤销

(3)需要为一批的兄弟类进行改装或加装功能,当然首选装饰模式

7 最佳实践

  继承是静态地给类增加功能,而装饰模式则是动态地增加功能。

  装饰模式是对继承的有力扩充。

  装饰模式扩展性很好。

转载于:https://www.cnblogs.com/tianxue/p/4151026.html

相关文章:

  • c语言的作用域、变量与结构体
  • 关于终端和控制台的一些解释
  • 从源码编译新版OGRE 1.7.2 [Cthugha] for iphone/ipad
  • VS2010 添加服务引用以后点不出引用服务的命名空间
  • 查找触发器
  • Android中的PopupWindow详解
  • 怎么使用response.write来做一个javascript的alert弹出窗口
  • 堆栈指针理解
  • Json的引入
  • Realtime Rendering 3rd笔记 8
  • CSS3 Media Queries
  • IIS7的虚拟目录设置独立应用程序池
  • css 中比较常见的属性
  • vs.net 2003下vb.net项目中控件属性栏没有事件图标的诡异现象
  • [BZOJ1089][SCOI2003]严格n元树(递推+高精度)
  • 【108天】Java——《Head First Java》笔记(第1-4章)
  • 3.7、@ResponseBody 和 @RestController
  • es6要点
  • Fastjson的基本使用方法大全
  • JS笔记四:作用域、变量(函数)提升
  • Python3爬取英雄联盟英雄皮肤大图
  • REST架构的思考
  • Vue官网教程学习过程中值得记录的一些事情
  • Zsh 开发指南(第十四篇 文件读写)
  • 创建一种深思熟虑的文化
  • 个人博客开发系列:评论功能之GitHub账号OAuth授权
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 基于Dubbo+ZooKeeper的分布式服务的实现
  • 力扣(LeetCode)22
  • 推荐一个React的管理后台框架
  • 吴恩达Deep Learning课程练习题参考答案——R语言版
  • 新年再起“裁员潮”,“钢铁侠”马斯克要一举裁掉SpaceX 600余名员工 ...
  • # C++之functional库用法整理
  • #100天计划# 2013年9月29日
  • #图像处理
  • #我与Java虚拟机的故事#连载04:一本让自己没面子的书
  • (10)ATF MMU转换表
  • (6)STL算法之转换
  • (Spark3.2.0)Spark SQL 初探: 使用大数据分析2000万KF数据
  • (附源码)spring boot火车票售卖系统 毕业设计 211004
  • (附源码)springboot建达集团公司平台 毕业设计 141538
  • (三十五)大数据实战——Superset可视化平台搭建
  • (顺序)容器的好伴侣 --- 容器适配器
  • (循环依赖问题)学习spring的第九天
  • (一)插入排序
  • (转) Android中ViewStub组件使用
  • (转)重识new
  • (转载)Google Chrome调试JS
  • . ./ bash dash source 这五种执行shell脚本方式 区别
  • .bashrc在哪里,alias妙用
  • .NET 6 Mysql Canal (CDC 增量同步,捕获变更数据) 案例版
  • .NET基础篇——反射的奥妙
  • .NET面试题(二)
  • .NET与 java通用的3DES加密解密方法
  • .ui文件相关