Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱
MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina.com

目录

装饰模式

简介

装饰模式以对客户端透明的方式【扩展】对象的功能,客户端并不会觉得对象在装饰前和装饰后有什么不同。

PS:对客户端透明的意思是,因为装饰类和原始类实现了相同的接口,所以你只需像使用原始类一样使用装饰类即可。

换句话说,你不需要学习新知识,就能完全知道装饰类有什么用

装饰模式是【继承】关系的一个替代方案。

只为增加功能而使用继承,当基类较多时会导致继承体系越来越臃肿,装饰模式可以在不创造更多子类的情况下,将对象的功能加以扩展。

装饰对象和真实对象有相同的接口,这样客户端对象就可以以和真实对象相同的方式和装饰对象交互。

装饰对象包含一个真实对象的引用,它接收所有来自客户端的请求,并把这些请求转发给真实的对象,并在转发这些请求之前或之后可以附加一些功能。

角色

  • 抽象构件角色(Component):给出一个抽象接口,以规范准备接收附加责任的对象。
  • 具体构件角色(Concrete Component):定义将要接收附加责任的类。
  • 装饰角色(Decorator):持有一个构件(Component)对象的引用,并定义一个与抽象构件接口一致的接口。
  • 具体装饰角色(Concrete Decorator):负责给构件对象“贴上”附加的责任。

优点 :

  • 解决【类膨胀】【类爆炸】【继承体系臃肿】的问题
  • 扩展性非常好
  • 比继承更灵活

案例

原始接口只具有work功能:

interface IWork {
public void work();
}

此接口有很多不同类型的实现类:

class People implements IWork {
@Override
public void work() {
System.out.println("人开始干活.....................");
}
} class Robot implements IWork {
@Override
public void work() {
System.out.println("机器人开始干活.....................");
}
} class AI implements IWork {
@Override
public void work() {
System.out.println("AI开始干活.....................");
}
}

如果使用继承来扩展原始类的功能:

class PeopleV2 extends People {
@Override
public void work() {
System.out.println("先检查零件是否正常");//增强的功能
super.work();
System.out.println("干完活收拾下房间\n");//增强的功能
}
} class RobotV2 extends Robot {
@Override
public void work() {
System.out.println("先检查零件是否正常");//增强的功能
super.work();
System.out.println("干完活收拾下房间\n");//增强的功能
}
} class AIV2 extends AI {
@Override
public void work() {
System.out.println("先检查零件是否正常");//增强的功能
super.work();
System.out.println("干完活收拾下房间\n");//增强的功能
}
}

可以看到,为了在需要的时候(注,不能直接更改原始类的work()方法,因为这些增强功能不是任何时候都需要的)增强原始类的功能,需要为每IWork接口的所有实现类都添加一个子类,在子类中实现对原始类功能的增强。当IWork接口的实现类很多时,会造成类体系迅速膨胀!

如果使用装饰模式来扩展原始类的功能,则只需定义一个装饰角色类Decorator:

class Decorator implements IWork {
private IWork work;
public Decorator(IWork work) {
this.work = work;
} @Override
public void work() {
System.out.println("先检查零件是否正常");//增强的功能
work.work();
System.out.println("干完活收拾下房间\n");//增强的功能
}
}

动态地给对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。

客户端调用

public class Test {
public static void main(String args[]) {
IWork work = new People();
Decorator decorator = new Decorator(work);
decorator.work();
}
}

2016-10-31

Decorator Wrapper 装饰模式 MD的更多相关文章

  1. Decorator Wrapper 装饰模式 包装

    简介 装饰模式 装饰模式以对客户端[透明]的方式[扩展]对象的功能,客户端并不会觉得对象在装饰前和装饰后有什么不同,是继承关系的一个替代方案. 若只为增加功能而使用继承,当基类较多时会导致继承体系越来 ...

  2. python's decorator&wrapper

    [python's decorator&wrapper] decorator A function returning another function, usually applied as ...

  3. Decorator Pattern(装饰模式)

    装饰模式:动态的给一个对象添加一些额外的职责.当然我们也可以通过继承来实现类似的功能,但是随着子类的增多,各种子类的组合会造成子类的急剧膨胀. Requirement: 假设客户有一个要求,需要打一个 ...

  4. 深入浅出设计模式——装饰模式(Decorator Pattern)

    模式动机 一般有两种方式可以实现给一个类或对象增加行为: 继承机制,使用继承机制是给现有类添加功能的一种有效途径,通过继承一个现有类可以使得子类在拥有自身方法的同时还拥有父类的方法.但是这种方法是静 ...

  5. 第 13 章 装饰模式【Decorator Pattern】

    以下内容出自:<<24种设计模式介绍与6大设计原则>> Ladies and gentlemen,May I get your attention,Please?,Now I’ ...

  6. Decorator学习笔记

    初学者,自己的理解,请各位前辈不吝指正! Decorator,装饰模式,设计模式之一,谈谈我的理解,装饰这个词在我概念中就是给某个事物加上一些美丽的外表,把它变得更加完美.但是装饰是可以随时改变的,可 ...

  7. 《Java设计模式》之装饰模式

    装饰模式(Decorator) 1.    装饰模式(Decorator)的定义:又名包装(Wrapper)模式.装饰模式以对client透明的方式扩展对象的功能,是继承关系的一个替代方案. 2.   ...

  8. 12、Decorator 装饰器 模式 装饰起来美美哒 结构型设计模式

    1.Decorator模式 装饰模式又名包装(Wrapper)模式.装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰器模式(Decorator Pattern)允许向一个现 ...

  9. Python Decorator分析

    decorator本身是一个函数,这个函数的功能是接受被修饰的函数(decorated)作为参数,返回包装函数(wrapper)替换被修饰函数(decorated). @decorator func ...

随机推荐

  1. linux通过c++实现线程池类

    目录 线程池的实现 线程池已基于C++11重写 : 基于C++11实现线程池的工作原理 前言 线程池的概念 使用原因及适用场合 线程池的实现原理 程序测试 线程池的实现 线程池已基于C++11重写 : ...

  2. python3.6 利用requests和正则表达式爬取猫眼电影TOP100

    import requests from requests.exceptions import RequestException from multiprocessing import Pool im ...

  3. IdentityServer4之JWT签名(RSA加密证书)及验签

    一.前言 在IdentityServer4中有两种令牌,一个是JWT和Reference Token,在IDS4中默认用的是JWT,那么这两者有什么区别呢? 二.JWT与Reference Token ...

  4. ONVIF开发实例

    <开发过过程中的经验总结> ➤工具的使用     (1)首先将文件soapClientLib.c 中"代码"的第二行和第三行注释掉,实际上该文件根本没有用,为了保险起见 ...

  5. 【BZOJ 3036】 3036: 绿豆蛙的归宿 (概率DP)

    3036: 绿豆蛙的归宿 Time Limit: 2 Sec  Memory Limit: 128 MBSubmit: 491  Solved: 354 Description 随着新版百度空间的下线 ...

  6. DataTable初次使用笔记

    概述:DataTable是一个jQuery插件,用于生成HTML表格,功能很强大. 使用: 使用DataTable需要引入jQuery,因为他是基于jQuery的插件,然后引入DataTable的js ...

  7. [Visual Studio] VS2012调试时很慢的解决方案

      1.转自http://guooge.com/archives/408.html VS2010调试极慢获取出现死机,因为启动了IntelliTrace Visual Studio 2010 Ulti ...

  8. unity热更新

    Unity3D 学习笔记4 —— UGUI+uLua游戏框架 C#Light 和 uLua的对比第二弹 在Unity中使用Lua脚本:语言层和游戏逻辑粘合层处理 Ulua_toLua_基本案例 Uni ...

  9. 【scrapy】使用方法概要(一)(转)

    [请初学者作为参考,不建议高手看这个浪费时间] 工作中经常会有这种需求,需要抓取互联网上的数据.笔者就经常遇到这种需求,一般情况下会临时写个抓取程序,但是每次遇到这种需求的时候,都几乎要重头写,特别是 ...

  10. lamp经典安装

    一.网络方面的知识 2 ①-网络常见的命令 2 ②-网卡相关 2 ③-防火墙相关 2 ④-selinux相关 3 二.上传amp源代码包 5 三.linux下软件安装-vsftpd安装 6 ①-rpm ...