这是我参与更文挑战的第3天,活动详情查看: 更文挑战
本文正在参加「Java主题月 – Java 开发实战」,详情查看 活动链接
承接上篇,继续来学学其它的设计模式
装饰器模式 Decorator Pattern
概念:允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
这种模式创建了一个装饰类,用来包装原有的类,提供了额外的功能。
优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。
缺点:多层装饰比较复杂。
比如:
小明买衣服的场景
/**
* @author Jin
* @version 1.0
* @date 2021/6/3 14:43
*/
public class DecoratorPatternDemo {
//分别使用 BlueClothesFactoryDecorator和GreenClothesFactoryDecorator 来装饰 ClothesFactory 对象。
public static void main(String[] args) {
ClothesFactory clothesFactory = new Shirt();
ClothesFactoryDecorator blueClothes = new BlueClothesFactoryDecorator(new Shirt());
ClothesFactoryDecorator greenClothes = new GreenClothesFactoryDecorator(new Shirt());
System.out.println("Default colors for clothing");
clothesFactory.production();
System.out.println("\nProducing blue clothes");
blueClothes.production();
System.out.println("\nProducing green clothes");
greenClothes.production();
}
}
// 创建一个接口
interface ClothesFactory {
// 创建一个生产衣服的方法
void production();
}
//创建实现接口的实体类。
class Shirt implements ClothesFactory {
//重写生产衣服的方法
@Override
public void production() {
System.out.println("生产了衬衫");
}
}
// 创建实现了 ClothesFactory 接口的抽象装饰类。
abstract class ClothesFactoryDecorator implements ClothesFactory {
protected ClothesFactory decorateClothesFactory;
public ClothesFactoryDecorator(ClothesFactory clothesFactory){
this.decorateClothesFactory = clothesFactory;
}
@Override
public void production(){
decorateClothesFactory.production();
}
}
// 创建扩展了 ClothesFactoryDecorator 类的实体装饰类(给衣服染蓝色)。
class BlueClothesFactoryDecorator extends ClothesFactoryDecorator {
public BlueClothesFactoryDecorator(ClothesFactory clothesFactory) {
super(clothesFactory);
}
@Override
public void production() {
decorateClothesFactory.production();
setBlue(decorateClothesFactory);
}
private void setBlue(ClothesFactory decoratedClothesFactory){
System.out.println("给衣服染蓝色");
}
}
// 创建扩展了 ClothesFactoryDecorator 类的实体装饰类(给衣服染绿色)。
class GreenClothesFactoryDecorator extends ClothesFactoryDecorator {
public GreenClothesFactoryDecorator(ClothesFactory clothesFactory) {
super(clothesFactory);
}
@Override
public void production() {
decorateClothesFactory.production();
setGreen(decorateClothesFactory);
}
private void setGreen(ClothesFactory decoratedClothesFactory){
System.out.println("给衣服染绿色");
}
}
复制代码
运行结果:
在Spring中,涉及装饰器模式的场景有:数据源包装、I/O流
数据源包装:当我们只有一个数据源的时候,通过Spring和hibernate框架配置一个数据源,然后sessionFactory的dataSource属性就指向这个数据源,并且固定不变
datasource:
url: jdbc:mysql://192.168.1.111:3306/db_name?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true
username: root
password: 123456
复制代码
- 当项目需要连接多个数据库,而不同的客户在每次访问中根据需要去访问不同的数据库,实现动态切换数据源则用到了装饰器
- 在I/O流应用当中,FilterInputStream是JAVA的IO中也有抽象的装饰器基类它是很多装饰器最基础的装饰基类。
spring中用到的包装器(装饰器)模式在类名上有两种表现:一种是类名中含有Wrapper,另一种是类名中含有Decorator。基本上都是动态地给一个对象添加一些额外的职责
- Component为统一接口,也是装饰类和被装饰类的基本类型。
- ConcreteComponent为具体实现类,也是被装饰类,他本身是个具有一些功能的完整的类。
- Decorator是装饰类,实现了Component接口的同时还在内部维护了一个ConcreteComponent的实例,并可以通过构造函数初始化。而Decorator本身,通常采用默认实现,他的存在仅仅是一个声明:我要生产出一些用于装饰的子类了。而其子类才是赋有具体装饰效果的装饰产品类。
- ConcreteDecorator是具体的装饰产品类,每一种装饰产品都具有特定的装饰效果。可以通过构造器声明装饰哪种类型的ConcreteComponent,从而对其进行装饰。
今日小结:在对装饰器模式的学习上,通过代码来实现对应的功能,更加能够感受到设计模式的作用,对设计模式文字的解释能够有一个笼统的概念,但模式上的应用还是落实到编码中,才能体现出来。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END