0%
这是一片思考的空间 -- arthinking
Spring 重构&代码整洁之道 软件设计 JVM 并发编程 数据结构与算法 分布式 存储 网络 微服务 设计模式
Java技术栈 - 涉及Java技术体系

设计模式笔记 - Decorator 装饰模式 (Design Pattern) 及其在JavaIO流系统中的运用

1、装饰模式(Decorator):

动态地给一个对象天剑一些额外的职责,就增加功能来说,装饰模式比生成子类更加灵活。

装饰模式是以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。

动态方式给一个对象附加更多的功能。

装饰模式可以在不创造更多的子类的情况下扩张对象的功能。

2、装饰模式的角色:

抽象构件角色(Component):定义一个对象接口,可以给这些对象动态地添加职责。 具体构件角色(Concrete Component):定义了一个具体的对象,也可以给这个对象添加一些职责。

装饰角色(Decorator):装饰抽象类。

具体装饰角色(Concrete Decorator):具体的装饰对象,起到给Component添加职责的功能。

3、装饰模式的结构图:

4、装饰模式的特点:

装饰角色和构件角色有相同的接口,这样客户端就可以用和构件角色相同的方式和装饰角色交互了。

装饰角色包含一个真实对象的引用。

来自客户端的请求,通过装饰对象接收,转发给真实的构件角色。

装饰对象可以在转发请求之前或之后附加功能。在面向对象设计中,通常是通过继承来实现的。而使用了装饰模式,就可以不用修改给定对象的结构就可以实现了。

5、装饰模式和继承的比较:

装饰模式:

可以扩展对象的功能而不需要额外创建子类。

可以动态添加功能。

防止由于子类而导致复杂的继承结构,更加灵活,方便客户端对功能进行组合使用。

继承:

扩展类对象的功能,需要实现相应的子类。

是静态的,导致出现很多子类,复杂的继承结构,缺乏灵活性。

6、装饰模式在JavaIO流系统中的使用

下面就通过一个装饰模式的基本实现说明装饰模式在JavaIO流系统中的使用。

6.1、首先创建抽象构件角色,这个接口相当于JavaIO中的java.io.InputStream:

1
2
3
4
5
6
7
/**
* 抽象构件角色
*/
public interface Component {

public void operation();
}

6.2、创建一个具体的构件角色实现构件角色接口,这个类相当于JavaIO流的任何一个节点流类,如:java.io 类 FileInputStream:

/**

  • 具体构件角色
    */
    public class ConcreteComponent implements Component {

    @Override
    public void operation() {

     System.out.println("具体的功能");
    

    }
    }

6.3、创建一个装饰角色实现抽象构件角色,这个类相当于JavaIO中的过滤流java.io 类 FilterInputStream:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* 装饰角色
*/
public class Decorator implements Component {

private Component component;

public Decorator(Component component){
this.component = component;
}
@Override
public void operation() {

component.operation();
}
}

6.4、创建一个具体的装饰角色继承装饰角色,可以对继承下来的方法封装其他的操作,这个类相当于JavaIO中的任何一个过滤流,如:java.io 类 BufferedInputStream:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* 具体装饰角色
*/
public class ConcreteDecorator extends Decorator {

public ConcreteDecorator(Component component) {
super(component);
}

@Override
public void operation() {

super.operation();
this.addBehavior();
}

private void addBehavior(){
System.out.println("ok");
}
}

6.5、客户端调用代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Client {

/**
* @param args
*/
public static void main(String[] args) {

//节点流
Component component = new ConcreteComponent();
//过滤流
Component component2 = new ConcreteDecorator(component);
component2.operation();
}
}

欢迎关注我的其它发布渠道

订阅IT宅
内功修炼
Java技术栈
Java架构杂谈是IT宅精品文章公众号,欢迎订阅:
📄 网络基础知识:两万字长文50+张趣图带你领悟网络编程的内功心法 📄 HTTP发展史:三万长文50+趣图带你领悟web编程的内功心法 📄 HTTP/1.1:可扩展,可靠性,请求应答,无状态,明文传输 📄 HTTP/1.1报文详解:Method,URI,URL,消息头,消息体,状态行 📄 HTTP常用请求头大揭秘 📄 HTTPS:网络安全攻坚战 📄 HTTP/2:网络安全传输的快车道 📄 HTTP/3:让传输效率再一次起飞 📄 高性能网络编程:图解Socket核心内幕以及五大IO模型 📄 高性能网络编程:三分钟短文快速了解信号驱动式IO 📄 高性能网络编程:彻底弄懂IO复用 - IO处理杀手锏,带您深入了解select,poll,epoll 📄 高性能网络编程:异步IO:新时代的IO处理利器 📄 高性能网络编程:网络编程范式 - 高性能服务器就这么回事 📄 高性能网络编程:性能追击 - 万字长文30+图揭秘8大主流服务器程序线程模型
📄 Java内存模型:如果有人给你撕逼Java内存模型,就把这些问题甩给他 📄 一文带你彻底理解同步和锁的本质(干货) 📄 AQS与并发包中锁的通用实现 📄 ReentrantLock介绍与使用 📄 ReentrantReadWriteLock介绍与使用 📄 ReentrantLock的Condition原理解析 📄 如何优雅的中断线程 📄 如何优雅的挂起线程 📄 图解几个好玩的并发辅助工具类 📄 图解BlockingQueue阻塞队列
📄 消息队列那么多,为什么建议深入了解下RabbitMQ? 📄 高并发异步解耦利器:RocketMQ究竟强在哪里? 📄 Kafka必知必会18问:30+图带您看透Kafka
📄 洞悉MySQL底层架构:游走在缓冲与磁盘之间 📄 SQL运行内幕:从执行原理看调优的本质 📄 洞悉Redis技术内幕:缓存,数据结构,并发,集群与算法