设计模式之二装饰者模式

来源:互联网 发布:mac os版本是什么意思 编辑:程序博客网 时间:2024/05/16 17:03

设计模式之二装饰者模式

一 概述
1.什么是装饰者模式?
在不修改类,不使用继承的前提下,用一个对象来装饰另一个对象,以扩展目标对象的功能。

2.装饰者模式的作用:
继承也可以扩展类的功能,装饰者模式比继承更加灵活,因为继承时子类受父类的约束,比如子类方法不能降低访问权限,返回值必须是父类方法返回值的子类,而装饰模式就不受这些约束,比较灵活。

 

二 基本装饰者模式
结构:

  • 父类:可以是接口、抽象类、一般类,保证能够以操作目标对象的方式操作装饰者,即保证装饰者拥有与目标对象相同的方法结构。
  • 目标类;
  • 装饰者类:其中包含目标对象引用,往往通过构造器注入。

 

三 高级装饰者模式
1.不仅可以对目标对象进行多种形式的增强,而且可以构建装饰者链将多种增强形式同时施加到目标对象上。

2.结构

  • 父类。
  • 目标类:实现或者继承了父类。
  • 装饰者基类:实现或继承了父类,只是实现了目标对象方法,并未增强,作为后续增强的基础。
  • 具体装饰者A类:继承了装饰者基类,对目标类进行一种形式的增强。
  • 具体装饰者B类:继承了装饰者基类,对目标类进行一种形式的增强。

3.按照功能模块化原则,一个模块只负责单一的功能,每一种具体装饰者类,只负责实现一种增强形式。
4.具体装饰者类对目标类的增强建立在基类处理结果的基础上,因此在代码中通过先super获取基类的结果,然后再进行增强。

5.构建装饰者链
⑴基本原理:

首先将目标对象传入一个具体装饰者对象中,再将该具体装饰者对象传入下一个具体装饰者对象中,以此推进,形成一个装饰者链,对目标对象逐级增强。
⑵构建关键:

在具体装饰者类中通过super获取基类处理结果,将基类作为中间环节构建装饰者链。

⑶实现Demo

接口

复制代码
package com.designmode.decorator.senior;public interface ISomeService {    String doSome();}
复制代码

目标类

复制代码
package com.designmode.decorator.senior;public class SomeServiceImpl implements ISomeService {    @Override    public String doSome() {        return "   abc   ";    }}
复制代码

装饰者基类

复制代码
package com.designmode.decorator.senior;public class SomeServiceWrapper implements ISomeService {    private ISomeService target;    public SomeServiceWrapper(ISomeService target) {        super();        this.target = target;    }    @Override    public String doSome() {        return target.doSome();    }}
复制代码

具体装饰者A类

复制代码
package com.designmode.decorator.senior;public class TrimDecorator extends SomeServiceWrapper {    public TrimDecorator(ISomeService target) {        super(target);        // TODO Auto-generated constructor stub    }    @Override    public String doSome() {        // TODO Auto-generated method stub        return super.doSome().trim();    }}
复制代码

具体装饰者B类

复制代码
package com.designmode.decorator.senior;public class UpperDecorator extends SomeServiceWrapper {    public UpperDecorator(ISomeService target) {        super(target);        // TODO Auto-generated constructor stub    }    @Override    public String doSome() {        // TODO Auto-generated method stub        return super.doSome().toUpperCase();    }}
复制代码

测试类

复制代码
package com.designmode.decorator.senior;import org.junit.Test;public class DecoratorTest {    /**     * 装饰者基类,原样实现了目标对象的方法,并未增强     */    @Test    public void test01() {        ISomeService target = new SomeServiceImpl();        ISomeService decorator = new SomeServiceWrapper(target);        String result = decorator.doSome();        System.out.println("result=" + result);    }    /**     * 一次增强,对装饰者基类增强     */    @Test    public void test02() {        ISomeService target = new SomeServiceImpl();        ISomeService decorator = new TrimDecorator(target);        String result = decorator.doSome();        System.out.println("result=" + result);    }    /**     * 形成装饰者链,逐级增强     */    @Test    public void test03() {        ISomeService target = new SomeServiceImpl();        ISomeService trimDecorator = new TrimDecorator(target);// 一级增强        ISomeService service = new UpperDecorator(trimDecorator);// 二级增强        String result = service.doSome();        System.out.println("result=" + result);    }}
复制代码

 

三 常见装饰者应用
IO流中广泛使用装饰者模式,一些类正是装饰了基本输入输出流创建的,如XMLWriter\DateOutputStream\BufferedInputstream\

ObjectInputstream等。

 

四 与静态代理模式对比
1.相同点:

  • 都与目标类实现共同的接口。
  • 都可以动态地扩展目标类的功能。
  • 都需要在自身类中包含目标对象。

2.不同点
⑴设计目的不同:

  • 装饰者模式是为了增强目标类的功能。
  • 静态代理是为了隐藏与保护目标类。

⑵包含目标对象的方式不同:

  • 在装饰者模式中,目标对象由用户创建,通过构造器传入装饰者中,目标对用户可见。
  • 在静态代理模式中,目标对象在装饰者类的无参构造方法中创建,对用户不可见。

注:静态代理模式请参考http://www.cnblogs.com/tonghun/p/6925614.html