摘要:装饰器模式是一种灵活的设计模式,它可以在不改变原有对象的基础上,通过给对象添加额外的功能来实现对象的功能扩展。本文将介绍装饰器模式的定义、结构、优点和缺点,并通过一个实例来说明装饰器模式的实现过程。
关键词:装饰器模式,设计模式,功能扩展
- 什么是装饰器模式
装饰器模式(Decorator Pattern)是一种灵活的设计模式,它可以在不改变原有对象的基础上,通过给对象添加额外的功能来实现对象的功能扩展。装饰器模式可以在运行时动态地将责任附加到对象上,而不会影响到其他对象。
装饰器模式的结构如上图所示,它包含以下角色:
(1)Component:抽象构件,它是具体构件和抽象装饰类的共同父类,声明了在具体构件中实现的业务方法。
(2)ConcreteComponent:具体构件,它实现了在抽象构件中声明的抽象方法,装饰器可以给它增加额外的职责(方法)。
(3)Decorator:抽象装饰类,它继承了抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。
(4)ConcreteDecorator:具体装饰类,它是抽象装饰类的子类,负责向具体构件添加额外的职责。 - 优点
(1)装饰器模式可以提供比继承更多的灵活性。
(2)可以通过一种动态的方式来扩展一个对象的功能,并且可以动态地撤销。
(3)可以对一个对象进行多次装饰,通过使用不同的具体装饰类以及这些装饰类的排列组合,可以实现不同的效果。
(4)具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,原有类库代码无须改变,符合“开闭原则”。 - 缺点
(1)装饰器模式会产生很多小对象,这些对象的区别在于它们之间相互连接的方式有所不同,而不是它们的类或者属性值有所不同,大量小对象会占用更多的系统资源,在一定程度上影响程序的性能。
(2)过多地使用装饰器模式,会导致系统中出现很多具体装饰类,增加系统的复杂度和理解难度。 - 实例
下面我们通过一个实例来说明装饰器模式的实现过程,实例描述了一个用于计算奖金的系统,其中有三种类型的经理:科长、副经理和经理,每种类型的经理的奖金分别是基本奖金的1.1倍、1.5倍和2倍。
(1)首先,我们需要定义一个抽象构件类,它是具体构件类和抽象装饰类的共同父类,声明了在具体构件中实现的业务方法:
public abstract class Manager {
public abstract double getSalary();
}
(2)然后,我们定义三个具体构件类,它们分别实现了在抽象构件中声明的抽象方法:
public class CommonManager extends Manager {
@Override
public double getSalary() {
return 1000;
}
}
public class DeputyManager extends Manager {
@Override
public double getSalary() {
return 1500;
}
}
public class GeneralManager extends Manager {
@Override
public double getSalary() {
return 2000;
}
}
(3)接着,我们定义一个抽象装饰类,它继承了抽象构件,并包含具体构件的实例:
public abstract class Decorator extends Manager {
protected Manager manager;
public Decorator(Manager manager) {
this.manager = manager;
}
}
(4)最后,我们定义三个具体装饰类,它们是抽象装饰类的子类,负责向具体构件添加额外的职责:
public class SectionManager extends Decorator {
public SectionManager(Manager manager) {
super(manager);
}
@Override
public double getSalary() {
return manager.getSalary() * 1.1;
}
}
public class ViceManager extends Decorator {
public ViceManager(Manager manager) {
super(manager);
}
@Override
public double getSalary() {
return manager.getSalary() * 1.5;
}
}
public class GeneralManager2 extends Decorator {
public GeneralManager2(Manager manager) {
super(manager);
}
@Override
public double getSalary() {
return manager.getSalary() * 2;
}
}
(5)最后,我们来看看如何使用装饰器模式来计算经理的奖金:
public class Test {
public static void main(String[] args) {
Manager commonManager = new CommonManager();
Manager sectionManager = new SectionManager(commonManager);
Manager viceManager = new ViceManager(sectionManager);
Manager generalManager = new GeneralManager2(viceManager);
System.out.println("经理的奖金:" + generalManager.getSalary());
}
}
输出结果:
经理的奖金:3300.0
5. 总结
装饰器模式是一种灵活的设计模式,它可以在不改变原有对象的基础上,通过给对象添加额外的功能来实现对象的功能扩展。装饰器模式可以提供比继承更多的灵活性,可以通过一种动态的方式来扩展一个对象的功能,并且可以动态地撤销。但是,装饰器模式会产生很多小对象,这些对象的区别在于它们之间相互连接的方式有所不同,而不是它们的类或者属性值有所不同,大量小对象会占用更多的系统资源,在一定程度上影响程序的性能。