设计模式之(五)——装饰模式

装饰模式,顾名思义就是对原有的对象进行装饰,添加新的东西。装饰模式可以在不创造更多的子类的模式下,将对象的功能加以扩展。

讲到装饰模式不得不说,java 的 io 就是有利用装饰模式设计。

写两句代码就清楚了。

1、socket编程,读控制台输入的字符,我们会写:

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

2、文件读(写):

 BufferedReader br = new BufferedReader(new FileReader(file));

这里就使用了装饰模式,这其实就是将 InputStreamReader 对象和 FileReader 用BufferedReader 来进行装饰,然后就会得到了一个具有了缓存buff 功能的流读取方式了。

这里我们稍微总结一下。

装饰模式需要几个材料才能实现:

1、 抽象构建角色(Component):无论是抽象类还是接口,这里是 待装饰对象 和添加的 装饰对象 都需要有一个统一的接口实现(或继承)这样才能真正的实现装饰。(java io中如 InputStream/OutputStream 和Reader/Writer类)。

2、 具体的构建角色(ConcreteComponent):实现具体的待装饰的对象。我们都需要一个统一的“空白”对象,我们之后是给这个“空白”对象进行装饰,添加功能。(java io中如 FileOutputStream 和 FileInputStream)。

3、装饰角色(Docorator):统一的装饰对象。这里可以认为是定义需要添加的装饰的一个抽象。这里可以根据 装饰的样式不同 定义不同的子类,在进行添加时互不干扰。(装饰的多变可以有)。

4、具体的装饰角色(ConcreteDecorator):真正意义上的装饰,即添加的功能对象。(java io中如 BufferedOutputStream 和 BufferedInputStream,DataOutputStream 和 DataInputSrtream)。

这里我们来解释下,如图:

这里 有一个 待装饰ConcreteComponent 只有装饰 Docorator 后才能形成一个整体 Component

然而可能我们需要装饰的功能不止一个,这是我们需要将功能 抽象成一个装饰类,然后添加功能时可以根据需要进行添加 装饰A 或者 装饰B 或者两者都加(两者都加和上一层的装饰类似)。

举个例子:

interface Component {
    public void doSth();
}

class ConcreteComponent implements Component {
    @Override
    public void doSth() {
        System.out.println("功能X");
    }
}

class Decorator implements Component {
    private Component component;

    public Decorator(Component component) {
        this.component = component;
    }

    @Override
    public void doSth() {
        component.doSth();
    }
}

class ConcreteDecoratorA extends Decorator {
    public ConcreteDecoratorA(Component component) {
        super(component);
    }

    @Override
    public void doSth() {
        super.doSth();
        System.out.println("功能A");
    }
}

class ConcreteDecoratorB extends Decorator {
    public ConcreteDecoratorB(Component component) {
        super(component);
    }

    @Override
    public void doSth() {
        super.doSth();
        System.out.println("功能B");
    }
}

public class Test {
    public static void main(String[] args) {
        Component component = new ConcreteDecoratorA(
                              new ConcreteDecoratorB(
                              new ConcreteComponent()));
        component.doSth();
    }
}

运行结果就是在实现自身功能的同时实现了添加的功能。如图:

这里就是先将 B 的的功能装饰上去,然后将 A 的功能装饰上去,这样就形成了新的类,同时实现 X,B,A 的功能。

不过这里的装饰类是比较通常的实现方法,这里也有简洁的实现方式,正如我上面说的那样,比如 :

1、直接在 带装饰类 中添加功能时,就不需要接口(抽象类)Component 。只需添加的装饰是带装饰类的子类即可。

2、装饰添加的只有一个对象功能时我们可以不需要 装饰类的抽象层 Decorator

那么现在,我们再回头再看看java 的 io。

public abstract class Reader 

public class BufferedReader extends Reader

public class InputStreamReader extends Reader 

public class FileReader extends InputStreamReader

BufferedReader br = new BufferedReader(new FileReader(file));

我们可以看到 上述 BufferedReader ,InputStreamReader ,FileReader 的祖先都是 Reader。

然后 FileReader 用 BufferedReader 来装饰就形成了一个具有存储缓冲区的文件流读的功能了。

从上述 讲解的装饰模式可以看出来,这就是使用装饰模式实现功能的添加。让数据以流的形式输入输出,然后存放在缓存区内进行接下来的操作。

只要弄懂了装饰模式的意思,具体的实现可以根据需要实现功能的添加。

水平有限,不吝赐教。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-19 11:42:58

设计模式之(五)——装饰模式的相关文章

Java设计模式(五)外观模式 桥梁模式

(九)外观模式 外观模式为子系统提供一个接口,便于使用.解决了类与类之间关系的,外观模式将类之间的关系放在一个 Facade 类中,降低了类类之间的耦合度,该模式不涉及接口. class CPU { public void startup(){ System.out.println("cpu start"); } public void shutdown(){ System.out.println("cpu stop"); } } class Memory { pu

设计模式(五):PROTOTYPE原型模式 -- 创建型模式

1.定义 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 2.适用场景 原型模式的主要思想是基于现有的对象克隆一个新的对象出来,一般是有对象的内部提供克隆的方法,通过该方法返回一个对象的副本,这种创建对象的方式,相比我们之前说的几类创建型模式还是有区别的,之前的讲述的工厂模式与抽象工厂都是通过工厂封装具体的new操作的过程,返回一个新的对象,有的时候我们通过这样的创建工厂创建对象不值得,特别是以下的几个场景的时候,可能使用原型模式更简单也效率更高. • 1)当一个系统应该独立于

设计模式(五) : 创建型模式--建造者模式

建造者模式的意图是将产品的内部表象和产品的生产过程分割开来. 类图: 示意性代码: package com.javadesignpattern.builder; public interface Builder { public void buildPart1(); public void buildPart2(); public Product retrieveProduct(); } ? 1 2 3 4 5 6 7 package com.javadesignpattern.builder;

【读书笔记】设计模式第五章:行为型模式

本文主要分析了模板方法模式.命令模式.责任链模式.策略模式.迭代器模式,介绍它们的定义.优缺点.使用场景,以及实例代码.为了深刻地理解设计模式,最重要的还是动手编写代码. 我参照书中的例程重新构想了一些更加生动.易于理解的例子,希望大家喜欢. 代码可以通过以下链接进行浏览: http://git.oschina.net/caipeichao/java-design-pattern 这些代码都经过编译运行,保证没有错误. 模板方法 定义 定义一个操作中的算法框架,而将一些步骤延迟到子类中 角色:抽

设计模式 ( 十五 ) 中介者模式Mediator(对象行为型)

设计模式 ( 十五 ) 中介者模式Mediator(对象行为型) 1.概述 在面向对象的软件设计与开发过程中,根据“单一职责原则”,我们应该尽量将对象细化,使其只负责或呈现单一的职责,即将行为分布到各个对象中. 对于一个模块或者系统,可能由很多对象构成,而且这些对象之间可能存在相互的引用,在最坏的情况下,每一个对象都知道其他所有的对象,这无疑复杂化了对象之间的联系.虽然将一个系统分割成许多对象通常可以增强可复用性,但是对象间相互连接的激增又会降低其可复用性,大量的相互连接使得一个对象似乎不太可能

浅谈javascript单体【读javascript设计模式第五章节单体有感】

单体,整个运行环境就独有一份,最简单的一种单体就是一个把所有属性和方法都集中在一起的对象,区别于一般的字面量对象,一般字面量对象是对一个物体的描述,集合该物体所具有的一些属性和方法,而单体则包含更多的些逻辑在里面,单体的好处有,划分命名空间,如果用来作为网页包装器,可以使得页面所有变量都封装在一个对象里,大幅度减小网页里的全局变量, 代码如: common.js (function(wz){ $.extend({ init:function(){ var self = this; this.bi

云计算设计模式(五)——计算资源整合模式

云计算设计模式(五)--计算资源整合模式 合并多个任务或操作成一个单一的计算单元.这种模式可以提高计算资源的利用率,并降低与云托管的应用程序进行计算处理相关的成本和管理开销. 背景和问题 云应用程序频繁执行各种操作.在某些解决方案也可能是有意义的最初遵循的关注点分离的设计原则,并把这些操作成托管和独立部署(例如,如在微软的Azure云服务,独立Azure网站不同的角色独立计算单元或单独的虚拟机).然而,尽管这种策略可以帮助简化溶液的逻辑设计,部署大量计算单元作为同一应用可以提高运行时的托管成本,

设计模式学习之装饰模式:IO流的装饰器

IO流的装饰器 题目分析:通过对java的io系列类分析得知,java的io流使用了设计模式中的装饰模式,以动态的给一个对象增加职责,能够更加灵活的增加功能.通过看io的源代码得知FilterOutputStream类继承了OutputStream类并拥有父类的一个对象,它和父类具有组合聚合的关系.因此要实现我们自己的加密类只需扩展FilterOutputStream类重写它的wite方法即可 UML图: 源代码: package com.cmc import java.io.FilterOut

设计模式(五)学习----装饰模式

装饰设计模式:又名包装模式(Wrapper),以对客户端透明的方式扩展对象的功能,是继承关系的一种替代关系.装饰模式以对客户端透明的方式动态的给一个对象附加上更多的责任.换言之,客户端不会觉得在装饰前和装饰后有什么不同. 下面看装饰设计模式的UML类图: 在装饰模式中的各个角色: 抽象构件Component:给出一个抽象接口,以规范准备接收附加责任的对象. 具体构件角色:ConcreteComponent:定义一个要接收附加责任的类. 装饰角色:Decorator,实现抽象构件的接口,拥有一个抽

《Java设计模式》之装饰模式

装饰模式(Decorator) 1.    装饰模式(Decorator)的定义:又名包装(Wrapper)模式.装饰模式以对client透明的方式扩展对象的功能,是继承关系的一个替代方案. 2.    装饰模式以对client透明的方式动态的给一个对象附加上很多其它的责任.换言之client并不会觉的对象在装饰前和装饰后有什么差别. 3.    装饰模式能够在不创造很多其它的子类的模式下,将对象的功能加以扩展. 4.    装饰模式与类继承的差别: 1)    装饰模式是一种动态行为,对已经存