1、定义
动态地给一个对象增加一些额外的职责。就扩张功能而言,装饰模式提供了一种比使用子类更加灵活的替代方案。
就像在墙上刷油漆.使用Decorator模式相比用生成子类方式达到功能的扩充显得更为灵活。
2、UML类图
-
Component(抽象构建):它是具体构建类和抽象装饰类的父类。声明具体构建类的业务方法,它可以使客户端同等的对待被装饰类修饰过的类和没被修饰过的类。实现客户端的透明操作。
-
ConcreteComponent(具体构件类):它实现了抽象构建类的业务方法,装饰类会给它增加额外的方法。
-
Decorator(装饰类):它也是抽象构建类的子类,用于给具体构建类添加方法。它维护一个指向抽象构建对象的引用,通过该引用可以调用装饰之前构建对象的方法,并通过其子类扩展该方法,已达到装饰的目的。
-
ConcreteDecorator(具体装饰类):它是抽象装饰类的子类,负责给构建类添加新的方法。每一个具体的装饰类都定义了一个具体的行为。
3、实例
步骤一:创建抽象的房子类
public abstract class House {
public abstract String getHouse();
public abstract String color();
public abstract String car();
}
步骤二:创建实体房子类,实体房子继承抽象房子
public class villa extends House{
@Override
public String getHouse() {
System.out.println("抽象构建类:购买房子");
return "具体构件类:买了別墅\n";
}
@Override
public String color() {
// TODO Auto-generated method stub
return "白色";
}
@Override
public String car() {
// TODO Auto-generated method stub
return "别克";
}
}
步骤三:创建抽象装饰父类
public class Decorator extends House{
private House dec;
public Decorator(House dec) {
// TODO Auto-generated constructor stub
this.dec = dec;
}
@Override
public String getHouse() {
// TODO Auto-generated method stub
return this.dec.getHouse();
}
@Override
public String color() {
// TODO Auto-generated method stub
return this.dec.color();
}
@Override
public String car() {
// TODO Auto-generated method stub
return this.dec.car();
}
}
步骤四:创建具体装饰子类
public class colorDecorator extends Decorator{
public colorDecorator(House dec) {
super(dec);
}
public String getHouse() {
return super.getHouse()+"具体装饰类1:粉刷墙面 "+super.color()+"\n";
}
}
public class garageDecorator extends Decorator{
public garageDecorator(House dec) {
super(dec);
}
public String getHouse() {
return super.getHouse()+"具体装饰类2:增加车库 "+super.car();
}
}
测试类
public class Client {
public static void main(String[] args) {
House dec;
dec = new villa();
dec = new colorDecorator(dec);
dec = new garageDecorator(dec);
System.out.println(dec.getHouse());
}
}
4、优点
-
对于扩张一个对象的功能,装饰模式比继承模式更加灵活,不会导致类的数量急剧增加。
-
可以通过一种动态的方式扩张一个类的功能,同过配置文件可以在运行时济宁选择,不同的装饰类。
-
可以对一个对象进行多次装饰,通过使用不同的具体装饰类以及这些装饰类的排列组合可以创造不同的行为的组合。
5、缺点
-
在使用装饰模式的时候进行系统设计时会产生很多小对象,这些对象的区别在于他们之间相互连接的方式有所不同,而不是他们的类或者属性值有所不同,大量小对象势必产生一大部分的系统资源开销。影响系统性能。
-
装饰模式是一种比继承更加灵活的解决方案。但同时,也意味着比继承更加容易出错,更加难排长。对于多层装饰的对象,需要逐级排查,较为繁琐。
6、使用场景
-
在不影响其他对象的情况下以动态的,透明的方式给单个对象添加职责。
-
不能用继承进行扩张的时候。