【设计模式】装饰者模式-明月装饰了你的窗子

装饰者模式

  使用装饰者模式,可以动态的给一个对象添加一些额外的职责。这适用于,我们只希望给某个对象而不是整个类添加一些功能的场景。通过使用含有某个特定功能的类来“包裹”原始的类,提供给原始的类某些它本身不具备的特性。比如,我们有一杯“茉莉茶”,现在加上一颗“柠檬”,那我们就有了一杯“柠檬茉莉花茶”。“柠檬”作为一个装饰者,提供了“茉莉茶”本身没有的清爽口感。当然,这也带来了一定的负担,你需要花更多的“钱”。

1. 定义

  装饰者模式动态地将职责附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的解决方案。

2. 为什么需要

  装饰者提供了继承更高的灵活性。可以使用继承来实现将父类的功能添加到子类中,但是这种方式限制了用户选择的权利,没有办法选择将父类的哪些功能添加到子类中,只能被动的接受父类所有的功能。作为一个类而言,拥有更多的功能并不一定是件好事。所有的类都不应该试图成为一个“全栈“。装饰者模式则刚好提供了用户选择的权利,用户可以”谨小慎微“的选择自己需要的功能,而不用为自己不需要的功能去买单。

  该模式的实现方式,也被它的名字清楚的表达。

  装饰。

3. 实现方案

  3.1 实现注意点

  1. 接口一致性。装饰对象的接口必须与它所装饰的类的接口是一致的。体现了“装饰”过程不能改变对象的“本质”
  2. 省略抽象的装饰者类。
  3. 改变对象的外壳。装饰者Decorator可以被看做是一个对象的外壳,它可以改变对象的行为。

  3.2 实现代码

  参与者:

  1. 一个 抽象类Tea ,用于表示茶的最顶层类。
  2. 一个具体类 JasmineTea ,表示茶的一种,茉莉茶。
  3. 一个抽象类 TeaDecorator  ,表示茶的装饰者。用于向茶中加入不同的配料。
  4. 一个具体类 Lemon ,继承 TeaDecorator ,表示可以向茶中加入的配料,柠檬。

  抽象类 Tea 实现代码如下:

/*
    为一个抽象类,所有的茶都需要直接或间接的继承它
 */
public abstract class Tea {

    private String description = "tea";

    public String getDescription() {
        return description;
    }
}

  

  具体类 JasmineTea 实现代码如下:

/**
 * 现在小店只提供一种茶,茉莉茶。
 *
 * 可以向它添加不同的茶调料,搭配不同的口味
 */
public class JasmineTea extends Tea {

    @Override
    public String getDescription() {
        return "jasmine tea";
    }
}

  小店刚开业,只提供茉莉花茶,请多担待。不过,我们提供了配料可以搭配不同的口味。

  先需要提供一个 TeaDecorator 的抽象类,它可以提供不同的配料,实现代码如下:

/*
    茶的装饰者,比如凉茶,柠檬茶等
 */
public abstract class TeaDecorator extends Tea{

    public abstract String getDescription();
}

  接下来,则是本店现今提供的唯一调料,柠檬,实现代码如下:

/*
    这是一个“茶”的装饰者,表示在茶中加入柠檬
 */
public class Lemon extends TeaDecorator {

    private Tea tea;

    /**
     * 注意:这里需要传入“一杯茶”,也就是要“被装饰”的对象
     * 这里的语义:有一杯茶,需要向茶中加入柠檬。
     * 理所当然的,柠檬就是一个“装饰者”
     */
    public Lemon(Tea tea) {
        this.tea = tea;
    }

    public String getDescription() {
        return "lemon " + tea.getDescription();
    }
}

  好!小店已经准备好了茶,也准备好了调料。那是时候给各位客观端上一杯沁人心脾的“柠檬茉莉花茶”了,代码实现如下:

public class App {

    public static void main(String[] args) {

        Tea jasmineTea = new JasmineTea(); // 先冲一杯清香的茉莉茶
        Tea lemonJasmineTea = new Lemon(jasmineTea); // 然后向茶中加入一颗柠檬

        System.out.println(lemonJasmineTea.getDescription()); // 一杯生津止渴的 “lemon jasmine tea” 就泡好了
    }
}

  端上一杯“柠檬茉莉花茶”,就着网易云音乐,看着“四人帮”的设计模式,岂不美哉!

4. 总结  

  装饰者的主要特点在于在不影响其他对象的情况下,可以动态的给单个对象添加职责。关于这点,我们可以参考JDK中的 java.io 包,它是使用装饰者模式的典型场景。装饰者模式有如下优点:

  1. 相比静态继承提供了更大的灵活性。它可以在运行时增加和删除职责。此外,可以很容易的重复添加一个特性。
  2. 避免了在层次结构高层的类有太多的特性。它不在一个类中支持所有的特性,每个装饰者类可以只有一个特性。可以从简单的部件复合出复杂的功能。

  使用该模式也会引入一些问题:

  1. 有许多小的对象。过多的对象会使得有些人反感,反正我个人还是挺喜欢小的函数、类、模块...

  装饰的内涵在于不改变原有本质的前提下提供原来没有的功能。我们需要区分哪些是需要被装饰的,而哪些是装饰者。更多的时候是,我们装饰着别人,同时又被别人所装饰。

  正所谓:明月装饰了你的窗子,你装饰了别人的梦...

  好梦!

时间: 2024-10-06 00:10:52

【设计模式】装饰者模式-明月装饰了你的窗子的相关文章

Java进阶篇设计模式之五-----外观模式和装饰器模式

前言 在上一篇中我们学习了结构型模式的适配器模式和桥接模式.本篇则来学习下结构型模式的外观模式和装饰器模式. 外观模式 简介 外观模式隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口.这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性. 简单的来说就是对外提供一个简单接口,隐藏实现的逻辑.比如常用电脑的电源键,我们只需按电源键,就可以让它启动或者关闭,无需知道它是怎么启动的(启动CPU.启动内存.启动硬盘),怎么关闭的(关闭硬盘.关闭内存.关闭CPU)

java/android 设计模式学习笔记(7)---装饰者模式

这篇将会介绍装饰者模式(Decorator Pattern),装饰者模式也称为包装模式(Wrapper Pattern),结构型模式之一,其使用一种对客户端透明的方式来动态的扩展对象的功能,同时它也是继承关系的一种替代方案之一,但比继承更加灵活.在现实生活中也可以看到很多装饰者模式的例子,或者可以大胆的说装饰者模式无处不在,就拿一件东西来说,可以给它披上无数层不一样的外壳,但是这件东西还是这件东西,外壳不过是用来扩展这个东西的功能而已,这就是装饰者模式,装饰者的这个角色也许各不相同但是被装饰的对

java设计模式------装饰着模式

java设计模式-------装饰者模式 装饰者模式 Decorator模式(别名Wrapper):动态将职责附加到对象上,若要扩展功能,装饰者提供了比继承更具弹性的代替方案.主要有组件(components)和装饰器(Decorator)组成.要求components和Decorator实现相同的接口或者抽象类(具体类的局限性太大). 设计原则.模式特点.适用性 - 1. 多用组合,少用继承. 利用继承设计子类的行为,是在编译时静态决定的,而且所有的子类都会继承到相同的行为.然而,如果能够利用

Java设计模式——装饰者模式

JAVA 设计模式 装饰者模式 用途 装饰者模式 (Decorator) 动态地给一个对象添加一些额外的职责.就增加功能来说,Decorator 模式相比生成子类更为灵活. 装饰者模式是一种结构式模式. 结构 图-装饰者模式结构图 Component : 定义一个对象接口,可以给这些对象动态地添加职责. interface Component {     public void operation(); } ConcreteComponent : 实现 Component 定义的接口. clas

Java设计模式(四) 装饰器模式 代理器模式

(七)装饰器模式 Decorator 装饰器模式是为了动态的给一个对象增加一些新功能.装饰对象与被装饰的对象需要实现同一个接口,装饰对象持有被装饰对象的实例. interface DecoratorSourceable{ public void method(); } //被装饰类 class DecoratorSource implements DecoratorSourceable{ public void method(){ System.out.println("Source"

HeadFirst设计模式 之 C++实现(三):Decorator(装饰者模式)

装饰者模式是很有意思的一种设计模式,你将能够在不修改任何底层代码的情况下,给你的(或别人的)对象赋予新的职责.不是使用继承每回在编译时超类上修改代码,而是利用组合(composition)和委托(delegation)可以在运行时具有继承行为的效果. 代码应该如同晚霞中的莲花一样地关闭(免于改变),如同晨曦中的莲花一样地开放(能够扩展). 这就是,设计原则之五:类应该对扩展开放,对修改关闭. 通常情况下,我们不会对代码的每一处设计都采用该原则,我们实在没有闲工夫把设计的每个部分都这么设计(而且,

javascript设计模式——装饰者模式

前面的话 在程序开发中,许多时候都并不希望某个类天生就非常庞大,一次性包含许多职责.那么可以使用装饰者模式.装饰者模式可以动态地给某个对象添加一些额外的职责,而不会影响从这个类中派生的其他对象.本文将详细介绍装饰者模式 概念 在传统的面向对象语言中,给对象添加功能常常使用继承的方式,但是继承的方式并不灵活,还会带来许多问题:一方面会导致超类和子类之间存在强耦合性,当超类改变时,子类也会随之改变:另一方面,继承这种功能复用方式通常被称为“白箱复用”,“白箱”是相对可见性而言的,在继承方式中,超类的

设计模式篇——初探装饰器模式

文章目录 1.装饰器模式介绍 2.装饰器模式类图 3.装饰器模式Demo实现(一个小镇的拉面馆) 4.装饰器模式总结 装饰器模式介绍:装饰器模式可以在不修改任何底层代码的情况下,给对象赋予新的职责(程序运行时的扩展,动态的将责任附加到对象上).属于结构型设计模式. 类图: 我们来看下装饰器模式的类图: 一个简单的Demo(故乡小镇的一个面馆): 在故乡的一个小镇上面,有一家面馆,主营拉面.在这里你可以只点清汤面(SoupNoodle),也可以往里面加佐料,佐料有牛肉(Beef),鱼丸(FishB

掌握设计模式之装饰者模式

![](http://ww4.sinaimg.cn/large/006tNc79ly1g4ztauvhzej30p00dw45p.jpg) ## 前言 当应用开发中,我们要为一个对象在原有功能上进行扩展增强时,往往采用继承的方式,而继承过多时就会使得功能类更加复杂,不利于维护,而设计模式中装饰者模式可以帮助我们更好对应这种场景,装饰者模式可以做到让对象能够动态地进行功能扩展,而不影响其他对象. 那究竟它是如何实现的呢,又如何实际应用呢,就让我们一起来学习下这个模式吧. ## 模式定义 装饰者模式