设计模式之二装饰者模式

一 概述
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

posted @ 2017-05-31 18:58  tonghun  阅读(413)  评论(0编辑  收藏  举报