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模式------装饰边框与被装饰物的一致性相关推荐

  1. 【笔记整理】图解设计模式 | 第12章 Decorator模式(装饰边框与被装饰物的一致性)

    [笔记整理]图解设计模式 | 导航 定义 不断地为对象添加装饰的设计模式被称为Decorator模式,其中Decorator指的是"装饰物". Decorator模式中的登场角色 ...

  2. 装饰边框 与 被装饰物 一致的 Decorator模式

    文章目录 Decorator模式 应用场景 本质 优点 缺点 角色 Decorator模式的类图 示例程序 示例程序的类图 示例代码 拓展思路 相关设计模式 满足的原则 Decorator模式 应用场 ...

  3. 设计模式(十二)-装饰器模式(Decorator Pattern)——装饰边框与被饰物的一致性

    装饰器模式(Decorator Pattern)能不断的为对象添加装饰. Display.java package com.test.dp.Decorator.Sample;//抽象类,用于显示字符串 ...

  4. Decorator(装饰器) 模式

    12.1 Decorator 模式   假如有一块蛋糕,如果只涂上奶油,其他什么也不加,就是奶油蛋糕.如果加上草莓,就是草莓奶油蛋糕.如果再加上一块黑色巧克力板,上面用白色巧克力写上姓名,然后插上蜡烛 ...

  5. 设计模式-Decorator模式(装饰者模式)

    文章目录 装饰者模式 代码实现 为什么使用装饰者模式 装饰者模式 假如现在有一块蛋糕, 加上奶油就是奶油蛋糕.如果继续再加上草莓,就是草莓蛋糕,再加点蜡烛,就变成了生日蛋糕.不论是蛋糕.奶油蛋糕.草莓 ...

  6. 11.设计模式--装饰者模式(Decorator模式)

    1.定义 装饰者模式是一种结构型模型,是动态的给对象增加职责,对于新增功能来说要比通过子类方式更加的灵活. 想想一下现在有一块蛋糕,他本质上就是一个蛋糕,而如果在蛋糕上加上巧克力就变成了巧克力蛋糕,而 ...

  7. 设计模式学习笔记——装饰(Decorator)模式

    设计模式学习笔记--装饰(Decorator)模式 @(设计模式)[设计模式, 装饰模式, decorator] 设计模式学习笔记装饰Decorator模式 基本介绍 装饰案例 类图 实现代码 Dis ...

  8. 设计模式--装饰者(Decorator)模式

    模式定义 动态(组合)地给一个对象增加一些额外的职责,就增加功能而言,Decorator模式比生成子类(继承)更为灵活(消除重复代码并且减少子类个数) 类图 应用场景 扩展一个类的功能或给一个类添加附 ...

  9. Decorator(装饰)--对象结构型模式

    Decorator(装饰)–对象结构型模式 一.意图 1.动态地给一个对象添加一些额外的职责.就增加功能来说,Decorator模式相比生成子类更为灵活. 二.动机 1.在某些情况下我们可能会&quo ...

最新文章

  1. TortoiseSVN找不到系统指定路径
  2. JavaScript字符串的单引号和双引号问题
  3. caffe学习(二):利用mnist数据集训练并进行手写数字识别(windows)
  4. 使用Java调用以WSDL形式发布的web service
  5. PHP JSON数组与对象的理解
  6. dismiss和remove_remove的近义词辨析
  7. https及核心SSL
  8. [C++] 构造函数 which is of non-class type
  9. 判定浏览器是否支持原生透明
  10. pandas 时间序列分析(一)—— 基础
  11. 删除OSX中第三方的「偏好设置」程序(.prefPane)
  12. 计算机英语四六级成绩查询,CET成绩查询常见问题答疑-99宿舍
  13. 使用python将windows下多种文件格式转换成PDF格式
  14. [经典面试题]实现memcpy库函数
  15. 【网页制作】CSS文本和字体属性讲解【附讲解视频】
  16. stm32L0系统----开发环境搭建
  17. java强行访问别人qq空间_疯人院:如何使用javascript来获取QQ空间最近访客好友。...
  18. arcgis操作不响应
  19. 经商必读的创业类书籍推荐
  20. 卡迪夫大数据专业排名_2019英国大数据解析

热门文章

  1. 如何下载 数据库系统教程 第6版 大学模式sql文件
  2. (附源码)springboot基于web儿童教育网站 毕业设计111123
  3. UE4地编基础-灯光篇
  4. keil和proteus下载,和详细安装教程
  5. LKD 笔记:内核同步
  6. UMPC和MID的电源系统设计挑战及解决办法
  7. Tensorflow catdog-checkpoint
  8. C语言编程酒店房价,C语言酒店入住管理系统课设(附源码).doc
  9. 淘宝支持优站(U站)关键词设置代码meta name标签
  10. 未定义标识符 “uint“ “uint8_t” 解决