装饰模式

理论知识

装饰模式 :动态地将责任附加到对象上.若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

装饰模式使用被装饰类的一个子类的实例,把客户端的调用委派到被装饰类,装饰模式的关键在于这种扩展是完全透明的。
装饰模式在Java种使用也很广泛,比如我们在重新定义按钮、对话框等时候,实际上已经在使用装饰模式了。装饰模式最浅显的例子是相片-相框的例子。

其中类的职责如下:
抽象构件角色(Project):给出一个接口,以规范准备接收附加责任的对象
具体构件角色(Employe):定义一个将要接收附加责任的类
装饰角色(Manager):持有一个构件对象的实例,并定义一个与抽象构件接口一致的接口
具体装饰角色(ManagerA、ManagerB):负责给构件对象“贴上”附加的责任

个人理解

装饰模式直接看代码挺难理解的,我通过一个例子来说明。
有一家公司是出口眼镜和汽车的,过完年,要开始给海外客户供货了,其中有三位需要汽车大客户分别需要三批不同的车:上了漆的车,上了漆和加尾翼的车,还有加了尾翼的车。还有一位需要眼镜的客户。造车和造眼镜本公司就可以直接制造。而汽车上漆和加尾翼需要委托代工工厂。

新建一个公司老板(Boss.java)——抽象构件角色

1
2
3
public interface Boss {
public void makeProject();
}

接着造车部门(MakeCar.java)——具体构件角色

1
2
3
4
5
6
public class MakeCar implements Boss {
@Override
public void makeProject() {
System.out.println("造完车");
}
}

造眼镜部门(MakeEyeglass.java)——具体构件角色

1
2
3
4
5
6
public class MakeEyeglass implements Boss {
@Override
public void makeProject() {
System.out.println("造完眼镜");
}
}

代工工厂(Factory.java)——装饰角色

1
2
3
4
5
6
7
8
9
10
public class Factory implements Boss {
public Boss boss;
public Factory(Boss boss){
this.boss=boss;
}
@Override
public void makeProject() {
boss.makeProject();
}
}

上漆(MakeCarPush1.java)——具体装饰角色

1
2
3
4
5
6
7
8
9
10
11
12
public class MakeCarPush1 extends Factory{
public MakeCarPush1(Boss boss) {
super(boss);
}
public void makeProject() {
super.makeProject();
addColors();
}
public void addColors(){
System.out.println("上漆");
}
}

加尾翼(MakeCarPush2)——具体装饰角色

1
2
3
4
5
6
7
8
9
10
11
12
public class MakeCarPush2 extends Factory {
public MakeCarPush2(Boss boss) {
super(boss);
}
public void makeProject() {
super.makeProject();
addWing();
}
public void addWing(){
System.out.println("加尾翼");
}
}

实现类(Start.java)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Start {
public static void main(String[] args) {
MakeCarPush1 mc1=new MakeCarPush1(new Factory(new MakeCar()));
mc1.makeProject();
MakeCarPush2 mc2=new MakeCarPush2(new MakeCarPush1(new Factory(new MakeCar())));
mc2.makeProject();
MakeCarPush2 mc3=new MakeCarPush2(new Factory(new MakeCar()));
mc3.makeProject();
MakeEyeglass me=new MakeEyeglass();
me.makeProject();
}
}

最终效果