结构型模式--装饰模式(Decorator)
顾名思义,装饰模式就是给一个对象增加一些新的功能,而且是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例,关系图如下:
Source类是被装饰类,Decorator类是一个装饰类,可以为Source类动态的添加一些功能,代码如下:
[java] view plaincopy
- public interface Sourceable {
- public void method();
- }
[java] view plaincopy
- public class Source implements Sourceable {
- @Override
- public void method() {
- System.out.println("the original method!");
- }
- }
[java] view plaincopy
- public class Decorator implements Sourceable {
- private Sourceable source;
- public Decorator(Sourceable source){
- super();
- this.source = source;
- }
- @Override
- public void method() {
- System.out.println("before decorator!");
- source.method();
- System.out.println("after decorator!");
- }
- }
测试类:
[java] view plaincopy
- public class DecoratorTest {
- public static void main(String[] args) {
- Sourceable source = new Source();
- Sourceable obj = new Decorator(source);
- obj.method();
- }
- }
输出:
before decorator!
the original method!
after decorator!
装饰器模式的应用场景:
1、需要扩展一个类的功能。
2、动态的为一个对象增加功能,而且还能动态撤销。(继承不能做到这一点,继承的功能是静态的,不能动态增删。)
缺点:产生过多相似的对象,不易排错!
==================================================================
另外一个例子:
/** * Test.java * Created on 2013-8-1 上午10:02:29 */ package my; /** * <p>Project: Test2</p> * <p>Title: Test.java</p> * <p>Description: </p> * <p>Copyright (c) 2013 Wilmar Consultancy Services</p> * <p>All Rights Reserved.</p> * @author <a href="mailto:[email protected]">liyong</a> */ public class Test { public static void main(String[] args) { Teacher t1 = new SimpleTeacher(); Teacher t2 = new CppTeacher(t1); Teacher t3 = new JavaTeacher(t2); t3.teach(); // t.teach(); } } abstract class Teacher { public abstract void teach(); } class SimpleTeacher extends Teacher { public void teach() { System.out.println("Good Good Study, Day Day Up"); } } class JavaTeacher extends Teacher { Teacher teacher; public JavaTeacher(Teacher t) { this.teacher = t; } public void teach() { teacher.teach(); System.out.println("Teach Java"); } } class CppTeacher extends Teacher { Teacher teacher; public CppTeacher(Teacher t) { this.teacher = t; } public void teach() { teacher.teach(); System.out.println("Teach C++"); } }
3、===============================================================
装饰模式:给一个类添加一些额外的职责,并且在添加这些额外的职责时不会控制该类的执行逻辑。
UML类图:
组成部分:
抽象构件:原始的功能接口
具体构件:具体的原始功能类
装饰角色:持有具体构件类的对象,以便执行原有功能
具体装饰:具体扩展的功能在这里
下面看一个对开车功能拓展的实例(晚上+开车):
抽象构件:
- package com.gjy.drector;
- /**
- * 抽象接口,规范准备接收附加责任的对象
- * @author gjy
- */
- public interface Component {
- public void operation();
- }
具体构件:
- package com.gjy.drector;
- /**
- * 接收附加责任, 此类型的类可以有多个, 只对应一个Decorator类
- * @author gjy
- */
- public class ConcreteComponent implements Component {
- public ConcreteComponent(){}
- public void operation()
- {
- System.out.println("开车");
- }
- }
装饰角色:
- package com.gjy.drector;
- /**
- * 装饰角色,持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口
- * @author gjy
- */
- public class Decorator implements Component {
- private Component component;
- public Decorator(){}
- public Decorator(Component component)
- {
- this.component = component;
- }
- public void operation() {
- component.operation();
- }
- }
具体装饰:
- package com.gjy.drector;
- /**
- * 添加附加责任
- * @author gjy
- */
- public class ConcreteDecorator extends Decorator {
- public ConcreteDecorator(){}
- public ConcreteDecorator(Component component)
- {
- super(component);
- }
- public void operation()
- {
- this.addedOperation();
- super.operation();
- }
- public void addedOperation()
- {
- System.out.println("晚上");
- }
- }
测试:
- package com.gjy.drector;
- /**
- * 客户端类
- * @author gjy
- */
- public class Client {
- public static void main(String[] args) {
- Component component = new ConcreteComponent();
- Decorator decorator = new ConcreteDecorator(component);
- //客户端不变, 但已增加了责任
- decorator.operation();
- }
- }
输出结果:
晚上
开车