1.装饰模式讲解

1.1定义

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

1.2装饰模式要点

透明的给一个对象增加功能,换句话说就是要给一个对象增加功能,但是不能让这个对象知道,也就是不能去改动这个对象。

面向对象设计的一个基本规则就是:尽量使用对象组合,而不是使用对象继承。

装饰者和被装饰对象有相同的超类型。

可以用一个或多个装饰者包装一个对象。

装饰者可以在所委托被装饰者的行为之前或之后,加上自己的行为,以达到特定的目的。

对象可以在任何时候被装饰,所以可以在运行时动态的,不限量的用你喜欢的装饰者来装饰对象。 

装饰模式中使用继承的关键是想达到装饰者和被装饰对象的类型匹配,而不是获得其行为。

装饰者一般对组件的客户是透明的,除非客户程序依赖于组件的具体类型。在实际项目中可以根据需要为装饰者添加新的行为,做到“半透明”装饰者。

适配器模式的用意是改变对象的接口而不一定改变对象的性能,而装饰模式的用意是保持接口并增加对象的职责。

1.3装饰模式的结构图和说明




抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。


具体构件(Concrete Component)角色:定义一个将要接收附加责任的类。


装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。


具体装饰(Concrete Decorator)角色:负责给构件对象添加上附加的责任。

1.4装饰模式示例代码

package demo21.decorator.example3;
/**
* 组件对象的接口,可以给这些对象动态的添加职责
*/
public abstract class Component {
/**
* 示例方法
*/
public abstract void operation();
}
***************************************************************************************************
package demo21.decorator.example3;
/**
* 具体实现组件对象接口的对象
*/
public class ConcreteComponent extends Component { public void operation() {
//相应的功能处理
}
}
**************************************************************************************************
package demo21.decorator.example3;
/**
* 装饰器接口,维持一个指向组件对象的接口对象,
* 并定义一个与组件接口一致的接口
*/
public abstract class Decorator extends Component {
/**
* 持有组件对象
*/
protected Component component;
/**
* 构造方法,传入组件对象
* @param component 组件对象
*/
public Decorator(Component component) {
this.component = component;
} public void operation() {
//转发请求给组件对象,可以在转发前后执行一些附加动作
component.operation();
}
}
**************************************************************************************************
package demo21.decorator.example3;
/**
* 装饰器的具体实现对象,向组件对象添加职责
*/
public class ConcreteDecoratorA extends Decorator {
public ConcreteDecoratorA(Component component) {
super(component);
}
/**
* 添加的状态
*/
private String addedState; public String getAddedState() {
return addedState;
} public void setAddedState(String addedState) {
this.addedState = addedState;
} public void operation() {
//调用父类的方法,可以在调用前后执行一些附加动作
//在这里进行处理的时候,可以使用添加的状态
super.operation();
}
}
**************************************************************************************************
package demo21.decorator.example3; /**
* 装饰器的具体实现对象,向组件对象添加职责
*/
public class ConcreteDecoratorB extends Decorator {
public ConcreteDecoratorB(Component component) {
super(component);
}
/**
* 需要添加的职责
*/
private void addedBehavior() {
//需要添加的职责实现
}
public void operation() {
//调用父类的方法,可以在调用前后执行一些附加动作
super.operation();
addedBehavior();
}
}

1.5装饰模式的本质

动态结合

1.6装饰模式的优缺点

优点:

比继承更加灵活

更容易复用功能

简化高层定义


缺点:

会产生很多细粒度对象

1.7何时选用

如果需要以动态透明的方式给对象添加职责,可以使用装饰模式

如果不适合使用子类来进行扩展的时候,可以考虑使用装饰模式

2.举例说明装饰模式

最最常见的例子就是java中的I/O数据流了,大家有时间可以看看他的继承实现结构图

假如你刚刚买了一辆汽车,是一个裸车,他不符合你的自己的个性化的要求,比如说外观不好看,轮胎不好,发动机马力不足等等。那么你就需要对外表进行装饰,换换颜色,把车里面增加一些坐垫。那么,这里就需要用到我们刚刚学过的装饰模式。


实例代码如下,代码注释的很清楚,我就不再赘述了

2.1对应Component

package demo21.decorator.example1;

/**
* 组件对象---车
*
* @author 王玉超
*
*/
public abstract class Car {
/**
* 行驶功能
*/
public abstract void run();
}

2.2对应ConcreteComponent

package demo21.decorator.example1;

/**
* 具体的车,假如是奥迪
*
* @author 王玉超
*
*/
public class AudiCar extends Car { @Override
public void run() {
System.out.println("奥迪行驶在马路上...");
} }

2.3对应Decorator

package demo21.decorator.example1;

/**
* 装饰器接口,维持一个指向组件对象的接口对象, 并定义一个与组件接口一致的接口,这是是装饰的接口
*/
public abstract class Decorator extends Car {
/**
* 持有组件对象
*/
private Car car; /**
* 构造方法,传入组件对象
*
* @param car
* 组件对象
*/
public Decorator(Car car) {
this.car = car;
} @Override
public void run() {
// 转发给component组件对象car
this.car.run();
}
}

2.4对应 ConcreteDecoratorA

package demo21.decorator.example1;

/**
* 装饰器的具体实现对象,向组件对象添加职责 ,这个是添加颜色的车
*/
public class AddColorCar extends Decorator {
public AddColorCar(Car car) {
super(car);
} /**
* 添加的状态,更改外观
*/
private String face; public void setFace(String face) {
this.face = face;
} public void addColor() {
System.out.println("我添加了颜色" + this.face);
} @Override
public void run() {
// 调用父类的方法,可以在调用前后执行一些附加动作
// 在这里进行处理的时候,可以使用添加的状态
super.run(); this.addColor();
}
}

2.5对应 ConcreteDecoratorB

package demo21.decorator.example1;

/**
* 装饰器的具体实现对象,向组件对象添加职责 ,这个是添加坐垫的车
*/
public class AddSeatCar extends Decorator {
public AddSeatCar(Car car) {
super(car);
} /**
* 添加的状态,添加坐垫
*/
private String seat; public void setSeat(String seat) {
this.seat = seat;
} public void addSeat() {
System.out.println("我添加了坐垫" + this.seat);
} @Override
public void run() {
// 调用父类的方法,可以在调用前后执行一些附加动作
// 在这里进行处理的时候,可以使用添加的状态
super.run(); this.addSeat();
}
}

2.6客户端使用

package demo21.decorator.example1;

public class Client {
public static void main(String[] args) {
// 被装饰的对象
Car car = new AudiCar();
// 装饰者对象
Decorator colorCar = new AddColorCar(car);
((AddColorCar) colorCar).setFace("红色"); Decorator seatCar = new AddSeatCar(colorCar);
((AddSeatCar) seatCar).setSeat("夏天清凉坐垫"); // 汽车跑起来吧
seatCar.run();
}
}

如何看完以后,还是不明白,我建议读者看看java I/O数据流里面的各种类,以及他们之间的关系,或许就明白了。

设计模式23---设计模式之装饰模式(Decorator)(结构型)的更多相关文章

  1. 设计模式09: Decorator 装饰模式(结构型模式)

    Decorator 装饰模式(结构型模式) 子类复子类,子类何其多加入我们需要为游戏中开发一种坦克,除了不同型号的坦克外,我们还希望在不同场合中为其增加以下一种多种功能:比如红外线夜视功能,比如水路两 ...

  2. 修饰模式(Decorator结构型)C#简单例子

    修饰模式(Decorator结构型)C#简单例子 玩家基本功能是移动.运行等等.BaseAbility新增加功能:1.伤害技能harmAbility:2.阻碍技能BaulkAbility:3.辅助技能 ...

  3. Java开发中的23种设计模式详解(2)结构型

    我们接着讨论设计模式,上篇文章我讲完了5种创建型模式,这章开始,我将讲下7种结构型模式:适配器模式.装饰模式.代理模式.外观模式.桥接模式.组合模式.享元模式.其中对象的适配器模式是各种模式的起源,我 ...

  4. (转)Java经典设计模式(2):七大结构型模式(附实例和详解)

    原文出处: 小宝鸽 总体来说设计模式分为三大类:创建型模式.结构型模式和行为型模式. 博主的上一篇文章已经提到过创建型模式,此外该文章还有设计模式概况和设计模式的六大原则.设计模式的六大原则是设计模式 ...

  5. 设计模式(11)--Flyweight(享元模式)--结构型

    作者QQ:1095737364    QQ群:123300273     欢迎加入! 1.模式定义: 享元模式是对象的结构模式.享元模式以共享的方式高效地支持大量的细粒度对象. 2.模式特点: 享元模 ...

  6. 设计模式06: Adapter 适配器模式(结构型模式)

    Adapter 适配器模式(结构型模式) 适配(转换)的概念无处不在:电源转接头.电源适配器.水管转接头... 动机(Motivation)在软件系统中,由于应用环境的变化,常常需要将“一些现存的对象 ...

  7. 大话设计模式宏观总结——创建型&结构型&行为型

    师傅验收项目的时候.问大话设计模式那三种类型的差别和联系是什么,顿时我傻了眼.由于除了知道这三种类型分别如何称呼以外.从来都没想过为什么这样划分?于是,我便回答:我没想过这个问题.若是从字面上来理解的 ...

  8. 装饰器模式 Decorator 结构型 设计模式 (十)

    引子           现实世界的装饰器模式 大家应该都吃过手抓饼,本文装饰器模式以手抓饼为模型展开简介 "老板,来一个手抓饼,  加个培根,  加个鸡蛋,多少钱?" 这句话会不 ...

  9. 设计模式-Decorator(结构型模式) 用于通过 组合 的方式 给定义的类 添加新的操作,这里不用 继承 的原因是 增加了系统的复杂性,继承使深度加深。

    以下代码来源: 设计模式精解-GoF 23种设计模式解析附C++实现源码 //Decorator.h #pragma once class Component { public: virtual ~C ...

  10. 设计模式(8)--Decorator--装饰器模式--结构型

    1.模式定义: 装饰模式又名包装(Wrapper)模式.装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 2.模式特点:    装饰模式能够实现动态的为对象添加功能,是从一个对象 ...

随机推荐

  1. linux和window下mkdir函数

    通过WIN32宏进行判断   window下mkdir函数   #include<direct.h> int _mkdir( const char *dirname );   linux下 ...

  2. Git教程之多人协作

    当你从远程仓库克隆时,实际上Git自动把本地的master分支和远程的master分支对应起来了,并且,远程仓库的默认名称是origin.要查看远程库的信息,用git remote:

  3. js动态创建及移除div的方法

    本文实例讲述了js动态创建及移除div的方法.分享给大家供大家参考.具体实现方法如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ...

  4. Java API ——String类

    1.String类概述 · 字符串是由多个字符组成的一串数据(字符序列),也可以看成是一个字符数组. · 字符串字符值“abc”也可以看成是一个字符串对象. · 字符串是常量,一旦被赋值,就不能被改变 ...

  5. 怎样开发Chrome浏览器的插件

    http://jingyan.baidu.com/article/b907e627fb90fd46e7891c3c.html Chrome 浏览器作为基于Webkit的新一代浏览器.Chrome自从正 ...

  6. Error Code: 1175

    用mysql workbench 更新一个表的时候报如下异常: Error Code: 1175. To disable safe mode, toggle the option in Prefere ...

  7. PHP操作FTP类 (上传下载移动创建等)

    使用PHP操作FTP-用法 Php代码 收藏代码 <? // 联接FTP服务器 $conn = ftp_connect(ftp.server.com); // 使用username和passwo ...

  8. R12 - OM改进了对成本与收入确认的流程

    我们知道在企业经营活动中,根据财务制度的要求,对于收入与成本确认有很复杂的原则,这里就不去细讨论这些原则了,要了解的话可以看纵横四海的BLOG: 中也有,但11中是灰的. 这个科目什么时候发挥作用呢? ...

  9. IOS,Object C学习过程中遇到的attributes

    @property 定义一个属性 @synthesize 告诉编译器自动为属性自动生成 getter 和setter方法 在定义属性的时候会用到如下@attributes nonatomic,告诉编译 ...

  10. 大四实习准备5_android广播机制

    2015-5-1 android 广播机制 5.1简介 分为标准广播(Normal broadcasts)(无先后顺序,几乎同时接收,不可截断)和有序广播(Ordered broadcasts)(有先 ...