Java设计模式之装饰器模式

一、概述

装饰模式,动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator 模式相比生成子类更为灵活。该模式以对客户端透明的方式扩展对象的功能。

1、什么时候使用
1) 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责;
2) 处理那些可以撤销的职责;
3) 当不能采用生成子类的方式进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

2、四大角色
1)抽象装饰对象角色(Component):接口,被装饰对象的基类,提供被装饰得方法,被装饰对象和装饰器都实现该接口;
2)具体装饰对象角色(ConcreteComponent):具体被装饰对象,它继承自Component,并实现需要被装饰的方法基本内容;      
3)抽象装饰器角色(Decorator):抽象类,维持一个装饰对象实例的引用,所有具体装饰器对象的父类,完成装饰器的部分职能。可以只对被装饰的对象进行一些简单的包裹,也可包含对被装饰的对象中方法的实现;      
4)具体装饰器角色(ConcreteDecorator):完成具体的装饰功能。装饰功能的实现是通过调用被装饰对象对应的方法,加上装饰对象自身的方法,这是装饰器模式动机中的添加额外功能的关键。可以有多个具体装饰角色,但是要注意各装饰之间的调用顺序。

二、代码示例

抽象装饰对象

public interface Person {
    void doCoding();
}

被装饰对象及其基本方法

public class Employee implements Person {

    @Override
    public void doCoding() {
        System.out.println("程序员实现功能需求");
    }
}

抽象装饰器,指定一个装饰对象的引用

public abstract class Manager implements Person {
    protected Person person;

    public void doCoding() {
        person.doCoding();
    }
}

具体装饰器,指定该装饰器的装饰对象

public class ManagerA extends Manager {

    public ManagerA(Person person) {
        this.person = person;
    }

    @Override
    public void doCoding() {
        doEarly();
        super.doCoding();
    }

    private void doEarly() {
        System.out.println("项目经理A处理前期事项");
    }

}

另一个具体装饰器

public class ManagerB extends Manager {

    public ManagerB(Person person) {
        this.person = person;
    }

    @Override
    public void doCoding() {
        super.doCoding();
        doEnd();
    }

    private void doEnd() {
        System.out.println("项目经理B处理后期事项");
    }

}

测试代码

public class ClientMain {
    public static void main(String args[]) {
        Person employee = new Employee();
        employee = new ManagerA(employee);//赋予程序猿项目经理A职责
        employee = new ManagerB(employee);//赋予程序猿项目经理B职责
        employee.doCoding();
    }
}

输出:
项目经理A处理前期事项
程序员实现功能需求
项目经理B处理后期事项

如果将上面“赋予程序猿项目经理A职责”与“赋予程序猿项目经理B职责”执行顺序换一下,发现输出依然如上,没有改变。这里的主要原因是将Person这个被装饰对象,从一个装饰器传递到另一个装饰器了。

特点
1) 装饰者和被装饰者拥有相同的超类型(可能是抽象类也可能是接口);
2)在装饰类中包含一个被装饰组件类的对象引用;
3)可以为被装饰对象添加额外的功能;
4)在装饰类中重写被装饰组件类中的方法,并对被装饰组件类中对应的方法调用;
5)因为装饰者和被装饰者拥有相同的抽象类型,因此在任何需要原始对象(被包装)的场合,都可以用装饰过的对象来替代它;可以用多个装饰类来包装一个对象,装饰类可以包装装饰类或被装饰对象。简而言之,装饰模式保持接口,增强性能;继承至Component同时包含一个Component作为其成员变量(装饰器模式动机中的动态地增加功能是在这里实现的)。
 

参考:
https://blog.csdn.net/wuqingyidongren/article/details/51537790
https://www.cnblogs.com/chenxing818/p/4705919.html

你可能感兴趣的:(设计模式)