1.定义
装饰模式(Decorator Pattern) :动态地给一个对象增加一些额外的职责(Responsibility),就增加对象功能来说,装饰模式比生成子类实现更为灵活。其别名也可以称为包装器(Wrapper),与适配器模式的别名相同,但它们适用于不同的场合。它是一种对象结构型模式。
2.UML图
(1)组件的uml图
(2)变形金刚的uml图
3.代码
(1)组件的代码:
package com.wuhuiskiff.www.decorator.code.component;
/**
* @Auther: 一叶扁舟
* @Date: 2019/2/11 15:48
* @Description:
*/
public abstract class Component {
public abstract void operation();
}
package com.wuhuiskiff.www.decorator.code.component;
/**
* @Auther: 一叶扁舟
* @Date: 2019/2/11 15:51
* @Description:
*/
public class ConcreteComponent extends Component {
@Override
public void operation() {
//具体的组件
System.out.println("具体的组件");
}
}
package com.wuhuiskiff.www.decorator.code.component;
/**
* @Auther: 一叶扁舟
* @Date: 2019/2/11 15:52
* @Description:装饰器
*/
public class Decorator extends Component{
private Component component;
@Override
public void operation() {
this.component.operation();
}
public Decorator(Component component) {
this.component = component;
}
}
package com.wuhuiskiff.www.decorator.code.component;
/**
* @Auther: 一叶扁舟
* @Date: 2019/2/11 16:00
* @Description:
*/
public class ConcreteDecoratorA extends Decorator {
@Override
public void operation() {
// 调用原有的业务方法
super.operation();
// 调用新增的方法
this.changeStatus();
}
public ConcreteDecoratorA(Component component) {
super(component);
}
public void changeStatus(){
System.out.println(" ConcreteDecoratorA 改变组件的状态。。。");
}
}
package com.wuhuiskiff.www.decorator.code.component;
/**
* @Auther: 一叶扁舟
* @Date: 2019/2/11 16:03
* @Description:
*/
public class ConcreteDecoratorB extends Decorator {
@Override
public void operation() {
super.operation();
this.changeBehavior();
}
public ConcreteDecoratorB(Component component) {
super(component);
}
public void changeBehavior(){
System.out.println("ConcreteDecoratorB 改变行为状态。。。");
}
}
package com.wuhuiskiff.www.decorator.code.component;
/**
* @Auther: 一叶扁舟
* @Date: 2019/2/11 16:06
* @Description:
*/
public class ClientTest {
public static void main(String[] args) {
Component component = new ConcreteComponent();
Decorator decorator = new ConcreteDecoratorA(component);
decorator.operation();
System.out.println("---------------------------");
decorator = new ConcreteDecoratorB(component);
decorator.operation();
}
}
(2)变形金刚代码
package com.wuhuiskiff.www.decorator.code.car;
/**
* @Auther: 一叶扁舟
* @Date: 2019/2/11 16:29
* @Description: 变形金刚接口
*/
public interface TransForm {
void move();
}
package com.wuhuiskiff.www.decorator.code.car;
/**
* @Auther: 一叶扁舟
* @Date: 2019/2/11 16:30
* @Description:
*/
public class Car implements TransForm {
public Car() {
System.out.println("变形金刚是一辆车。。。");
}
@Override
public void move() {
System.out.println("车可以在地面上移动。。。");
}
}
package com.wuhuiskiff.www.decorator.code.car;
/**
* @Auther: 一叶扁舟
* @Date: 2019/2/11 16:31
* @Description:变形
*/
public class Changer implements TransForm {
private TransForm transForm;
public Changer(TransForm transForm) {
this.transForm = transForm;
}
@Override
public void move() {
this.transForm.move();
}
}
package com.wuhuiskiff.www.decorator.code.car;
/**
* @Auther: 一叶扁舟
* @Date: 2019/2/11 16:36
* @Description:
*/
public class Airplane extends Changer {
public Airplane(TransForm transForm) {
super(transForm);
System.out.println("变形金刚变成了飞机。。。");
}
@Override
public void move() {
super.move();
}
public void fly(){
System.out.println("变形金刚变成了飞机,可以飞。。。");
}
}
package com.wuhuiskiff.www.decorator.code.car;
/**
* @Auther: 一叶扁舟
* @Date: 2019/2/11 16:32
* @Description:
*/
public class Robot extends Changer {
public Robot(TransForm transForm) {
super(transForm);
System.out.println("变形金刚变成了机器人。。。");
}
@Override
public void move() {
super.move();
}
public void say(){
System.out.println("变形金刚变成了机器人,可以说话。。。");
}
}
package com.wuhuiskiff.www.decorator.code.car;
/**
* @Auther: 一叶扁舟
* @Date: 2019/2/11 16:39
* @Description:
*/
public class ClientTest {
public static void main(String[] args) {
TransForm transForm = new Car();
transForm.move();
System.out.println("--------------------------");
Changer changer;
Airplane airplane = new Airplane(transForm);
airplane.move();
//fly是对原有的move方法的扩展
airplane.fly();
System.out.println("============================");
Robot robot = new Robot(transForm);
robot.move();
robot.say();
}
}
4.优缺点
(1)装饰模式的优点
装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性。
可以通过一种动态的方式来扩展一个对象的功能,通过配置文件可以在运行时选择不同的装饰器,从而实现不同的行为。
通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。可以使用多个具体装饰类来装饰同一对象,得到功能更为强大的对象。
具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,在使用时再对其进行组合,原有代码无须改变,符合“开闭原则”。
(2)装饰模式的缺点
使用装饰模式进行系统设计时将产生很多小对象,这些对象的区别在于它们之间相互连接的方式有所不同,而不是它们的类或者属性值有所不同,同时还将产生很多具体装饰类。这些装饰类和小对象的产生将增加系统的复杂度,加大学习与理解的难度。
这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加易于出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为烦琐。
5.应用
(1) 在javax.swing包中,可以通过装饰模式动态给一些构件增加新的行为或改善其外观显示。 如JList构件本身并不支持直接滚动,即没有滚动条,要创建可以滚动的列表,可以使用如下代码实现:
JList list = new JList(); JScrollPane sp = new JScrollPane(list); |
(2). 装饰模式在JDK中最经典的实例是Java IO。
以InputStream为例:
6.总结
装饰模式用于动态地给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类实现更为灵活。它是一种对象结构型模式。
装饰模式包含四个角色:
抽象构件定义了对象的接口,可以给这些对象动态增加职责(方法);
具体构件定义了具体的构件对象,实现了在抽象构件中声明的方法,装饰器可以给它增加额外的职责(方法);
抽象装饰类是抽象构件类的子类,用于给具体构件增加职责,但是具体职责在其子类中实现;
具体装饰类是抽象装饰类的子类,负责向构件添加新的职责。
使用装饰模式来实现扩展比继承更加灵活,它以对客户透明的方式动态地给一个对象附加更多的责任。装饰模式可以在不需要创造更多子类的情况下,将对象的功能加以扩展。