GOF23设计模式之装饰模式(decorator)
一、装饰模式概述
(1)动态的为一个对象增加新的功能。
(2)装饰模式是一种用于代替继承的技术,无需通过继承增加子类就能扩展对象的新功能。
使用对象的关联关系代替继承关系,更加灵活,同时避免类型体系的快速膨胀。
二、装饰模式实现细节
(1)Componen 抽象构件角色:
真实对象和装饰对象有相同的接口。这样,客户端就能够以真实对象相同的方式同装饰对象交互。
(2)ConcreteComponent 具体构件角色(真是角色):
IO 流中的FileInputStream、FileOutputStream
(3)Decorator 装饰角色:
持有一个抽象构件的引用。装饰对象接受所有客户端的请求,并把这些请求转发给真实的对象,这样就能在真实对象调用前后增加新的功能。
三、装饰模式情景导入
场景:设计一款可以增加任意功能的汽车,除了陆地上跑以外,还可以随意增加天上飞、水上游、自动驾驶等功能。
/**
* Component抽象构件角色
* @author CL
*
*/
public interface ICar {
void move();
} /**
* ConcreteComponent具体构件角色(真实角色)
* @author CL
*
*/
class Car implements ICar { @Override
public void move() {
System.out.println("陆地上跑!");
} } /**
* Decorator装饰角色
* @author CL
*
*/
class SuperCar implements ICar {
protected ICar car; public SuperCar(ICar car) {
this.car = car;
} @Override
public void move() {
car.move();
}
} /**
* ConcreteDecorator具体装饰角色
* 新增新的功能:天上飞
* @author CL
*
*/
class FlyCar extends SuperCar { public FlyCar(ICar car) {
super(car);
} public void fly() {
System.out.println("天上飞!");
} @Override
public void move() {
super.move();
fly();
} } /**
* ConcreteDecorator具体装饰角色
* 新增新的功能:水上游
* @author CL
*
*/
class WaterCar extends SuperCar { public WaterCar(ICar car) {
super(car);
} public void swim() {
System.out.println("水上游!");
} @Override
public void move() {
super.move();
swim();
} } /**
* ConcreteDecorator具体装饰角色
* 新增新的功能:人工智能 自动驾驶
* @author CL
*
*/
class AICar extends SuperCar { public AICar(ICar car) {
super(car);
} public void autoMove() {
System.out.println("自动驾驶!");
} @Override
public void move() {
super.move();
autoMove();
} }
测试:
/**
* 测试装饰模式
* @author CL
*
*/
public class Client { public static void main(String[] args) {
System.out.println("基本功能,陆地上跑-->");
Car car = new Car();
car.move(); System.out.println("\n增加新的功能,天上飞-->");
FlyCar flyCar = new FlyCar(car);
flyCar.move(); System.out.println("\n增加新的功能,水上游-->");
WaterCar waterCar = new WaterCar(car);
waterCar.move(); System.out.println("\n增加新的功能,水上游, 自动驾驶-->");
AICar aCar = new AICar(new WaterCar(car));
aCar.move(); System.out.println("\n增加新的功能,天上飞,水上游, 自动驾驶-->");
AICar c = new AICar(
new WaterCar(
new FlyCar(car)));
c.move();
} }
控制台输出:
基本功能,陆地上跑-->
陆地上跑! 增加新的功能,天上飞-->
陆地上跑!
天上飞! 增加新的功能,水上游-->
陆地上跑!
水上游! 增加新的功能,水上游, 自动驾驶-->
陆地上跑!
水上游!
自动驾驶! 增加新的功能,天上飞,水上游, 自动驾驶-->
陆地上跑!
天上飞!
水上游!
自动驾驶!
四、装饰模式总结
装饰模式(Decorator)也叫做包装器模式(Wrapper)
装饰模式降低系统的耦合度,可以动态的增加或删除对象的职责,并使得需要装饰的具体构建类和具体装饰类可以独立变化,以便增加新的具体构建类和具体装饰类。
优点:
a. 扩展对象功能,比继承灵活,不会导致类个数急剧增加;
b. 可以对一个对象进行多次装饰,创造出不同行为的组合,得到功能更加强大的对象;
c. 具体构建类和具体装饰类可以独立变化,用户可以根据需要自己增加新的具体构件子类和具体装饰子类。
缺点:
a. 产生很多小对象,大量小对象占据内存,一定程度上影响性能;
b. 装饰模式易于出错,调试排查比较麻烦。
五、装饰模式实际开发应用场景
(1)IO 中输入流和输出流的设计
a. Componen 抽象构件角色:
IO 流中的InputStream、OutputStream、Reader、Writer
b. ConcreteComponen 具体构件角色:
IO 流中的FileInputStream、FileOutputStream
c. Decorator 装饰角色:
持有一个抽象构件的引用:IO 流中的FileInputStream、FileOutputStream
d. ConcreteDecorator 具体装饰角色:
负责给构件对象增加新的责任,IO 流中的BufferedInputStream、BufferedOutputStream
(2)Swing 包中图形界面构件功能;
(3)Servlet API 中提供了一个 request 对象的Decorator 设计模式的默认实现类,增强了 request 对象的功能;
(4)Struts2 中,request、response、session 对象的处理;
(5)…………
GOF23设计模式之装饰模式(decorator)的更多相关文章
- 乐在其中设计模式(C#) - 装饰模式(Decorator Pattern)
原文:乐在其中设计模式(C#) - 装饰模式(Decorator Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 装饰模式(Decorator Pattern) 作者:weba ...
- 【GOF23设计模式】装饰模式
来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_装饰模式.IO流底层架构.装饰和桥接模式的区别 package com.test.decorator; /** * Com ...
- 二十四种设计模式:装饰模式(Decorator Pattern)
装饰模式(Decorator Pattern) 介绍动态地给一个对象添加一些额外的职责.就扩展功能而言,它比生成子类方式更为灵活.示例有一个Message实体类,某个对象对它的操作有Insert()和 ...
- 设计模式-09装饰模式(Decorator Pattern)
1.模式动机 一般有两种方式可以实现给一个类或对象增加行为: 继承机制:使用继承机制是给现有类添加功能的一种有效途径,通过继承一个现有类可以使得子类在拥有自身方法的同时还拥有父类的方法.但是这种方法是 ...
- 设计模式之装饰模式(Decorator)摘录
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/fengbingchun/article/details/29237955 23种GOF设计模式一般分 ...
- 设计模式 笔记 装饰模式 Decorator
//---------------------------15/04/17---------------------------- //Decorator 装饰模式----对象结构型模式 /* 1:意 ...
- 结构型设计模式之装饰模式(Decorator)
结构 意图 动态地给一个对象添加一些额外的职责.就增加功能来说,D e c o r a t o r 模式相比生成子类更为灵活. 适用性 在不影响其他对象的情况下,以动态.透明的方式给单个对象添加职责. ...
- 设计模式之装饰模式(Decorator)
装饰模式原理:给对象增加特性,这种特性是一种累加的效果 代码如下 #include <iostream> #include <string> #include <list ...
- 【设计模式】—— 装饰模式Decorator
前言:[模式总览]——————————by xingoo 模式意图 在不改变原来类的情况下,进行扩展. 动态的给对象增加一个业务功能,就功能来说,比生成子类更方便. 应用场景 1 在不生成子类的情况下 ...
随机推荐
- 基于centos的docker安装
1. 安装需求 内核版本3.10以上 Centos 7以上 64位版本 2. 使用root登录或者具有sudo权限 3. 确保系统是最新的 yum update 4. 添加yum源 tee /etc/ ...
- URAL 1203 Scientific Conference 简单dp 难度:0
http://acm.timus.ru/problem.aspx?space=1&num=1203 按照结束时间为主,开始时间为辅排序,那么对于任意结束时间t,在此之前结束的任务都已经被处理, ...
- SpringXML方式给bean初始化属性值
可以在Spring容器初始化bean的时候给bean的属性赋初始值,直接在property标签里设置即可 1 2 3 4 5 6 <bean name="user**" cl ...
- SpringXML方式配置bean的集合注入:list,map,properties
新建一个bean,设置相应的集合属性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class Collecti ...
- CocoaPods Mac App的安装和使用
CocoaPods桌面应用版下载地址:https://cocoapods.org/app打开应用会提示你是否安装命令行工具,选择install就也可以在命令行使用Pod了.省去了上面的步骤们,方便快捷 ...
- String类的编码和解码问题
我们前面知道同一个字符在利用不同的编码表得到的结果一般是不一样的. 这里讨论个字符串的编码和解码问题 字符串的一些方法: String(byte[] b,Charset charset); Strin ...
- Django中通过定时任务触发页面静态化的方式
安装 pip install django-crontab 添加应用 INSTALLED_APPS = [ ... 'django_crontab', # 定时任务 ... ] 设置任务的定时时间 在 ...
- 剑指offer--43.连续子数组的最大和
最大子段和,最大能取所有 ---------------------------------------------------------------- 时间限制:1秒 空间限制:32768K 热度 ...
- vue.js 源代码学习笔记 ----- 工具方法 option
/* @flow */ import Vue from '../instance/index' import config from '../config' import { warn } from ...
- 理解 uncaughtException 和 domain 和 try catch 区别
文章 实践 uncaughtException 捕获的是全局的异常, 反应慢, 每个回调完成后才发出异常, 书写也麻烦 domain 可以捕获每个异常, 及时反馈, 并且书写简洁 但他们两个捕获的异常 ...