定义:
在不改变现有对象结构的情况下,动态的给该对象增加一些额外的功能。
组成:
- 抽象构件角色:定义一个抽象接口(即在具体构件也可以理解为源代码中需要扩展的接口,在此处声明一下)
- 具体构件角色:实现抽象构件,通过装饰角色实现一些额外的功能
- 抽象装饰角色: 一般是一个抽象类,继承或实现抽象构件,在它的属性里面有一个变量指向Component抽象构件,并且需要有个实例化方法
- 具体装饰角色: 实现抽象装饰的相关方法,并给具体构件对象添加附加的责任
优缺点:
优点有:
装饰器是继承的有力补充,比继承灵活,在不改变原有对象的情况下,动态的给一个对象扩展功能,即插即用
通过使用不用装饰类及这些装饰类的排列组合,可以实现不同效果
装饰器模式完全遵守开闭原则
缺点是:装饰器模式会增加许多子类,过度使用会增加程序得复杂性
开放封闭原则:
开放封闭原则是指软件实体(类,模块,函数等)应该可以扩展,但是不可修改。即:对于扩展是开放的,对于更改是封闭的。设计的时候时刻要考虑,尽量让这个类是足够好,写好了就不用改了,如果有新需求,则增加一些类,原来的代码能不动就不动。面对需求,对程序的改动是通过增加新代码进行的,而不是更改现有的代码。
实现
一:举例说明
手机屏幕有曲屏\全屏\键盘,摄像头有前置\后置,内存12G\36G,功能有蓝牙\NFC
1:原来的手机厂家只需要生产键盘手机,随着市场的发展厂家需要研发新的手机 。然后去组装手机(代码去实现)
(A):曲屏+前置+12G+蓝牙
(B):曲屏+前置+12G+NFC
(C):曲屏+前置+12G+蓝牙+NFC
(D):曲屏+前置+36G+蓝牙
*… …
组合种类很多。
2:厂家想组装新的手机,但是又不想改变原来的生产线。这时引入【装饰器模式】在原来的生产线旁边组装新的生产线,两条生产线合并组装手机。
上代码举例
/**
* 抽象构件
*/
public interface Handware {
public void show();
}
// 具体构件
public class Phone implements Handware {
@Override
public void show() {
System.out.println("~手机 【制造】完成 ~");
}
}
/**
* 抽象装饰
*/
public abstract class Decorator implements Handware{
private Handware handware;
public Decorator(Handware handware){
this.handware=handware;
}
@Override
public void show() {
handware.show();
}
}
//装饰者
public class Caiping extends Decorator {
public Caiping(Handware handware) {
super(handware);
}
public void show(){
System.out.println("拥有彩屏功能 "); super.show();
}
}
public class Lanya extends Decorator {
public Lanya(Handware handware) {
super(handware);
}
public void show(){
System.out.println("拥有蓝牙功能"); super.show();
}
}
public class SheXiangtou extends Decorator {
public SheXiangtou(Handware handware) {
super(handware);
}
public void show(){
System.out.println("拥有摄像头功能"); super.show();
}
}
//测试
public class test {
public static void main(String[] args) {
Handware phone = new Phone();
phone=new Caiping(phone);
phone=new SheXiangtou(phone);
phone=new Lanya(phone);
phone.show();
}
}
输出
拥有蓝牙功能
拥有摄像头功能
拥有彩屏功能
~手机 【制造】完成 ~
透明性要求
装饰模式对客户端的透明性要求程序不要声明一个“具体装饰角色”类型的变量(彩屏、蓝牙、摄像头),而应当声明一个“抽象构建角色”类型的变量(智能硬件)
正确写法
Handware phone = new Phone();
Handware phoneHandware=new Caiping(phone);
错误写法
Handware phone = new Phone();
Caiping caiping=new Caiping(phone);