使用装饰模式进行系统设计时将产生很多小对象,这些对象的区别在于它们之间相互连接的方式有所不同,而不是它们的类或者属性值有所不同,同时还将产生很多具体装饰类。这些装饰类和小对象的产生将增加系统的复杂度,加大学习与理解的难度。
这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加易于出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为烦琐。
装饰模式就像中秋节包装过的月饼一样,可以包多层,每一层可以使用不同的包装纸来包装。
桥接模式与装饰模式
两个模式都是为了解决子类过多问题, 但他们的诱因不同:
1.桥接模式对象自身有 沿着多个维度变化的趋势 , 本身不稳定;
2.装饰者模式对象自身非常稳定, 只是为了增加新功能/增强原功能。
类图
桥接模式
装饰模式
示例代码:
//抽象类:建筑
public abstract class Building {
protected Paint paint;
public Building(Paint paint) {
this.paint = paint;
}
public abstract void decorate();
}
//接口:油漆
public interface Paint {
void decorateImpl();
}
//教学楼
public class TeachingBuilding extends Building {
public TeachingBuilding(Paint paint) {
super(paint);
}
@Override
public void decorate() {
System.out.print("普通的教学楼");
paint.decorateImpl();
}
}
//实验楼
public class LaboratoryBuilding extends Building {
public LaboratoryBuilding(Paint paint) {
super(paint);
}
@Override
public void decorate() {
System.out.print("普通的实验楼");
paint.decorateImpl();
}
}
public class RedPaint implements Paint {
@Override
public void decorateImpl() {
System.out.println("被红色油漆装饰过。");
}
}
public class GreenPaint implements Paint {
@Override
public void decorateImpl() {
System.out.println("被绿色油漆装饰过。");
}
}
public class BulePaint implements Paint {
@Override
public void decorateImpl() {
System.out.println("被蓝色油漆装饰过。");
}
}
public class BridgePatternDemo {
public static void main(String[] args) {
//普通的教学楼被红色油漆装饰。
Building redTeachingBuilding=new TeachingBuilding(new RedPaint());
redTeachingBuilding.decorate();
//普通的教学楼被绿色油漆装饰。
Building greenTeachingBuilding1=new TeachingBuilding(new GreenPaint());
greenTeachingBuilding1.decorate();
//普通的实验楼被红色油漆装饰。
Building redLaboratoryBuilding=new LaboratoryBuilding(new RedPaint());
redLaboratoryBuilding.decorate();
//普通的实验楼被绿色油漆装饰。
Building greenLaboratoryBuilding=new LaboratoryBuilding(new GreenPaint());
greenLaboratoryBuilding.decorate();
//普通的实验楼被蓝色油漆装饰。
Building blueLaboratoryBuilding=new LaboratoryBuilding(new BulePaint());
blueLaboratoryBuilding.decorate();
}
}
运行结果:
普通的教学楼被红色油漆装饰过。
普通的教学楼被绿色油漆装饰过。
普通的实验楼被红色油漆装饰过。
普通的实验楼被绿色油漆装饰过。
普通的实验楼被蓝色油漆装饰过。
装饰模式
简明的说:
是你还有你,一切拜托你。
装饰模式就像中秋节包装过的月饼一样,可以
包多层,每一层可以使用不同的包装纸来包装
再放一遍类图
示例代码:
//接口:建筑
public interface Building {
void decorate();
}
//抽象类:油漆
public abstract class Paint implements Building {
protected Building building;
public Paint(Building building) {
this.building = building;
}
public void decorate(){
building.decorate();
}
}
//实验楼
public class LaboratoryBuilding implements Building{
@Override
public void decorate() {
System.out.print("普通的实验楼");
}
}
//教学楼
public class TeachingBuilding implements Building {
@Override
public void decorate() {
System.out.print("普通的教学楼");
}
}
//红色油漆
public class RedPaint extends Paint {
public RedPaint(Building building) {
super(building);
}
@Override
public void decorate() {
building.decorate();
decorateByRedPaint();
}
public void decorateByRedPaint(){
System.out.print("被红色油漆装饰过");
}
}
//绿色油漆
public class GreenPaint extends Paint {
public GreenPaint(Building building) {
super(building);
}
@Override
public void decorate() {
building.decorate();
decorateByGreenPaint();
}
public void decorateByGreenPaint(){
System.out.print("被绿色油漆装饰过");
}
}
//蓝色油漆
public class BulePaint extends Paint {
public BulePaint(Building building) {
super(building);
}
@Override
public void decorate() {
building.decorate();
decorateByBluePaint();
}
public void decorateByBluePaint(){
System.out.print("被蓝色油漆装饰过");
}
}
public class DecoratorPatternDemo {
public static void main(String[] args) {
System.out.println("\n-*-被红色油漆装饰过的普通的教学楼-*-");
Building redTeachingBuilding=new RedPaint(new TeachingBuilding());
redTeachingBuilding.decorate();
System.out.println("\n-*-被绿色油漆装饰过的普通的教学楼-*-");
Building greenTeachingBuilding=new GreenPaint(new TeachingBuilding());
greenTeachingBuilding.decorate();
System.out.println("\n-*-被红色油漆装饰过的普通的实验楼-*-");
Building redLaboratoryBuilding=new RedPaint(new LaboratoryBuilding());
redLaboratoryBuilding.decorate();
System.out.println("\n-*-被绿色油漆装饰过的普通的实验楼-*-");
Building greenLaboratoryBuilding=new GreenPaint(new LaboratoryBuilding());
greenLaboratoryBuilding.decorate();
System.out.println("\n-*-被红色和绿色油漆装饰过的普通的实验楼-*-");
Building building=new GreenPaint(new RedPaint(new LaboratoryBuilding()));
building.decorate();
System.out.println("\n-*-被红色和绿色和蓝色油漆装饰过的普通的实验楼-*-");
Building building1=new BulePaint(new GreenPaint(new RedPaint(new LaboratoryBuilding())));
building1.decorate();
}
}
运行结果:
-*-被红色油漆装饰过的普通的教学楼-*-
普通的教学楼被红色油漆装饰过
-*-被绿色油漆装饰过的普通的教学楼-*-
普通的教学楼被绿色油漆装饰过
-*-被红色油漆装饰过的普通的实验楼-*-
普通的实验楼被红色油漆装饰过
-*-被绿色油漆装饰过的普通的实验楼-*-
普通的实验楼被绿色油漆装饰过
-*-被红色和绿色油漆装饰过的普通的实验楼-*-
普通的实验楼被红色油漆装饰过被绿色油漆装饰过
-*-被红色和绿色和蓝色油漆装饰过的普通的实验楼-*-
普通的实验楼被红色油漆装饰过被绿色油漆装饰过被蓝色油漆装饰过