1.装饰模式的定义
装饰模式的英文定义为:
Attach additional responsibilities to an object dynamically keeping the same interface. Decorators provide a flexible alternative to subclassing for extending functionality.
这段话的意思就是动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式比生成子类更加的灵活。装饰模式类图如下:
在不改变原有接口的情况下,对该接口进行扩充。首先Component接口为装饰类的超类,它抽象了这个组件的通用功能。其次ConcreteComponent是Component的具体实现。Decorator类内部维护一个Component的引用,并且实现了operation方法(调用Component的引用的operation方法)。ConcreteDecorator继承于Decorator,然后对operation*进行扩展*。
Component.java
public interface Component{
public void operation();
}
ConcreteComponent.java
public class ConcreteComponent implements Component{
public void operation(){
}
}
Decorator.java
public abstract class Decorator implements Component{
private Component component = null;
public Decorator(Component component){
this.component = component;
}
public void operation(){
this.component.operation();
}
}
ConcreteDecorator.java
public class ConcreteDecorator extends Decorator{
public ConcreteDecorator(Component component){
super(component);
}
private void method(){
System.out.println("Decorator!!!!!");
}
public void operation(){
method();
super.operation();
}
}
TestDecorator.java
public class TestDecorator{
public static void main(String[] argv){
Component component = new ConcreteComponent();
component = new ConcreteDecorator(component);
component.operation();
}
}
2.装饰模式的优缺点
优点:
1)装饰类和被装饰类可以独立扩展,而不会相互耦合。即Component无需知道Decorator类,Decorator类是从外部对Component进行扩展的,然后Decorator类无需知道具体的的Component类及子类。
2)装饰模式是继承类的一个替代方案。装饰类Decorator类无论进行多少次装饰,返回的对象还是Component类。
3)装饰模式可以动态扩展一个实现类的功能。
缺点:
多层的装饰是相对比较复杂的。
3.装饰模式的实例
下面的代码用于实现裸车装饰过程。UML类图如下:
Car.java
public interface Car {
public void show();
}
Benz.java
public class Benz implements Car {
public void show(){
System.out.println("奔驰车的默认颜色是黑色。");
}
}
CarDecorator.java
public abstract class CarDecorator implements Car {
private Car m_Car;
public CarDecorator(Car m_Car){
this.m_Car = m_Car;
}
public void show(){
m_Car.show();
}
}
CarConcreteDecorator.java
public class CarConcreteDecorator extends CarDecorator {
public CarConcreteDecorator(Car m_Car){
super(m_Car);
}
public void print(){
System.out.println("在车尾绘制\"新手\"字样,颜色变成红色。");
}
public void setGPS(){
System.out.println("安装GPS定位。");
}
public void show(){
super.show();
print();
setGPS();
}
}
TeatDecorator.java
public class TestDecorator{
public static void main(String[] argv){
Car car = new Benz();
CarDecorator cd = new CarConcreteDecorator(car);
cd.show();
}
}