本文实例代码:github.com/JamesZBL/ja…java
装饰器(Decorator)模式用于动态地给一个对象添加一些额外的职责。 就增长功能来讲, Decorator模式相比生成子类更为灵活。装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。git
纯粹的装饰模式很难找到,大多数的装饰模式的实现都是“半透明”的,而不是彻底透明的。换言之,容许装饰模式改变接口,增长新的方法。半透明的装饰模式是介于装饰模式和适配器模式之间的。适配器模式的用意是改变所考虑的类的接口,也能够经过改写一个或几个方法,或增长新的方法来加强或改变所考虑的类的功能。 大多数的装饰模式其实是半透明的装饰模式,这样的装饰模式也称作半装饰、半适配器模式。github
如下状况使用Decorator模式bash
在不影响其余对象的状况下, 以动态、 透明的方式给单个对象添加职责。ide
处理那些能够撤消的职责。this
当不能采用生成子类的方法进行扩充时。 一种状况是, 可能有大量独立的扩展, 为支持每一种组合将产生大量的子类, 使得子类数目呈爆炸性增加。 另外一种状况多是由于类定义被隐藏, 或类定义不能用于生成子类。spa
Component:定义一个对象接口, 能够给这些对象动态地添加职责。code
ConcreteComponent:定义一个对象, 能够给这个对象添加一些职责。cdn
Decorator:持有一个指向 Component 对象的引用,并定义一个与 Component 接口一致的接口。对象
ConcreteDecorator:一贯组件添加职责。
[站外图片上传中...(image-a0ad13-1526278884853)]
铁匠和木匠同时制做一把铁锤,第一种方案是木匠制做锤把,铁匠制做锤头;第二中方案是铁匠先制做锤把再制做锤头(假定这里的木匠只会制做锤把)。制做过程分为三部分:1.对材料进行初步的检查,2.进行制造并把部件安装起来以供后面的操做,3.完成以后再次进行检查,确保没有质量问题。
首先定义“操做”接口,包括先后两次检查以及安装的操做。
/** * 流水线上操做行为的接口 */
public interface Operation {
void checkBefore();
void join();
void chekcAfter();
}
复制代码
如今只由木匠制做锤把,定义一个木匠的操做类 CarpenterOperation
/** * 木匠的工做 */
public class CarpenterOperation implements Operation {
private static final Logger LOGGER = LoggerFactory.getLogger(CarpenterOperation.class);
@Override
public void checkBefore() {
LOGGER.info("检查木材");
}
@Override
public void join() {
LOGGER.info("打造锤把");
}
@Override
public void chekcAfter() {
LOGGER.info("检查成品锤把");
}
}
复制代码
因为某些缘由,铁匠决定本身制做锤把,如今铁匠身兼双职,将木匠的工做也承担了。定义一个铁匠操做类 HammerSmith
/** * 铁匠 */
public class HammerSmithOperation implements Operation {
private static final Logger LOGGER = LoggerFactory.getLogger(HammerSmithOperation.class);
private Operation previousOperation;
public HammerSmithOperation(Operation previousOperation) {
this.previousOperation = previousOperation;
}
@Override
public void checkBefore() {
previousOperation.checkBefore();
LOGGER.info("检查铁材");
}
@Override
public void join() {
previousOperation.join();
LOGGER.info("打造锤头");
}
@Override
public void chekcAfter() {
previousOperation.chekcAfter();
LOGGER.info("检查成品锤头");
}
}
复制代码
一样实现了“操做”的接口,铁匠的每一个操做都包含了木匠相应的操做,至关于对木匠的操做增长了一层包裹和扩展。这种包装就是 Decorator 模式中的装饰。
如今分别让木匠和铁匠进行一系列操做
/** * Decorator */
public class Application {
private static final Logger LOGGER = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
LOGGER.info("仅由木匠制做锤把");
Operation carpenter = new CarpenterOperation();
carpenter.checkBefore();
carpenter.join();
carpenter.chekcAfter();
LOGGER.info("由铁匠完成锤把以及锤头的制做");
Operation hammerSmith = new HammerSmithOperation(carpenter);
hammerSmith.checkBefore();
hammerSmith.join();
hammerSmith.chekcAfter();
}
}
复制代码
输出以下内容
仅由木匠制做锤把
检查木材
打造锤把
检查成品锤把
由铁匠完成锤把以及锤头的制做
检查木材
检查铁材
打造锤把
打造锤头
检查成品锤把
检查成品锤头
复制代码
1. 装饰模式和静态继承的机制的做用都是对现有的类增长新的功能,但装饰模式有着比静态继承更灵活的组合方式。装饰模式能够在运行的时候决定须要增长仍是去除一种“装饰”以及什么“装饰”。静态继承则没有这样的灵活性,它对类功能的扩展是在运行以前就肯定了的。
2. 得益于装饰模式在组合上的灵活性和便利性,咱们能够将各类装饰类进行组合,从而较为简单的创造各类不一样的行为集合,实现多种多样的功能。
1. 装饰者的对象和它装饰的对象本质上是彻底不一样的,装饰模式会生成许多的对象,致使区分各类对象变得困难
2. 因为使用相同的标识,对于程序的理解和排错过程的难度也会随之增长
我的博客同步更新,获取更多技术分享请关注:郑保乐的博客