- 使用 Spring Initializr 创建 Spring Boot 应用程序
- 在Spring Boot中配置Cassandra
- 在 Spring Boot 上配置 Tomcat 连接池
- 将Camel消息路由到嵌入WildFly的Artemis上
装饰模式是指在不影响原有对象的情况下,动态地、无侵入地给一个对象添加一些额外的功能,如下这条 I/O 语句。
InpurStreamReader iReader = new InputStreamReader(new FileInputStream(new File("D:\abc.txt")));
如果把 D:\abc.txt 看作被装饰的对象,以上语句就依次对该对象进行了以下3步的包装。
new File("D:\abc.txt") 将字符串对象包装成了一个 File 对象,此时 File 对象包含了原字符串的内容。
new FileInputStream(...) 将 File 对象包装成了一个 FileinputStream 对象,此时 FileInputStream 包含了原 File 对象和原字符串的内容。
new InputStreamReader(...) 将 FileinputStream 对象包装成了一个 InputStreamReader 对象,此时 InputStreamReader 包含了原 FileInputStream 对象、原 File 对象和原字符串的内容。
可以发现,装饰模式可以让原对象经过一次次的包装,逐步拥有更强大的功能。因此在开发时,可以通过装饰模式对各个功能进行模块化封装。例如,如果要给对象 A 依次增加 X、Y 两个功能,就只需要对 A 进行两次包装即可。在 I/O 的设计中就大量使用到了这种装饰模式。
装饰模式包含了以下两个角色
1)抽象构建角色(Component)
被装饰对象的抽象接口。后续可以通过装饰者对该对象进行动态装饰。
2)具体构件角色(ConcreteComponent)
具体的对象,即抽象构建的一个实现类。
1)装饰角色(Decorator)
装饰抽象类,需要继承自 Component,用于装饰(扩展)Component 中定义的方法。语法上,装饰对象包含了一个对真实对象的引用。
2)具体装饰(ConcreteDecorator)角色:具体的装饰者,即装饰角色的一个实现类。
Phone 接口用于定义手机的基本功能是打电话call(),BasePhone 类是 Phone 的一个实现类,实现了 call() 定义的方法。SmallPhone 是 Phone 的一个装饰者,用于扩展 Phone 的功能。第一种装饰方式为 AISmartPhone,即给电话增加“人工智能”的功能;第二种装饰方式为 AutoSizeSmartPhone,即给电话增加“自动伸缩”的功能。
a 抽象构建角色(Component)
package decorator;
// 抽象构件角色(Component)
public interface Phone {
void call();
}
b 具体构建角色(ConcreteComponent)
package decorator;
// 具体构件角色(ConcreteComponent)
public class BasePhone implements Phone {
@Override
public void call() {
System.out.println("打电话");
}
}
c 装饰角色(Decorator)
package decorator;
// 装饰角色(Decorator)
public abstract class SmartPhone implements Phone {
private Phone phone;
public SmartPhone(Phone phone) {
super();
this.phone = phone;
}
@Override
public void call() {
phone.call();
}
}
d 第一个具体装饰角色(ConcreteDecorator)
package decorator;
public class AISmartPhone extends SmartPhone {
public AISmartPhone(Phone phone) {
super(phone);
}
// 给电话增加新的功能:人工智能
public void aiFunction() {
System.out.println("电话拥有人工智能的强大功能");
}
public void call() {
super.call();
aiFunction();
}
}
e 第一个具体装饰角色(ConcreteDecorator)
package decorator;
public class AutoSizeSmartPhone extends SmartPhone {
public AutoSizeSmartPhone(Phone phone) {
super(phone);
}
// 给电话增加新的功能:手机尺寸自动伸缩
public void autoSize() {
System.out.println("手机的尺寸可以自动伸缩");
}
public void call() {
super.call();
autoSize();
}
}
f 测试类
package decorator;
public class Test {
public static void main(String[] args) {
// 基础的电话功能
System.out.println("--基础的电话功能--");
BasePhone basePhone = new BasePhone();
basePhone.call();
// 进行 AISmartPhone 装饰后的电话
System.out.println("\n--智能手机:增加了AI的功能--");
AISmartPhone AISmartPhone = new AISmartPhone(basePhone);
AISmartPhone.call();
// 进行AutoSizeSmartPhone装饰后的电话
System.out.println("\n--智能手机:增加了自动伸缩的功能--");
AutoSizeSmartPhone autoSizeSmartPhone = new AutoSizeSmartPhone(basePhone);
autoSizeSmartPhone.call();
//进行AISmartPhone及AutoSizeSmartPhone两次装饰后的电话
System.out.println("\n--智能手机:增加了AI和自动伸缩的功能--");
SmartPhone smartPhone = new AutoSizeSmartPhone(new AISmartPhone(basePhone));
smartPhone.call();
}
}
--基础的电话功能--
打电话
--智能手机:增加了AI的功能--
打电话
电话拥有人工智能的强大功能
--智能手机:增加了自动伸缩的功能--
打电话
手机的尺寸可以自动伸缩
--智能手机:增加了AI和自动伸缩的功能--
打电话
电话拥有人工智能的强大功能
手机的尺寸可以自动伸缩
Process finished with exit code 0
实战-行业攻防应急响应 简介: 服务器场景操作系统 Ubuntu 服务器账号密码:root/security123 分析流量包在/home/security/security.pcap 相
背景 最近公司将我们之前使用的链路工具切换为了 OpenTelemetry. 我们的技术栈是: OTLP C
一 同一类的方法都用 synchronized 修饰 1 代码 package concurrent; import java.util.concurrent.TimeUnit; public c
一 简单例子 1 代码 package concurrent.threadlocal; /** * ThreadLocal测试 * * @author cakin */ public class T
1. 问题背景 问题发生在快递分拣的流程中,我尽可能将业务背景简化,让大家只关注并发问题本身。 分拣业务针对每个快递包裹都会生成一个任务,我们称它为 task。task 中有两个字段需要
实战环境 elastic search 8.5.0 + kibna 8.5.0 + springboot 3.0.2 + spring data elasticsearch 5.0.2 +
Win10下yolov8 tensorrt模型加速部署【实战】 TensorRT-Alpha 基于tensorrt+cuda c++实现模型end2end的gpu加速,支持win10、
yolov8 tensorrt模型加速部署【实战】 TensorRT-Alpha 基于tensorrt+cuda c++实现模型end2end的gpu加速,支持win10、linux,
目录如下: 为什么需要自定义授权类型? 前面介绍OAuth2.0的基础知识点时介绍过支持的4种授权类型,分别如下: 授权码模式 简化模式 客户端模式 密码模式
今天这篇文章介绍一下如何在修改密码、修改权限、注销等场景下使JWT失效。 文章的目录如下: 解决方案 JWT最大的一个优势在于它是无状态的,自身包含了认证鉴权所需要的所有信息,服务器端
前言 大家好,我是捡田螺的小男孩。(求个星标置顶) 我们日常做分页需求时,一般会用limit实现,但是当偏移量特别大的时候,查询效率就变得低下。本文将分四个方案,讨论如何优化MySQL百万数
前言 大家好,我是捡田螺的小男孩。 平时我们写代码呢,多数情况都是流水线式写代码,基本就可以实现业务逻辑了。如何在写代码中找到乐趣呢,我觉得,最好的方式就是:使用设计模式优化自己
我们先讲一些arm汇编的基础知识。(我们以armv7为例,最新iphone5s上的64位暂不讨论) 基础知识部分: 首先你介绍一下寄存器: r0-r3:用于函数参数及返回值的传递 r4-r6
一 同一类的静态方法都用 synchronized 修饰 1 代码 package concurrent; import java.util.concurrent.TimeUnit; public
DRF快速写五个接口,比你用手也快··· 实战-DRF快速写接口 开发环境 Python3.6 Pycharm专业版2021.2.3 Sqlite3 Django 2.2 djangorestfram
一 添加依赖 org.apache.thrift libthrift 0.11.0 二 编写 IDL 通过 IDL(.thrift 文件)定义数据结构、异常和接口等数据,供各种编程语言使用 nam
我正在阅读 Redis in action e-book关于semaphores的章节.这是使用redis实现信号量的python代码 def acquire_semaphore(conn, semn
自定义控件在WPF开发中是很常见的,有时候某些控件需要契合业务或者美化统一样式,这时候就需要对控件做出一些改造。 目录 按钮设置圆角
师父布置的任务,让我写一个服务练练手,搞清楚socket的原理和过程后跑了一个小demo,很有成就感,代码内容也比较清晰易懂,很有教育启发意义。 代码 ?
? 1 2
我是一名优秀的程序员,十分优秀!