1、Decorator模式

装饰模式又名包装(Wrapper)模式。装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

2、介绍

使用场景: 1、扩展一个类的功能。2、动态增加功能,动态撤销。

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

主要解决:一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。

优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

缺点:多层装饰比较复杂。

主要解决:一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。

3、示例代码

示例以:明星和普通人 俩种角色开题,示例演示俩种不同角色的穿衣,以及品牌

定义PersonComponent类

package cn.design.structured.decorator;

/**
* @author lin
* @version 1.0
* @date 2020-07-24 17:32
* @Description TODO
*/
public interface  PersonComponent {    String toDoingDay();    String getRole();
}

定义ConCreatePersonComponent类

package cn.design.structured.decorator;

/**
* @author lin
* @version 1.0
* @date 2020-07-24 17:37
* @Description TODO
*/
public class ConCreatePersonComponent implements PersonComponent {
   String name;
   String role;
   String faxing;
   /**
    * 上装
    */
   String jacket;
   /**
    * 下装
    */
   String bottoms;
   String shoes;    public ConCreatePersonComponent(String name, String role, String faxing, String jacket, String bottoms, String shoes) {
       this.name = name;
       this.role = role;
       this.faxing = faxing;
       this.jacket = jacket;
       this.bottoms = bottoms;
       this.shoes = shoes;
  }    @Override
   public String toDoingDay() {
       return "name='" + name + ",role=" + role + ",今天发型faxing=" + faxing + ",上装jacket=" + jacket + ",下装bottoms=" + bottoms + ",鞋子shoes=" + shoes + " 过了一天";
  }    @Override
   public String getRole() {
       return role;
  } }

定义BaseDecorator类

package cn.design.structured.decorator;

/**
* @author lin
* @version 1.0
* @date 2020-07-24 17:40
* @Description TODO
*/
public abstract class BaseDecorator implements PersonComponent {
   String decoratorStr;
   PersonComponent component;    public BaseDecorator(PersonComponent component) {
       this.component = component;
  }    @Override
   public String toDoingDay() {
       String role = component.getRole();        if (role.equalsIgnoreCase("star")) {
           decoratorStr = " today 吃雪糕,骑着自行车 ";
      } else {
           decoratorStr = " today 吃西餐,开车奔驰 ";
      }
       String str = component.toDoingDay();
       return decoratorStr + ";" + str;
  } }

定义ConCreateBaseDecorator类

package cn.design.structured.decorator;

/**
* @author lin
* @version 1.0
* @date 2020-07-24 17:49
* @Description TODO
*/
public class ConCreateBaseDecorator extends BaseDecorator {    public ConCreateBaseDecorator(PersonComponent component) {
       super(component);
  }    @Override
   public String toDoingDay() {
       String old = super.toDoingDay();
       String role = component.getRole();
       if (role.equalsIgnoreCase("star")) {
           decoratorStr += ("; ConCreateBaseDecorator 装备升级 周围围着很多小迷妹");
      } else {
           decoratorStr += ("; ConCreateBaseDecorator 糟糕 被老师叫到了 办公室");
      }
       return decoratorStr + ";" +
               old + ";";
  }    @Override
   public String getRole() {
       return null;
  } }

定义DecoratorMain测试类

package cn.design.structured.decorator;

/**
* @author lin
* @version 1.0
* @date 2020-07-24 17:32
* @Description TODO
*/
public class DecoratorMain {
   public static void main(String[] args) {
       PersonComponent student = new ConCreatePersonComponent("小明", "student", "平头", "校服", "休闲裤", "老北京拖鞋");
       PersonComponent star = new ConCreatePersonComponent("黄晓明", "star", "大背头", "西装", "西裤", "芬迪皮鞋");
       // 普通修饰
       BaseDecorator b1 = new ConCreateBaseDecorator(student);
       System.out.println(b1.toDoingDay());
       // 精装修
       BaseDecorator b2 = new ConCreateBaseDecorator(star);
       System.out.println(b2.toDoingDay());
  } }

运行结果如下:

today 吃西餐,开车奔驰 ; ConCreateBaseDecorator 糟糕 被老师叫到了 办公室; today 吃西餐,开车奔驰  ;name='小明,role=student,今天发型faxing=平头,上装jacket=校服,下装bottoms=休闲裤,鞋子shoes=老北京拖鞋 过了一天;
today 吃雪糕,骑着自行车 ; ConCreateBaseDecorator 装备升级 周围围着很多小迷妹; today 吃雪糕,骑着自行车  ;name='黄晓明,role=star,今天发型faxing=大背头,上装jacket=西装,下装bottoms=西裤,鞋子shoes=芬迪皮鞋 过了一天;

4、深入了解

类图:

角色:

◆Component

增加功能时的核心角色。以本章开头的例子来说,装饰前的蛋糕就是Component角色。Component角色只是定义了蛋糕的接口( API)。在示例程序中,由Display类扮演此角色。

◆ConcreteComponent

该角色是实现了Component角色所定义的接口(API)的具体蛋糕。在示例程序中,由StringDisplay类扮演此角色。

◆Decorator (装饰物)

该角色具有与Component角色相同的接口( API)。在它内部保存了被装饰对象一Component角色。Decorator 角色知道自己要装饰的对象。在示例程序中,由Border类扮演此角色。

◆ConcreteDecorator (具体的装饰物)

该角色是具体的Decorator角色。在示例程序中,由SideBorder类和FullBorder类扮演此角色。

公众号发哥讲

这是一个稍偏基础和偏技术的公众号,甚至其中包括一些可能阅读量很低的包含代码的技术文,不知道你是不是喜欢,期待你的关注。

如果你觉得文章还不错,就请点击右上角选择发送给朋友或者转发到朋友圈~

● 扫码关注我们

据说看到好文章不推荐的人,服务器容易宕机!

本文版权归发哥讲博客园共有,原创文章,未经允许不得转载,否则保留追究法律责任的权利。

12、Decorator 装饰器 模式 装饰起来美美哒 结构型设计模式的更多相关文章

  1. 装饰器模式(Decorator Pattern)

    装饰器模式 一.什么是装饰器模式   装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装 ...

  2. PHP设计模式之装饰器模式(Decorator)

    PHP设计模式之装饰器模式(Decorator) 装饰器模式 装饰器模式允许我们给一个类添加新的功能,而不改变其原有的结构.这种类型的类属于结构类,它是作为现有的类的一个包装 装饰器模式的应用场景 当 ...

  3. Java设计模式12:装饰器模式

    装饰器模式 装饰器模式又称为包装(Wrapper)模式.装饰器模式以多客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰器模式的结构 通常给对象添加功能,要么直接修改对象添加相应的功能, ...

  4. c#设计模式之装饰器模式(Decorator Pattern)

    引子 在面向对象语言中,我们常常会听到这样一句话:组合优于继承.那么该如何去理解这句话呢? 下面我将以游戏装备为模型用简单的代码去展示它 先创建一个装备的抽象类,然后创建刀枪2个具体的业务子类 pub ...

  5. 装饰器模式(Decorator) C++

    装饰器模式是比较常用的一种设计模式,Python中就内置了对于装饰器的支持. 具体来说,装饰器模式是用来给对象增加某些特性或者对被装饰对象进行某些修改. 如上图所示,需要被装饰的对象在最上方,它自身可 ...

  6. Java IO流以及装饰器模式在其上的运用

    流概述 Java中,流是一种有序的字节序列,可以有任意的长度.从应用流向目的地称为输出流,从目的地流向应用称为输入流. Java的流族谱 Java的 java.io 包中囊括了整个流的家族,输出流和输 ...

  7. python设计模式之装饰器模式

    装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰 ...

  8. java设计模式之 装饰器模式

    装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构. 这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装 ...

  9. JAVA设计模式--装饰器模式

    装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰 ...

随机推荐

  1. redis(十三):Redis 集合(Set) python

    # -*- coding: utf-8 -*- import redis r = redis.Redis(host="126.56.74.190",port=639,passwor ...

  2. Zabbix 4.0 API 实践,主机/主机群组 批量添加模板和删除模板

    场景 我们日常在管理Zabbix 的时候,经常会需要批量添加模板和批量删除模板,Zabbix页面是提供的批量链接的功能,但是它链接的也只是当前页的主机,我们想扩展这个功能,在链接的时候,可以批量链接整 ...

  3. Python数据可视化:画饼状图、折线图、圈图

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. from math import pi import matplotlib ...

  4. P1039 侦探推理(洛谷)

    昨天做了一个非常神奇的题,告诉我们做题之前一定要好好检测评测姬! 明明同学最近迷上了侦探漫画<柯南>并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏.游戏的内容是这样的,明明的同学们先 ...

  5. 集训 T2-监考老师

    大致题意: 找出一个位置可以选出最大的"横排总和+竖列总和". 基本思路 利用前缀和的思想在读入的时候把每一列每一行的总和都算出来, 然后暴力枚举每一个点,每一个点的答案就是这一行 ...

  6. Linux内核功能介绍及如何使用保护您的网页安全

    在本文中,我们快速浏览了Linux内核的许可流程,并向您展示了如何使用它们来保护您的网页或应用安全 传统上,Linux内核通过以下两类来区分其进程: 特权进程:这些进程使用户可以绕过所有内核权限检查. ...

  7. Makefile中的一个坑

    问题描述:Makefile中,我想将一个变量的后缀全部进行替换,如将所有的.c后缀变成.d后缀 方法:$(CUR_SOURCE: .c = .d ) 说明:查阅相关资料,了解到上述这种语法就可以将所有 ...

  8. vue学习(十六) 自定义私有过滤器 ES6字符串新方法 填充字符串

    <div id="app"> <p>{{data | formatStr('yyyy-MM-dd')}}</p></div> //s ...

  9. springmvc(一)springmvc简介与入门程序

    springmvc概括: Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱 ...

  10. Mybatis(三)动态sql语句

    动态sql语句操作 1.MyBatis中#{ }和${ }的区别 在 mapper 中定义的参数传到 xml 中之后,在查询之前 mybatis 会对其进行动态解析.mybatis 为我们提供了两种支 ...