设计模式(十二)Decorator模式

  Decorator模式就是不断地为对象添加装饰的设计模式。以蛋糕为例,程序中的对象就相当于蛋糕,然后像不断地装饰蛋糕一样地不断地对其增加功能,它就变成了使用目的更加明确的对象。

  首先看示例程序的类图。

  然后看示例程序代码。

 1 package bigjunoba.bjtu.decorator;
 2
 3 public abstract class Display {
 4
 5     public abstract int getColumns();
 6     public abstract int getRows();
 7     public abstract String getRowText(int row);
 8     public final void show() {
 9         for (int i = 0; i < getRows(); i++) {
10             System.out.println(getRowText(i));
11         }
12     }
13 }

  Display类是可以显示多行字符串的抽象类。getColumns方法用来获取横向行数,getRows方法用来获取纵向行数,getRowText方法用于获取指定的某一行的字符串,show方法是用来显示所有行字符串,首先获得行数,然后循环打印每一行的字符串。

 1 package bigjunoba.bjtu.decorator;
 2
 3 public class StringDisplay extends Display{
 4
 5     private String string;
 6
 7     public StringDisplay(String string) {
 8         this.string = string;
 9     }
10
11     @Override
12     public int getColumns() {
13         return string.getBytes().length;
14     }
15
16     @Override
17     public int getRows() {
18         return 1;
19     }
20
21     @Override
22     public String getRowText(int row) {
23         if (row == 0) {
24             return string;
25         } else {
26             return null;
27         }
28     }
29
30 }

  StringDisplay类用于显示单行字符串。string字段中保存的是要显示的字符串,由于StringDisplay类显示的是单行字符串,因此getColumns方法就是返回字符串的长度,而getRows方法返回的行数就是1,由于返回的是单行字符串,所以getRowText方法只有在传入的参数是0时才会返回字符串。StringDisplay类就相当于生日蛋糕中的核心蛋糕。

1 package bigjunoba.bjtu.decorator;
2
3 public abstract class Border extends Display {
4
5     protected Display display;
6     protected Border(Display display) {
7         this.display = display;
8     }
9 }

  Border类继承了Display类,但它是装饰边框的抽象类。这里有一些疑惑。装饰边框与装饰物具有了相同的方法,因此也就具有了一致性。

  还需要注意的是,Border类中的display字段,表示的是被装饰物,也就是说,只要是display类的子类,都可以传递进来保存在display字段中。更有趣的是,当然可以把Border类的子类传递进来,这样Border类的子类表示的装饰边框类中又有一个display字段,又可以传递进去一个边框或装饰物,反复循环。可以理解为实现了不断增加新的装饰物。

 1 package bigjunoba.bjtu.decorator;
 2
 3 public class SideBorder extends Border {
 4
 5     private char borderChar;
 6
 7     protected SideBorder(Display display, char ch) {
 8         super(display);
 9         this.borderChar = ch;
10         // TODO Auto-generated constructor stub
11     }
12
13     @Override
14     public int getColumns() {
15         return 1 + display.getColumns();
16     }
17
18     @Override
19     public int getRows() {
20         return display.getRows();
21     }
22
23     @Override
24     public String getRowText(int row) {
25         return borderChar + display.getRowText(row) + borderChar;
26     }
27
28 }

  SideBorder类可以用指定的字符来装饰字符串的左右两侧。borderChar字段用来保存指定的字符。首先通过调用父类的构造器指定display和ch。然后通过调用被装饰物display的相关方法来实现这一装饰目的。

 1 package bigjunoba.bjtu.decorator;
 2
 3 public class FullBorder extends Border{
 4
 5     protected FullBorder(Display display) {
 6         super(display);
 7     }
 8
 9     @Override
10     public int getColumns() {
11         return 1 + display.getColumns() + 1;
12     }
13
14     @Override
15     public int getRows() {
16         return 1 + display.getRows() + 1;
17     }
18
19     @Override
20     public String getRowText(int row) {
21         if (row ==0) {
22             return "[" + makeLine(‘@‘, display.getColumns()) + "]";
23         } else if (row == display.getRows() + 1) {
24             return "[" + makeLine(‘@‘, display.getColumns()) + "]";
25         } else {
26             return "|" + display.getRowText(row - 1)  + "|";
27         }
28
29     }
30
31     private String makeLine(char ch, int count) {
32         StringBuffer stringBuffer = new StringBuffer();
33         for (int i = 0; i < count + 1; i++) {
34             stringBuffer.append(ch);
35         }
36         return stringBuffer.toString();
37     }
38
39 }
  FullBorder类在字符串的上下左右都加上装饰边框。这里需要理解一下这些方法。getColumns方法获得的列数,也就是字符数为被装饰物的字符数加上两侧边框字符数。getRows方法获得的行数是被装饰物的行数加上上下边框的行数
  makeLine方法是连续地显示count次指定的字符ch,声明为private是因为防止被FullBorder以外的类使用。getRowText用于生成指定那一行的字符串,例如,row ==0表示下边框,row == display.getRows() + 1表示上边框。
 1 package bigjunoba.bjtu.decorator;
 2
 3 public class Main {
 4
 5     public static void main(String[] args) {
 6         Display display1 = new StringDisplay("Lianjiang");
 7         Display display2 = new SideBorder(display1, ‘*‘);
 8         Display display3 = new FullBorder(display2);
 9         Display display4 =
10                 new SideBorder(
11                         new FullBorder(
12                                 new FullBorder(
13                                         new SideBorder(
14                                                 new FullBorder(new StringDisplay("Lianjiang")),‘*‘
15                                                       )
16                                                 )
17                                       ),‘!‘
18                               );
19         System.out.println("这是display1的输出:");
20         display1.show();
21         System.out.println();
22
23         System.out.println("这是display2的输出:");
24         display2.show();
25         System.out.println();
26
27         System.out.println("这是display3的输出:");
28         display3.show();
29         System.out.println();
30
31         System.out.println("这是display4的输出:");
32         display4.show();
33     }
34 }

  这是测试类。

这是display1的输出:
Lianjiang

这是display2的输出:
*Lianjiang*

这是display3的输出:
[@@@@@@@@@@@]
|*Lianjiang*|
[@@@@@@@@@@@]

这是display4的输出:
![@@@@@@@@@@@@@@@]!
!|[@@@@@@@@@@@@@]|!
!||*[@@@@@@@@@]*||!
!||*|Lianjiang|*||!
!||*[@@@@@@@@@]*||!
!|[@@@@@@@@@@@@@]|!
![@@@@@@@@@@@@@@@]!

  测试结果如图所示。结合测试类来分析,1的装饰边框是2,然后得到完全体后2的装饰框是3,最后4是组合装饰,也就是多重边框。

原文地址:https://www.cnblogs.com/BigJunOba/p/8707587.html

时间: 2024-07-30 23:09:10

设计模式(十二)Decorator模式的相关文章

设计模式 ( 十二 ) 职责链模式(Chain of Responsibility)(对象行为)

 设计模式(十二)职责链模式(Chain of Responsibility)(对象行为型) 1.概述 你去政府部门求人办事过吗?有时候你会遇到过官员踢球推责,你的问题在我这里能解决就解决.不能解决就推卸给另外个一个部门(对象).至于究竟谁来解决问题呢?政府部门就是为了能够避免屁民的请求与官员之间耦合在一起,让多个(部门)对象都有可能接收请求,将这些(部门)对象连接成一条链,而且沿着这条链传递请求.直到有(部门)对象处理它为止. 样例1:js的事件浮升机制 样例2: 2.问题 假设有多个对象都有

C#设计模式之十二代理模式(Proxy Pattern)【结构型】

原文:C#设计模式之十二代理模式(Proxy Pattern)[结构型] 一.引言 今天我们要讲[结构型]设计模式的第七个模式,也是"结构型"设计模式中的最后一个模式,该模式是[代理模式],英文名称是:Proxy Pattern.还是老套路,先从名字上来看看."代理"可以理解为"代替",代替"主人"做一些事情,为什么需要"代理",是因为某些原因(比如:安全方面的原因),不想让"主人"直接

设计模式 ( 十八 ) 策略模式Strategy(对象行为型)

设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也经常遇到类似的情况,实现某一个功能有多种算法或者策略,我们能够依据环境或者条件的不同选择不同的算法或者策略来完毕该功能.如查找.排序等,一种经常使用的方法是硬编码(Hard Coding)在一个类中,如须要提供多种查找算法,能够将这些算法写到一个类中,在该类中提供多个方法,每个方法相应一个详细的查找算法:当然也能够将这些查找算法封装在一个统一的方法中,通过if-else-或者case等条件推断语句来进行选择.

【转】设计模式 ( 十八 ) 策略模式Strategy(对象行为型)

设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能.如查找.排序等,一种常用的方法是硬编码(Hard Coding)在一个类中,如需要提供多种查找算法,可以将这些算法写到一个类中,在该类中提供多个方法,每一个方法对应一个具体的查找算法:当然也可以将这些查找算法封装在一个统一的方法中,通过if-else-或者case等条件判断语句来进行选择.这

Java设计模式之二工厂模式

在上一篇中我们学习了单例模式,介绍了单例模式创建的几种方法以及最优的方法.本篇则介绍设计模式中的工厂模式,主要分为简单工厂模式.工厂方法和抽象工厂模式. 简单工厂模式 简单工厂模式是属于创建型模式,又叫做静态工厂方法模式.简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例.调用只需要告诉工厂类所需要的类型,工厂类就会返回需要的产品类工厂的子类. 可以说是工厂模式中最简单的一种. 打个比方,我们在电脑经常玩游戏,我们只需要告诉电脑我们要玩什么游戏,电脑就会打开这个游戏,我们并不需要关心游戏是

Java设计模式菜鸟系列(十二)组合模式建模与实现

转载请注明出处:http://blog.csdn.net/lhy_ycu/article/details/39828653 组合模式(Composite):组合模式有时又叫部分-整体模式,将对象组合成树形结构来表示"部分-整体"层次结构.组合模式在处理树形结构的问题时比较方便. 一.uml建模: 二.代码实现 /** * 示例:组合模式有时也称"整合-部分"模式 * * 组合模式在处理树形结构的问题时比较方便 * * 节点 */ class TreeNode { /

设计模式(十二)职责链模式(Chain of Responsibility)(对象行为型)

1.概述 你去政府部门求人办事过吗?有时候你会遇到过官员踢球推责,你的问题在我这里能解决就解决,不能解决就推卸给另外个一个部门(对象).至于到底谁来解决这个问题呢?政府部门就是为了可以避免屁民的请求与官员之间耦合在一起,让多个(部门)对象都有可能接收请求,将这些(部门)对象连接成一条链,并且沿着这条链传递请求,直到有(部门)对象处理它为止. 例子1:js的事件浮升机制 例子2: 2.问题 如果有多个对象都有可能接受请求,如何避免避免请求发送者与接收者耦合在一起呢? 3.解决方案 职责链模式(Ch

JAVA设计模式十二--State(状态模式)

状态模式(State Pattern)是设计模式的一种,属于行为模式. 定义(源于Design Pattern):当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类. 状态模式主要解决的是当控制一个对象状态的条件表达式过于复杂时的情况.把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简化.意图:允许一个对象在其内部状态改变时改变它的行为适用场景: 1.一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为. 2.一个操作中含有庞大的多分支结

设计模式学习总结(二十二)--访问者模式

定义 访问者模式就是表示一个作用于某对象结构中的各元素的操作,它使我们可以在不改变各元素的类的前提下定义作用于这些元素的新操作.访问者模式适用于数据结构相对稳定的系统. 角色 Vistor: 抽象访问者.为该对象结构中的ConcreteElement的每一个类声明的一个操作. ConcreteVisitor: 具体访问者.实现Visitor申明的每一个操作,每一个操作实现算法的一部分. Element: 抽象元素.定义一个Accept操作,它以一个访问者为参数. ConcreteElement:

Android与设计模式——装饰者(Decorator)模式

在阎宏博士的<JAVA与模式>一书中开头是这样描述装饰(Decorator)模式的: 装饰模式又名包装(Wrapper)模式.装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰模式的结构 装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任.换言之,客户端并不会觉得对象在装饰前和装饰后有什么不同.装饰模式可以在不使用创造更多子类的情况下,将对象的功能加以扩展.(上文来源于网络) 装饰模式的类图如下: 在装饰模式中的角色有: ● 抽象构件(Context)角色:给