Decorator模式------装饰边框与被装饰物的一致性
1.
》》不断地为对象装饰的设计模式称为Decorator 模式。
2. 示例程序
》》功能:给文字添加装饰边框。这里所谓的装饰边框是指用“ - ” “ + ” “ | ”
等字符组成的边框。
》》 类的一览表
》》 示例程序的类图
3. 代码实现
》》 Display 抽象类
/*** Display 是可以显示多行字符串的抽象类* getColumns() 用于获取横向字符数,是抽象方法,需要子类去实现* getRows() 用于获取纵向字符数,是抽象方法,需要子类去实现* getRowText( int row ) 用于获取指定的某一行的字符串,是抽象方法,需要子类去实现* show() 方法是显示所有的字符串的方法。show() 方法使用了 getRows() 和 getRowText() 等抽象方法,这属于 Template Method 模式*/
public abstract class Display {public abstract int getColumns(); // 获取横向字符数public abstract int getRows(); // 获取纵向字符数public abstract String getRowText(int row); // 获取第 row 行的字符数public final void show(){ // 全部显示for(int i = 0 ; i < getRows() ; i++){System.out.println(getRowText(i));}}
}
》》StringDisplay 类
/*** StringDisplay 类是用于显示单行字符串的类。* StringDisplay 类是 Display 类的子类*/
public class StringDisplay extends Display{private String string ; // 要显示的字符串public StringDisplay(String string){ // 通过参数传入要显示的字符串this.string = string;}@Overridepublic int getColumns() {return string.getBytes().length; // 字符数}@Overridepublic int getRows() {return 1; // 行数是 1}@Overridepublic String getRowText(int row) { // 仅当 row 为 0 时返回值if(row == 0 ){return string;}else{return null;}}
}
》》Border 类
/*** Border 类是装饰边框的抽象类。虽然它所表示的是装饰边框,但它也是 Display 类的子类。* 通过继承,装饰边框与被装饰物具有了相同的方法。具体而言, Border 类继承了父类 getColumns getRows getRowText show* 等各方法。从接口(API)角度而言,装饰边框(Border)与被装饰物(Display)具有相同的方法也就意味着它们具有一致性。*/
public abstract class Border extends Display{protected Display display ; // 被装饰物protected Border(Display display){ // 在生成实例时通过参数指定被装饰物this.display = display;}
}
》》 SideBorder 类
/*** SideBorder 类是一种具体的装饰边框,是 Border 类的子类* SideBorder 类用指定的字符(borderChar)装饰字符串的左右两侧*/
public class SideBorder extends Border {private char borderChar ; // 表示装饰边框的字符public SideBorder( Display display , char ch ){ // 通过构造函数指定 Display 和 装饰边框字符super(display);this.borderChar = ch;}@Overridepublic int getColumns() { // 字符数为字符串数加上两侧边框字符数return 1+ display.getColumns() +1 ;}@Overridepublic int getRows() { // 行数即被装饰物的行数return display.getRows();}@Overridepublic String getRowText(int row) { // 指定的那一行的字符串为被装饰物的字符串,加上两侧的边框的字符return borderChar + display.getRowText(row) + borderChar ;}
}
》》FullBorder 类
/*** FullBorder 类,是 Border 类的子类。* SideBorder 类会在字符串的左右两侧加上装饰边框,而 FullBorder 类则会在字符串的上下左右都加上装饰边框。* 在 SideBorder 类中可以指定边框的字符,而在 FullBorder 类中,边框的字符是固定的。*/
public class FullBorder extends Border {public FullBorder(Display display){super(display);}@Overridepublic int getColumns() { // 字符数为被装饰物的字符数加上两侧边框的字符数return 1+ display.getColumns() +1 ;}@Overridepublic int getRows() {return 1 + display.getRows() +1 ; // 行数为被装饰物的行数加上上下边框的行数}@Overridepublic String getRowText(int row) { // 指定的那一行的字符串if( row == 0 ){ //下边框return "+"+ makeLine('-' , display.getColumns()) + "+";}else if(row == display.getRows() + 1 ) { // 上边框return "+" + makeLine('-', display.getColumns()) + "+";}else{return "|" + display.getRowText( row - 1 ) + "|"; // 其他边框}}private String makeLine( char ch , int count ){ // 生成一个重复 count 次数字符 ch 的字符串StringBuffer buf = new StringBuffer();for( int i = 0 ; i < count ; i++){buf.append(ch);}return buf.toString();}
}
》》 Main 类
/*** Main 类是用于测试程序行为的类。在Main 类中一共生成了 4 个实例,即 b1~ b4 ,它们的作用分别如下所示:* b1 : 将 “Hello , world .”不加装饰地直接显示出来* b2 : 在 b1 的两侧加上装饰边框 “#”* b3 : 在 b2 的上下左右加上边框* b4 : 为“你好,世界。”加上多重边框*/
public class Main {public static void main(String[] args){Display b1 = new StringDisplay("Hello , world.");b1.show();System.out.println("-------------------------------------------------------------");Display b2 = new SideBorder(b1 , '#');b2.show();System.out.println("-------------------------------------------------------------");Display b3 = new FullBorder(b2);b3.show();System.out.println("-------------------------------------------------------------");Display b4 = new SideBorder(new FullBorder(new StringDisplay("你好,世界。")),'#');b4.show();}}
》》上面代码的执行效果如下:
》》 b3 、 b2 、 b1 的对象图
4. Decoraotor 模式中的登场角色
*** Component
增加功能时的核心角色,在示例程序中,由抽象类 Display 类扮演此角色。
*** ConcreteComponent
该角色是实现了 Component 角色所定义的接口(API)的具体实现。
在示例程序中,由 StringDisplay 类扮演此角色
*** Decorator(装饰物)
该角色具有与 Component 角色相同的接口(API)。在它的内部保存了被装饰对象
Component 角色。 Decorator 角色知道自己要装饰的对象。在示例程序中,由 Border
类扮演此角色。
*** ConcreteDecorator (具体的装饰物)
该角色具体的 Decorator 角色。在示例程序中, 由 SideBorder 类和 FullBorder 类扮演
此角色。
5. 扩展思路的要点
》》 接口(API)的透明性
**** 在 Decorator 模式中,装饰边框和被装饰物具有一致性(具有相同的接口 API)
**** 即使被装饰物被边框装饰起来了,接口(API)也不会被隐藏起来,其他类依然可以
调用该接口中的方法。这就是接口(API)的 “ 透明性 ” 。
***** 得益于接口(API)的透明性, Decorator 模式中也形成了类似于 Composite 模式中
的递归结构。 也就是说,装饰边框里面的“ 被装饰物 ”实际上又是别的物体的“ 装饰边框 ”。
就像是剥洋葱时以为洋葱心要出来了,结果却发现还是皮。
***** Decorator模式虽然与 Composite 模式一样,都具有递归结构,但是它们的使用目的不同。
%%% Decorator 模式的主要目的是通过添加装饰物来增加对象的功能。
》》 在不改变被装饰物的前提下增加功能
***** 在 Decorator 模式中,装饰边框与被装饰物具有相同的接口(API)。虽然接口(API)
是相同的,但是越装饰,功能则越多。
***** 不修改被装饰的类即可增加功能
***** Decorator 模式使用了委托。对 “ 装饰边框 ” 提出的要求(调用装饰边框的方法)会被转交
(委托)给“ 被装饰物 ”去处理。
》》可以动态地增加功能
***** Decorator 模式中用到了委托,它使类之间形成了弱关联关系。因此,不用改变框架代码,
就可以生成一个与其他对象具有不同关系的新对象。
》》只需要一些装饰物即可添加许多功能
***** 使用 Decorator 模式可以为程序添加许多功能。只要准备一些装饰边框,即使这些装饰边框
都只是具有非常简单的功能,也可以将它们自由组合成为新的对象。
***** Decorator 模式就是可以应对多功能对象的需求的一种模式。
》》 java.io 包与 Decorator 模式
***** java.io 包是用于输入输出(Input / Output , I / O )的包。
》》 导致增加许多很小的类
***** Decorator 模式的一个缺点是会导致程序中增加许多功能类似的很小的类。
6. 相关的设计模式
》》 Adapter 模式
***** Decorator 模式可以在不改变被装饰物的接口(API)的前提下,为被装饰物
添加边框(透明性)
***** Adapter 模式用于适配两个不同的接口(API)。
》》 Stragety 模式
***** Decorator 模式可以像改变被装饰物的边框或是为被装饰物添加多重边框那样,
来增加类的功能
***** Stragety 模式通过整体地替换算法来改变类的功能。
7. 延伸:继承和委托中的一致性
(一致性:即“ 可以将不同的东西当作同一种东西看待”)
》》 继承 ----- 父类和子类的一致性
***** 子类和父类具有一致性。
》》委托 ----- 自己和被委托对象的一致性
***** 使用委托让接口具有透明性时,自己和被委托对象具有一致性。
Decorator模式------装饰边框与被装饰物的一致性相关推荐
- 【笔记整理】图解设计模式 | 第12章 Decorator模式(装饰边框与被装饰物的一致性)
[笔记整理]图解设计模式 | 导航 定义 不断地为对象添加装饰的设计模式被称为Decorator模式,其中Decorator指的是"装饰物". Decorator模式中的登场角色 ...
- 装饰边框 与 被装饰物 一致的 Decorator模式
文章目录 Decorator模式 应用场景 本质 优点 缺点 角色 Decorator模式的类图 示例程序 示例程序的类图 示例代码 拓展思路 相关设计模式 满足的原则 Decorator模式 应用场 ...
- 设计模式(十二)-装饰器模式(Decorator Pattern)——装饰边框与被饰物的一致性
装饰器模式(Decorator Pattern)能不断的为对象添加装饰. Display.java package com.test.dp.Decorator.Sample;//抽象类,用于显示字符串 ...
- Decorator(装饰器) 模式
12.1 Decorator 模式 假如有一块蛋糕,如果只涂上奶油,其他什么也不加,就是奶油蛋糕.如果加上草莓,就是草莓奶油蛋糕.如果再加上一块黑色巧克力板,上面用白色巧克力写上姓名,然后插上蜡烛 ...
- 设计模式-Decorator模式(装饰者模式)
文章目录 装饰者模式 代码实现 为什么使用装饰者模式 装饰者模式 假如现在有一块蛋糕, 加上奶油就是奶油蛋糕.如果继续再加上草莓,就是草莓蛋糕,再加点蜡烛,就变成了生日蛋糕.不论是蛋糕.奶油蛋糕.草莓 ...
- 11.设计模式--装饰者模式(Decorator模式)
1.定义 装饰者模式是一种结构型模型,是动态的给对象增加职责,对于新增功能来说要比通过子类方式更加的灵活. 想想一下现在有一块蛋糕,他本质上就是一个蛋糕,而如果在蛋糕上加上巧克力就变成了巧克力蛋糕,而 ...
- 设计模式学习笔记——装饰(Decorator)模式
设计模式学习笔记--装饰(Decorator)模式 @(设计模式)[设计模式, 装饰模式, decorator] 设计模式学习笔记装饰Decorator模式 基本介绍 装饰案例 类图 实现代码 Dis ...
- 设计模式--装饰者(Decorator)模式
模式定义 动态(组合)地给一个对象增加一些额外的职责,就增加功能而言,Decorator模式比生成子类(继承)更为灵活(消除重复代码并且减少子类个数) 类图 应用场景 扩展一个类的功能或给一个类添加附 ...
- Decorator(装饰)--对象结构型模式
Decorator(装饰)–对象结构型模式 一.意图 1.动态地给一个对象添加一些额外的职责.就增加功能来说,Decorator模式相比生成子类更为灵活. 二.动机 1.在某些情况下我们可能会&quo ...
最新文章
- TortoiseSVN找不到系统指定路径
- JavaScript字符串的单引号和双引号问题
- caffe学习(二):利用mnist数据集训练并进行手写数字识别(windows)
- 使用Java调用以WSDL形式发布的web service
- PHP JSON数组与对象的理解
- dismiss和remove_remove的近义词辨析
- https及核心SSL
- [C++] 构造函数 which is of non-class type
- 判定浏览器是否支持原生透明
- pandas 时间序列分析(一)—— 基础
- 删除OSX中第三方的「偏好设置」程序(.prefPane)
- 计算机英语四六级成绩查询,CET成绩查询常见问题答疑-99宿舍
- 使用python将windows下多种文件格式转换成PDF格式
- [经典面试题]实现memcpy库函数
- 【网页制作】CSS文本和字体属性讲解【附讲解视频】
- stm32L0系统----开发环境搭建
- java强行访问别人qq空间_疯人院:如何使用javascript来获取QQ空间最近访客好友。...
- arcgis操作不响应
- 经商必读的创业类书籍推荐
- 卡迪夫大数据专业排名_2019英国大数据解析
热门文章
- 如何下载 数据库系统教程 第6版 大学模式sql文件
- (附源码)springboot基于web儿童教育网站 毕业设计111123
- UE4地编基础-灯光篇
- keil和proteus下载,和详细安装教程
- LKD 笔记:内核同步
- UMPC和MID的电源系统设计挑战及解决办法
- Tensorflow catdog-checkpoint
- C语言编程酒店房价,C语言酒店入住管理系统课设(附源码).doc
- 淘宝支持优站(U站)关键词设置代码meta name标签
- 未定义标识符 “uint“ “uint8_t” 解决