装饰模式

    公司的一些业务类最开始的设计只实现了核心功能,在后来不断的发展中,需要对其功能进行扩展,增加诸如缓存、加密等功能。为了符合开闭原则,不对原有类进行修改。如果通过新增类继承原有类的方式,类的数量将会成几何级上涨。例如原有3个类,现在要对这些类都扩展四个新功能。那最少就要增加12个子类。臃肿、麻烦。
    装饰模式可以解决这个问题。
    定义: 动态地给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类实现更为灵活。装饰模式是一种对象结构型模式。
    装饰模式引入装饰器,与被装饰者继承相同的抽象类,是客户端几乎透明的使用。这一点与代理模式相似。装饰器持有被装饰者的引用,可以调用原始的实现。在运行时,可以动态的设置这个引用,因此对于新增的一类功能,编写一个装饰器,即可对所有原始类进行装饰,解决了类的数量暴增的问题。同时,还可以实现嵌套多层装饰。结构如下:
    Component为抽象父类。
    ConcreteComponentt为具体实现。
    Decorator为装饰器父类。
    然后是具体装饰器。
    Java代码实现:
public interface Worker {
    public void work();
}
public class RealWorker implements Worker {
    @Override
    public void work() {
        System.out.println("working...");
    }
}
public class Decotator implements Worker {
    private Worker worker;
    public Decotator(Worker worker) {
        this.worker = worker;
    }
    @Override
    public void work() {
        worker.work();
    }
}
public class LogDecorator extends Decotator {
    public LogDecorator(Worker worker) {
        super(worker);
    }
    @Override
    public void work() {
        super.work();
        log();
    }
    public void log() {
        System.out.println("loging...");
    }
}
public class test {
    public static void main(String[] args) {
        RealWorker worker = new RealWorker();
        Decotator decorator = new LogDecorator(worker);
        decorator.work();
    }
}

输出:

working...
loging...
 
    装饰模式与代理模式原理看起来非常相似,实际有很多区别。
  • 代理模式通常用于对被代理对象的访问控制,而装饰模式用于对对象功能的增强。
  • 代理用于对被代理的控制,所以通常替代被代理对象,在代理内部生成被代理示例,外部透明。而装饰器只是增强和装饰的作用。对象通常由外部传进来。
  • 装饰器模式旨在动态的装饰,而代理模式在编写时就确定了代理 关系。(动态代理除外)
    装饰模式在变化层面上,与桥接模式也很相似,它们的区别:
  • 桥接模式行为和变化是横向的,彼此之间关联不大,而装饰模式行为和变化是纵向的,叠加起来组成完整的统一行为。
    总结:
        优点:
  • 对已有类扩展,符合开闭,可以动态扩展,控制类的数量,提高代码重用。
  • 可以嵌套装饰,比较灵活
  • 具体实现和适配器可以独立变化和扩展,符合开闭
        缺点:
  • 更灵活,单更容易出错
    适用:
  • 不影响实现的前提下,透明动态的扩展功能。
  • 用继承的方式扩展导致类数量暴增时。
posted @ 2016-01-31 14:41  进击的璐璐  阅读(240)  评论(0编辑  收藏  举报