java常用设计模式(四)装饰者模式

  设计模式第四篇,装饰者模式,大家多多指教。

 简介

  装饰者模式是动态的将责任附加到对象上(引自《Head First设计模式》)。这里的重点在于动态这两个字,我们都知道继承的实现的方式,它是是类编译的时候就去加载文件,属于一种静态的附加,而我们要实现动态的附加就不能单纯的通过继承来实现。在这种背景下,装饰者模式就应运而生了。装饰者模式的实现:首先所有的类都有一个共同的抽象,这个抽象可以是一个抽象类,也可以是一个接口,所有的类该抽象的子类或者实现。语言描述比较抽象,下面我们通过一个例子来描述该模式。

 例子

  我们举一个吃火锅的例子,根据装饰者模式的特点:

  首先我们要有个共同的抽象,这里我们通过接口来实现,这个接口我们称之为锅底。  

/*
 * 锅底
 */
public interface Hotpot {
    /** 描述 */
    String getName();
    /** 价格 */
    Double getPrice();

}

  第二步,我们设计具体的锅底类,我们分为酱香锅、香辣锅和清汤锅,这是底锅,每笔单都必须有且只有一个。

public class JamHotpot implements Hotpot{
    @Override
    public String getName() {
        return "酱香锅";
    }

    @Override
    public Double getPrice() {
        return 4.0;
    }
}

public class SpicyHotpot implements Hotpot{
    @Override
    public String getName() {
        return "香辣锅";
    }

    @Override
    public Double getPrice() {
        return 4.0;
    }
}

public class ClearSoupHotpot implements Hotpot{
    @Override
    public String getName() {
        return "清汤锅";
    }

    @Override
    public Double getPrice() {
        return 3.0;
    }
}

  第三步,我们新增一个配菜接口,继承共同的接口锅底,这个接口用来作为所有配菜的父级,该接口可以拓展所以配菜的共有属性

/*
 * 配菜
 */
public interface SideDish extends Hotpot {
    //可拓展配菜的公共属性
}

  第四步,我们需要新增具体的配菜类,这里的配菜类我们注意到比锅底类多了成员变量和构造方法,而且getName和getPrice方法多了加了传入参数,这个就是为了动态的去附加功能,具体怎么实现参考最后一步。

/*
 * 牛肉
 */
public class Beef implements SideDish {

    private Hotpot hotpot;

    public Beef(Hotpot hotpot) {
        this.hotpot = hotpot;
    }

    @Override
    public String getName() {
        return hotpot.getName() + ",牛肉";
    }

    @Override
    public Double getPrice() {
        return hotpot.getPrice() + 38.0;
    }
}

/*
 * 生菜
 */
public class Lettuce implements SideDish {

    private Hotpot hotpot;

    public Lettuce(Hotpot hotpot) {
        this.hotpot = hotpot;
    }

    @Override
    public String getName() {
        return hotpot.getName() + ",生菜";
    }

    @Override
    public Double getPrice() {
        return hotpot.getPrice() + 8.0;
    }
}

  最后我们测试:

public class DecoratorTest {

    public static void main(String[] args) {
        System.out.println("=======酱香锅底加牛肉");
        Hotpot hotpot = new JamHotpot();
        hotpot = new Beef(hotpot);
        hotpot = new Lettuce(hotpot);
        System.out.println("===火锅的价格为:" + hotpot.getPrice() + "元");
        //如果我们需要更多的配菜参考上面的方式去添加更多的配菜
    }
}

 总结

  如上面所描写的那样,我只需要前台传递给我们所点的锅底和配菜,我们后台去动态的生成一个新的火锅对象。这么设计的好处的拓展极其方便,就算这个火锅店加了新的锅底,或者是配菜,对我们之前的代码是没有任何影响的,这就是所谓的开闭原则(对拓展开放,对修改关闭),后面我们会讲到设计模式相应的原则。除了上面的好处之外,装饰者模式也有他本身不能忽视的问题,那就是每次生成一笔订单都会生成很多小对象,如果该笔单对象很多的话,对我们的内存是个不小的考验,而且过多的小类会让我们的系统变得很复杂,让人很难以理解。所以装饰器模式有利有弊(更多的是利大于弊),我们可以好好思考装饰者模式应用场景,然后进一步掌握这种设计思想。

 番外

  想了解装饰者模式的更多详细信息可以通过jdk源码或者spring源码去了解。jdk中IO操作就有通过装饰者模式实现的,FilterInputStream和它的实现就是一个装饰者模式,同样的在spring源码中,凡事以Decorator结尾的类都是实现的装饰者模式,当然不是所有的装饰器模式都是以Decorator结尾的。

原文地址:https://www.cnblogs.com/blue-and-white/p/11078991.html

时间: 2024-11-03 00:09:51

java常用设计模式(四)装饰者模式的相关文章

java常用设计模式四:建造者模式

1.定义 是一种对象构建的设计模式,它可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象. 产品类:一般是一个较为复杂的对象,也就是说创建对象的过程比较复杂,一般会有比较多的代码量.产品类可以是一个具体的类,也可以是由一个抽象类与它的不同实现组成,也可以是由多个抽象类与他们的实现组成. 抽象建造者:引入抽象建造者的目的,是为了将建造的具体过程交与它的子类来实现.这样更容易扩展.一般至少会有两个抽象方法,一个用来建造产品,一个是用来返回产品.

Java常用的设计模式07:常用设计模式之装饰器模式

1. Java之装饰器模式(Decorator Pattern) (1)概述:     装饰模式在Java种使用也很广泛,比如我们在重新定义按钮.对话框等时候,实际上已经在使用装饰模式了.在不必改变原类文件和使用继承的情况下,动态    地扩展一个对象的功能.它是通过创建一个包装对象,也就是装饰来包裹真实的对象.     装饰者模式:动态地给一个对象添加一些额外的职责,就像在墙上刷油漆一样.就增加功能来说,Decorator模式比生成子类更为灵活. Decorator模式的工作原理是:可以创建始

常用设计模式:装饰者模式

今天看了一篇很棒的介绍装饰者模式的文章,于是就按照以往的惯例,学习了之后手动的码了这么一篇随记记录自己的体会,并且参考原文的例子,自己手动的实现了一遍整个demo,原文地址为:http://blog.csdn.net/zhaoyanjun6/article/details/56488020 首先我们来大体了解一下装饰者模式究竟是个什么东西呢?所谓的装饰者,可以参考现在很火的一个游戏--绝地大逃杀里头的枪械自由改装的概念来解释装饰者模式的概念.现在有这么一把AK47枪,除了枪之外,没有任何以外的配

JAVA基础——设计模式之装饰者模式

装饰模式 对新房进行装修并没有改变房屋的本质,但它可以让房子变得更漂亮.更温馨.更实用. 在软件设计中,对已有对象(新房)的功能进行扩展(装修). 把通用功能封装在装饰器中,用到的地方进行调用. 装饰模式是一种用于替代继承的技术,使用对象之间的关联关系取代类之间的继承关系.引入装饰类,扩充新功能. 角色 抽象构件 具体构件 抽象装饰类 具体装饰类 案例一,窗体装饰 1.组件类 package Decorator; // 装饰者模式 /** * Created by Jiqing on 2016/

java常用设计模式之 工厂模式

工厂模式: 定义 一个用于创建对象的接口,让子类决定实例化哪一个类. 一句话概括: 是一个类的实例化延迟到其子类.     适用于 以下情况: ①:当一个类 ,不知道它所必须创建的对象的类的时候. ②:当一个类,希望由它的子类来指定它所创建的对象的时候. ③:当类将创建对象的职责给多个帮助子类中的一个,并且希望将哪一个帮助子类是代理这一信息局部化的时候. 说明: ① Product :定义工厂方法所创建的对象的接口. ② ConcreteProduct:实现Product 接口. ③ Creat

java设计模式之 装饰器模式

适AT java设计模式之 装饰器模式 装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构. 这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,动态给一个对象添提供了额外的功能. 我们通过下面的实例来演示装饰器模式的用法.模拟一个人从想吃饭.找饭店.享受美食.结束吃饭的过程 代码展示: 首先创建一个被修饰的接口 Eat package deco

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

流概述 Java中,流是一种有序的字节序列,可以有任意的长度.从应用流向目的地称为输出流,从目的地流向应用称为输入流. Java的流族谱 Java的 java.io 包中囊括了整个流的家族,输出流和输入流的谱系如下所示: InputStream和OutputStream InputStream和OutputStream分别是输入输出流的顶级抽象父类,只定义了一些抽象方法供子类实现. 在输出流OutputStream中,如果你需要向一个输出流写入数据,可以调用 void write(int b)

设计模式之装饰者模式(Decorator)

1.定义 装饰者模式动态地将责任附加到对象上.若要扩展功能,装饰者提供了比继承更有弹性的替代方案 2.类图 Component抽象构件:Component是一个接口或者是抽象类,就是定义我们最核心的对象,也就是最原始的对象.在装饰者模式中,必然有一个最基本.最核心.最原始的接口或抽象类充当Component抽象构件. ConcreteComponent具体构件:ConcreteComponent是最核心.最原始.最基本的接口或抽象类的实现,你要装饰的就是它. Decorator装饰角色:一般是一

设计模式之装饰者模式(三)

欢迎大家的持续关注.上一次,我们结合第一篇推导出来的类图,到第二篇根据类图进行实际代码的编写,对装饰者模式有了一个整体的概念以及实战.不知道对你帮助如何呢?小编已经有门道了,看完接下来的一部分,你会恍然大悟,原来实际编码中你一直在用装饰者模式. 真实世界的装饰者:Java I/O 看到标题,是不是就很想往下看,到底是I/O中的什么呢,让你早已经拥有了装饰者模式的实践?就如书上给的描述,你第一次(还有第二次和第三次)看到这些API发出"哇"的惊叹时,放心,你不是唯一收到惊吓的人.下面,我

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

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