目录
什么是装饰器模式
装饰器模式(Decorator Pattern),又称为包装模式(Wrapper Pattern)是指在不改变原有对象的基础之上,将功能附加到对象上,提供了比继承更有弹性的替代方案(扩展原有对象的功能),即允许向一个现有的对象添加新的功能,属于结构型模式。装饰器模式的核心是功能扩展,使用装饰器模式可以透明且动态地扩展类的功能。
装饰器模式通过将对象包装在装饰器类中,以便动态地修改其行为。其创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。
装饰器模式的实现
装饰器模式角色
- 抽象组件(Component): 可以是一个接口或者抽象类,其充当被装饰类的原始对象,规定了被装饰对象或类的行为
- 具体组件(ConcreteComponent): 实现/继承抽象组件的一个具体对象,即被装饰对象;通过装饰角色为其添加一些职责
- 抽象装饰器(Decorator): 实现/继承抽象组件,通用的装饰具体组件的装饰器,其内部必然有一个属性指向抽象组件;其实现一般是一个抽象类,主要是为了让其子类按照其构造形式传入一个抽象组件,这是强制的通用行为(若系统中逻辑单一,并不需要实现许多装饰器,那么我们可以直接省略该类,可直接实现一个具体装饰器)
- 具体装饰器(ConcreteDecorator): 抽象装饰器的具体实现类,并给具体构件对象添加附加的责任,一般为其特有的功能;理论上,每个具体装饰器都扩展了抽象组件对象的一种功能
装饰器模式类图
装饰器模式代码实现
抽象组件代码
package com.common.demo.pattern.decorator;
/**
* @author Evan Walker 昂焱数据: https://www.ayshuju.com
* @version 1.0
* @desc 手机接口类,即抽象者模式中的抽象组件类
* @date 2023/07/19 16:03:54
*/
public interface Phone {
/**
* 打印方法
*/
void print();
}
具体组件代码
package com.common.demo.pattern.decorator;
/**
* @author Evan Walker 昂焱数据: https://www.ayshuju.com
* @version 1.0
* @desc 华为手机 即装饰着模式中的具体组件类
* @date 2023/07/19 16:04:54
*/
public class HuaweiPhone implements Phone{
@Override
public void print() {
System.out.print("我是一部华为手机");
}
}
package com.common.demo.pattern.decorator;
/**
* @author Evan Walker 昂焱数据: https://www.ayshuju.com
* @version 1.0
* @desc 苹果手机 即装饰着模式中的具体组件类
* @date 2023/07/19 16:11:15
*/
public class ApplePhone implements Phone {
@Override
public void print() {
System.out.print("我是一部苹果手机");
}
}
抽象装饰器代码
package com.common.demo.pattern.decorator;
/**
* @author Evan Walker 昂焱数据: https://www.ayshuju.com
* @version 1.0
* @desc 装饰角色
* @date 2023/07/19 16:07:14
*/
public abstract class PhoneDecorator implements Phone{
//该装饰对象装饰到的Phone组件实体对象
protected Phone phone;
public PhoneDecorator(Phone phone) {
this.phone = phone;
}
@Override
public void print() {
phone.print();
}
}
具体装饰器代码
package com.common.demo.pattern.decorator;
/**
* @author Evan Walker 昂焱数据: https://www.ayshuju.com
* @version 1.0
* @desc 挂件,具体装饰者
* @date 2023/07/19 16:13:57
*/
public class Accessories extends PhoneDecorator{
public Accessories(Phone phone) {
super(phone);
}
@Override
public void print() {
phone.print();
//添加行为
addAccessories();
}
public void addAccessories() {
System.out.println(",现在有漂亮的挂件了");
}
}
package com.common.demo.pattern.decorator;
/**
* @author Evan Walker 昂焱数据: https://www.ayshuju.com
* @version 1.0
* @desc 贴膜,具体装饰者
* @date 2023/07/19 16:13:28
*/
public class Sticker extends PhoneDecorator {
public Sticker(Phone phone) {
super(phone);
}
@Override
public void print() {
phone.print();
//添加行为
addSticker();
}
public void addSticker() {
System.out.println(",现在有贴膜了");
}
}
测试代码
package com.common.demo.pattern.decorator;
/**
* @author Evan Walker 昂焱数据: https://www.ayshuju.com
* @version 1.0
* @desc
* @date 2023/07/19 16:22:09
*/
public class Test {
public static void main(String[] args) {
Phone phone = new HuaweiPhone();
PhoneDecorator huaweiAccessories = new Accessories(new HuaweiPhone());
PhoneDecorator appleSticker = new Sticker(new ApplePhone());
phone.print();
System.out.println();
huaweiAccessories.print();
appleSticker.print();
}
}
测试结果
装饰器模式的特点
优点
- 装饰器模式与继承关系的目的都是要扩展对象的功能,但其可以提供比继承更多的灵活性,在不改变原有对象的情况下,动态的给一个对象扩展功能,即插即用
- 通过使用不同的具体装饰类以及这些装饰类的排列组合,可创造出很多不同行为的组合
- 装饰器模式完全遵守开闭原则
缺点
- 比继承更加灵活机动的特性,意味着会出现更多的代码、更多的类,增加程序的复杂性
- 装饰模式是针对抽象组件(Component)类型编程。当针对具体组件编程时,应思考当前应用架构,装饰者是否合适。当然也可以改变Component接口,增加新的公开的行为,实现“半透明”的装饰者模式
注意事项
- 可代替继承
应用场景
- 扩展一个类的功能
- 动态增加功能,动态撤销
更多消息资讯,请访问昂焱数据(https://www.ayshuju.com)