顾名思义,装饰模式就是给一个对象增加一些新的功能,而且是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例,关系图如下:

Source类是被装饰类,Decorator类是一个装饰类,可以为Source类动态的添加一些功能,代码如下:
- public interface Sourceable {
- public void method();
- }
- public class Source implements Sourceable {
- @Override
- public void method() {
- System.out.println("the original method!");
- }
- }
- 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!");
- }
- }
测试类:
- 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:liyong@wcs-global.com">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();
- }
- }
输出结果:
晚上
开车
本文详细介绍了装饰模式的概念及其应用场景,通过示例代码展示了如何为现有类动态添加新功能,同时保持原有的功能不变。装饰模式适用于需要扩展类功能的情况,特别是在不修改原始类的基础上动态地增加或删除功能。

419

被折叠的 条评论
为什么被折叠?



