巧妙的运用装饰器,让你的代码高出一个逼格!

开发 开发工具
装饰器模式,顾名思义,就是在一个类上增加功能,以起到装饰的作用。今天我们一起来看看深度了解一下装饰器的玩法!

一、介绍

装饰器模式,顾名思义,就是在一个类上增加功能,以起到装饰的作用。

我们都知道,如果想给某个类新增功能,但又要避免在原类上修改代码,最常用的方式就是新增一个类来继承目标类,但是如果增加多的话,会使类的数量爆炸式增长,为管理带来巨大的麻烦,装饰器模式就比较好地解决了这一点。

[[426041]]

从设计的角度看,装饰器模式涉及到四个角色:

  • 被装饰类:要进行扩展的源类;
  • 装饰器类:通过该类可以给被装饰类动态添加额外的方法,多以抽象为主;
  • 具体的装饰类:该类实现自装饰器类,已完成完整的算法;
  • 客户角色:客户类提出使用具体类的请求;

今天我们一起来看看深度了解一下装饰器的玩法!

二、代码示例

下面以生产一件衣服为例,一块布料裁剪好了之后做出的衣服样子还可以,但是这样的衣服是卖不出去的,因为毫无美感,因此我们需要通过一些装饰来使衣服变得好看。

我们先来创建一个抽象类或者接口,定义一个骨架,如下:

  1. /** 
  2.  * 建立基本骨架 
  3.  */ 
  4. public interface Clothes { 
  5.  
  6.     void makeClothes(); 

接着创建一个我们需要装饰的源类,如下:

  1. /** 
  2.  * 被装饰类 
  3.  */ 
  4. public class MakeClothes implements Clothes { 
  5.  
  6.     @Override 
  7.     public void makeClothes() { 
  8.         System.out.println("制作一件衣服"); 
  9.     } 

再来创建我们的主角,装饰类,如下:

  1. /** 
  2.  * 装饰类 
  3.  */ 
  4. public class Decorator implements Clothes { 
  5.  
  6.     private Clothes clothes; 
  7.  
  8.     public Decorator(Clothes clothes) { 
  9.         this.clothes = clothes; 
  10.     } 
  11.  
  12.     @Override 
  13.     public void makeClothes() { 
  14.         clothes.makeClothes(); 
  15.     } 
  16.  

最后,分别创建两个具体的装饰类,如下:

  1. /** 
  2.  * 具体的装饰类 
  3.  */ 
  4. public class EmbroideryDecorator extends Decorator { 
  5.  
  6.  
  7.     public EmbroideryDecorator(Clothes clothes) { 
  8.         super(clothes); 
  9.     } 
  10.  
  11.     @Override 
  12.     public void makeClothes() { 
  13.         super.makeClothes(); 
  14.         System.out.println("给衣服绣制花朵"); 
  15.     } 

 

  1. /** 
  2.  * 具体的装饰类 
  3.  */ 
  4. public class MickeyDecorator extends Decorator { 
  5.  
  6.  
  7.     public MickeyDecorator(Clothes clothes) { 
  8.         super(clothes); 
  9.     } 
  10.  
  11.     @Override 
  12.     public void makeClothes() { 
  13.         super.makeClothes(); 
  14.         System.out.println("给衣服绘制米老鼠图案"); 
  15.     } 

怎么用呢?请看下面的测试类:

  1. /** 
  2.  * 客户端 
  3.  */ 
  4. public class DecorateClient { 
  5.  
  6.     public static void main(String[] args) { 
  7.         Clothes clothes = new MakeClothes(); 
  8.         clothes = new EmbroideryDecorator(clothes);//给衣服绣花 
  9.         clothes = new MickeyDecorator(clothes);//给衣服添加米老鼠图案 
  10.         clothes.makeClothes(); 
  11.         System.out.println("成品已经完成!"); 
  12.     } 

输出结果如下:

  1. 制作一件衣服 
  2. 给衣服绣制花朵 
  3. 给衣服绘制米老鼠图案 
  4. 成品已经完成 

制作一件衣服给衣服绣制花朵给衣服绘制米老鼠图案成品已经完成

从结果上,可以看到,我们成功的给MakeClothes这个类,动态添加了2个方法,一个是给衣服绣花,另一个是给衣服添加米老鼠图案,最后成品完成!

可见装饰的效果还不错~

三、应用

其实在 jdk 中,装饰者设计模式也有很多典型的场景应用,例如我们熟悉的io包中的字节输入、输出流,就用到了装饰者设计模式!

其中FilterInputStream、FilterOutputStream就是装饰类,用于动态给输入、输出流增加方法!

四、总结

巧妙采用装饰器模式,可以很好的解决类继承数量过多的问题,让代码清晰可读。

但是如果装饰层数过多,也会影响到代码的维护,因此在实际的使用过程中,还需灵活使用!

 

责任编辑:赵宁宁 来源: Java极客技术
相关推荐

2021-07-12 07:08:54

责任链模式对象

2021-04-15 07:32:02

java 代码Stream

2021-08-11 06:57:17

验证码图片显示

2024-09-12 15:32:35

装饰器Python

2011-04-01 09:49:54

Python

2020-06-08 15:18:50

Python图片PIL

2024-04-29 06:50:45

Python代码运行

2016-11-17 12:49:36

云运维银行卡建设

2020-12-21 13:33:00

medit编辑器Linux

2021-07-26 07:32:48

模式适配器包装器

2022-10-31 07:09:15

拷贝代码项目

2017-12-07 15:05:50

全球互联网创新峰会

2017-11-09 08:48:49

JavaScript编程黑科技

2017-12-28 11:05:38

负载均衡算法巧妙

2020-04-13 16:05:25

JS装饰器前端

2024-10-11 11:21:39

适配器模式系统

2022-02-07 20:18:29

Redis缓存装饰

2023-11-23 16:46:55

LinuxAWK运维

2020-09-29 14:13:29

写一个高逼格可视化“圆

2009-11-18 15:39:43

PHP函数
点赞
收藏

51CTO技术栈公众号