前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >装饰者模式浅析

装饰者模式浅析

作者头像
孟君
发布2019-09-10 15:22:36
4500
发布2019-09-10 15:22:36
举报

装饰者模式是一种对象结构型模式,其意图是动态地给一个对象添加一些额外的职责。

一、装饰者模式的基本介绍

1.1 意图

动态地给一个对象添加额外的职责。

1.2 结构

装饰者模式的基本结构如下:

  • Component

定义一个对象接口,可以给这些对象动态地添加职责。

  • ConcreteComponent

定义一个对象,可以给这个对象添加一些职责。

  • Decorator

装饰角色,持有一个Component对象的实例,并定义一个与Componnet接口一致的接口。

  • ConcreteDecorator

具体装饰角色,负责给组件添加职责。

二、装饰者模式示例

西游记中的孙悟空,具有七十二般变化,给我们留下了深刻的印象,他的每一种变化都给他带来了一种新的本领。他变成鱼儿时,就可以到水里游泳;他变成雀儿,就可以在天上飞行。

下面我们就以齐天大圣的例子来完成一个装饰者模式的例子:

  • TheGreatestSage (Component)
package com.wangmengjun.tutorial.designpattern.decorator;

public interface TheGreatestSage {

  void move();
}
  • Change (Decorator)
package com.wangmengjun.tutorial.designpattern.decorator;

public class Change implements TheGreatestSage {

  private TheGreatestSage sage;
  
  public Change(TheGreatestSage sage) {
    this.sage = sage;
  }

  public void move() {
    sage.move();
  }

}
  • Monkey (ConcreteComponent)
package com.wangmengjun.tutorial.designpattern.decorator;

public class Monkey implements TheGreatestSage {

  public void move() {
    System.out.println("Monkey move~~");
  }

}
  • Bird (ConcreteDecorator1)
package com.wangmengjun.tutorial.designpattern.decorator;

public class Bird extends  Change {

  public Bird(TheGreatestSage sage) {
    super(sage);
  }

  @Override
  public void move() {
    System.out.println("Bird move~~");
  }
}
  • Fish(ConcreteDecorator2)
package com.wangmengjun.tutorial.designpattern.decorator;

public class Fish extends  Change {

  public Fish(TheGreatestSage sage) {
    super(sage);
  }

  @Override
  public void move() {
    System.out.println("Fish move~~");
  }
}

对象包装示例:

package com.wangmengjun.tutorial.designpattern.decorator;

public class Client {
  
  public static void main(String[] args) {
    TheGreatestSage sage = new Monkey();
    
    /**
     * 单层封装
     */
    TheGreatestSage bird = new Bird(sage);
    //bird.move();
    
    TheGreatestSage fish = new Fish(bird);
    //fish.move();
    
    /**
     * 多层封装
     */
    TheGreatestSage fish2 = new Fish(new Bird(sage));
    fish2.move();
  }

}

这种方式是否似曾相识 ?

大家回忆一下JDK中的io流的创建方式是否也是如此。一个InpuStream的简单结构如下:

new BufferedReader(new FileReader("F:\\test.txt"));

三、小结

3.1 适用场景

在以下 情况下可以使用装饰模式:

  • 需要扩展一个类的功能,或者给一个类增加附加责任。
  • 需要动态地给一个对象增加功能,这些功能可以再动态地撤销。
  • 需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变得不现实。

3.2 优点 vs 缺点

优点

  • 装饰模式与继承关系的目的都是扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性。装饰模式允许系统动态地决定“贴上”一个需要的“装饰”,或者去除一个不需要的“装饰”。而继承关系则不同,继承关系是静态的,它在系统运行前就决定了,运行时是不能改变的。
  • 装饰者模式不试图在一个复杂的可定制的类中支持所有可预见的特性。相反你可以定义一个简单的类,并且使用Decorator类给它逐渐的添加功能。可以从一个简单的部件组合出复杂的功能。可以创造出出很多不同行为的组合。

缺点

  • 使用装饰模式会产生比使用继承关系更多的对象,这些对象看上去类似。更多的对象会使得查错变得困难,特别是这些对象看上去都很相像。
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-09-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 孟君的编程札记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档