加入收藏 | 设为首页 | 会员中心 | 我要投稿 沧州站长网 (https://www.0317zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

Java 装饰器模式分析

发布时间:2021-12-08 18:34:36 所属栏目:教程 来源:互联网
导读:前言 在前几篇文章中,着重介绍了Java 中常见的 IO 相关知识,在学习的过程中,发现 IO 包中是用了大量的装饰器模式,为了彻底的学习 IO,今天就来揭开装饰器模式的面纱。 为了弄明白装饰器模式的本质,我查看了很多资料,发现有很多文章要么说的很苦涩,要

前言
在前几篇文章中,着重介绍了Java 中常见的 IO 相关知识,在学习的过程中,发现 IO 包中是用了大量的装饰器模式,为了彻底的学习 IO,今天就来揭开装饰器模式的面纱。
 
为了弄明白装饰器模式的本质,我查看了很多资料,发现有很多文章要么说的很苦涩,要么举的例子不恰当。
 
其实我们可以这样理解装饰器模式, 就拿自己举例子,你把自己裸体的样子,想象成被装饰的对象。你的鞋子,你的寸衣,你的外套,你的手表,你的帽子 等等,都是你的装饰物,你和这些装饰物,是装饰和被装饰的关系。
 
实例展示
好了,现在我们用代码的方法去理解这样概念。
 
首先,我们发现,不管是裸体的人,还是你的鞋子、帽子,都有展示的功能,我们称之为show 方法。
 
我们定义一个接口,它具有展示的功能,也就是show() ,
 
package com.user;
 
/**
 * 定义接口
 * @author T
 *
 */
public interface AbstractPerson {
 
    //具有展示的功能
    void show() ;
}
现在应该定义一个裸体的自己了,Me 类
 
package com.user;
 
/**
 * 定义一个具体的人,就是被装饰者
 * @author T
 *
 */
public class Me implements AbstractPerson {
 
    @Override
    public void show() {
        System.out.println( "什么都没穿,我展示的是裸体");
    }
 
}
下面该定义,鞋子,帽子,手表等 装饰物,等等先别急,我们应该先定义一个鞋子,帽子,手表的抽象父类 AbstractClothes 。 其实抽象的父类有一个构造函数,构造函数里面的参数是抽象的人类,这里的用法很巧妙,这也是能够实现装饰功能的一个必不可少的步骤。
 
package com.user;
 
/**
 * 定义抽象装饰物
 * @author T
 *
 */
public abstract class AbstractClothes implements AbstractPerson {
 
    AbstractPerson abstractPerson ;
 
    public AbstractClothes( AbstractPerson abstractPerson ){
        this.abstractPerson = abstractPerson ;
    }
 
    @Override
    public void show() {
        abstractPerson.show();
    }
 
}
 下面开始定义,帽子装饰物  Hat 类, 继承 AbstractClothes 类
 
package com.user;
 
/**
 * 帽子装饰物
 * @author T
 *
 */
public class Hat extends AbstractClothes {
 
    public Hat(AbstractPerson abstractPerson) {
        super(abstractPerson);
    }
    
    @Override
    public void show() {
        super.show();
        say();
    }
    
    public void say(){
        System.out.println( "我展示一个帽子");
    }
 
}
定义鞋子装饰类 Shoes ,   继承 AbstractClothes 类
 
package com.user;
 
/**
 * 鞋子装饰物
 * @author T
 *
 */
public class Shoes extends AbstractClothes {
 
    public Shoes(AbstractPerson abstractPerson) {
        super(abstractPerson);
    }
    
    @Override
    public void show() {
        super.show();
        say();
    }
    
    public void say(){
        System.out.println( "我展示一双鞋子");
    }
}
创建测试类 Test
 
package com.user;
 
public class Test {
 
    public static void main(String[] args) {
 
        //创建被装饰者
        Me me = new Me() ;
 
        //裸体的人被装饰了帽子 ,具有了展示帽子的能力
        Hat hat = new Hat( me ) ;
 
        // 带了帽子的人被装饰了鞋子,具有了展示鞋子的本领
        Shoes shoes = new Shoes( hat ) ;
 
        shoes.show();
    }
}
复制代码
 运行结果:
 
什么都没穿,我展示的是裸体
我展示一个帽子
我展示一双鞋子
装饰器模式的类图
在学习完了一个小例子之后,我们试着总结出装饰器模式的类图。
 
装饰器模式类图:
 
Java 装饰器模式详解
 
Component抽象构件角色:真实对象和装饰对象有相同的接口。这样,客户端对象就能够以与真实对象相同的方式同装饰对象交互。
ConcreteCompoent具体构建角色(真实对象):定义一个将要接收附加责任的类。
Decorator装饰角色:持有一个抽象构件的引用。装饰对象接受所有客户端的请求,并把这些请求转发给真实的对象。这样,就能在真实对象调用前后增加新的功能。
ConcreteDecorate具体装饰角色:负责给构件对象增加新的功能。
装模式在Java I/O库中的应用
IO流实现细节:
 
Component抽象构件角色:io流中的InputStream,OutputStream,Reader,Writer
ConcreteComponent具体构件角色:io流中的FileInputStream,FileOutputStream
Decorate装饰角色:持有抽象构件的引用,FilterInputStream,FilterOutputStream
ConcreteDecorate具体装饰角色:负责给构件对象添加新的责任,BufferedInputStream,BufferedOutputStream等
优点
 扩展对象功能,比继承灵活,不会导致类个数急剧增加。
可以对一个对象进行多次装饰,创造出不同行为的组合,得到功能更加强大的对象。
具体构件��和具体装饰类可以独立变化,用户可以根据需要自己增加新的 具体构件子类和具体装饰子类。
缺点
产生很多小对象。大量小的对象占据内存,一定程度上影响性能。
装饰模式易出错,调试排查比较麻烦。
总结
装饰模式(Decorate)也叫包装模式(Wrapper)
装饰模式降低系统的耦合度,可以动态的增加或删除对象的责任,并使得需要装饰的具体构建类和具体装饰类可以独立变化,以便增加新的具体构建类和具体装饰类。

(编辑:沧州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读