设计模式decorator模式(代码片段)

BigJunOBa BigJunOBa     2022-10-30     722

关键词:

  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是组合装饰,也就是多重边框。

  下面是Decorator模式的类图。

 

  Component:增加功能的核心角色。也就是装饰前的蛋糕,只是定义了蛋糕的接口,在示例中,是Display类。

  ConcreteComponent:实现了Component定义的接口的具体蛋糕。

  Decorator:具有与Component相同的接口,内部保存了被装饰对象--Component,示例中也就是Border类。

  ConcreteDecorator:具体的实现类。示例程序中的SideBorder类和FullBorder类。

 

  这里要扩展的知识是继承和委托。

  1.继承

  继承可以让子类和父类具有一致性。举一个例子,父类Parent和子类Child,有这么一个情况就是,Child类的实例可以保存在Parent类型的变量中,也可以调用从Parent类中继承的方法。比如:

 Parent obj = new Child();
 obj.parentMethod();

   也就是说,可以像操作Parent类的实例一样操作Child类的实例,这是将子类当做父类的一个例子。

  反过来,如果想将父类当做子类看待,需要先进行类型转换。

Perent obj = new Child();
((Child)obj).child.Method();

   2.委托

  使用委托让接口具有透明性,自己和委托对象具有一致性。

  先看一个例子:

abstract class Flower
    abstract void method();    


class Rose extends Flower 
    Violet obj = ...
    void method()
        obj.method();
            
    

class Violet extends Flower(
    void method()
     ...
    

  第一个例子是编写一个共同的抽象类Flower。

interface class Flower
    abstract void method();    


class Rose implements Flower 
    Violet obj = ...
    void method()
        obj.method();
            
    

class Violet implements Flower(
    void method()
     ...
    

   第二个例子就是编写一个Flower接口。

  这两个例子主要是说明,Rose和Violet都有相同的method方法,但是Rose将method方法的处理委托给了Vidlet,这样就体现了method方法是共通的。

 

设计模式---单一职责模式之装饰模式(decorator)(代码片段)

前提:"单一职责"模式在软件组件的设计中,如果责任划分的不清晰,使用继承,得到的结果往往是随着需求的变化,子类急剧膨胀,同时充斥着重复代码,这时候的关键是划清责任典型模式(表现最为突出)装饰模式Decorator桥... 查看详情

设计模式c++实现:装饰(decorator)模式(代码片段)

转载请注明,来自:http://blog.csdn.net/skyman_2001classComponentpublic: Component() virtual~Component() virtualvoidoperation()=0; virtualComponent*remove()=0;;classConcreteComponent:publi 查看详情

decorator装饰模式(代码片段)

装饰模式又名包装(Wrapper)模式。装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。装饰模式的结构装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任。换言之,客户端并不会觉得对象... 查看详情

装饰模式(decorator-pattern)(代码片段)

装饰模式(decorator-pattern)文章目录装饰模式(decorator-pattern)一、手抓饼点餐系统二、要求进阶三、装饰模式概要四、装饰模式的优劣及应用场景1.优点2.缺点3.应用场景一、手抓饼点餐系统请设计一个手抓饼点餐系统,支持加配... 查看详情

设计模式之装饰模式(decorator)详解及代码示例(代码片段)

一、装饰模式的定义  装饰(Decorator)模式的定义:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。二、装饰模式优缺点  装饰(Decorator)模式的主... 查看详情

十decorator装饰器模式(代码片段)

设计:代码清单:DisplaypublicabstractclassDisplaypublicabstractintgetColumns();publicabstractintgetRows();publicabstractStringgetRowText(introw);publicfinalvoidshow()for(inti=0;i<getRows();i++)System.out.println(getRowText(i));StringDisolaypublicclassStringDisplayextendsDisplayprivateStri... 查看详情

decorator设计模式的实现中装饰设计模式学习笔记(代码片段)

装饰设计模式a)当某个类的某个方法不适应当前业务的需要思路:》扩展父类的可供扩展的方法,可以使有,但不优》装饰设计模式(推荐)开发步骤:1)写一个普通类或写一个普通类扩展[extends]一个父类2)写一个需要被包装的实例... 查看详情

今天俺要说一说装饰着模式(decorator)(代码片段)

前言:装饰者模式,又叫做装饰器模式.顾名思义,就是给对象包裹一层,包装。让它变成你喜欢的对象。这种模式在我们开发中经常会用到,它是一种处理问题的技巧,即不让程序死板,也可以扩展程序。(一)何时能用到它》》》  1... 查看详情

装饰模式(decorator-pattern)(代码片段)

装饰模式(decorator-pattern)文章目录装饰模式(decorator-pattern)一、手抓饼点餐系统二、要求进阶三、装饰模式概要四、装饰模式的优劣及应用场景1.优点2.缺点3.应用场景一、手抓饼点餐系统请设计一个手抓饼点餐系统,支持加配... 查看详情

python笔记·函数装饰器(decorators)(代码片段)

...具有“横切”性质编程场合,与Java中的动态代理以及设计模式中的代理模式类似(与装饰器模式有相似之处,但有差异),可以认为是Python在语言级别上内置实现了代理模式或面向切面编程模式 查看详情

设计模式-composite(结构型模式)用于递归构建树状的组合结构,与decorator的区别是composite旨在通过构造子类而添加新操作,而decorator直接添加新操作。(代(代码片段)

以下代码来源:设计模式精解-GoF23种设计模式解析附C++实现源码//Component.h#pragmaonceclassComponentpublic:Component();virtual~Component();virtualvoidOperation()=0;virtualvoidAdd(constComponent&);virtualvoidRemove(constComponent&);virtualComponent*getChild(int);protec... 查看详情

结构型模式-装饰器模式(代码片段)

  对原有对象进行修饰,如有一个篮子,现在对篮子进行修饰,放入苹果,香蕉,橙子packageconstructional.pattern.decorator;/**创建一个对象的抽象也就是接口*/publicinterfaceBasketpublicvoidshow();packageconstructional.pattern.decorator;/***身份:被... 查看详情

java示例代码_使用decorator模式时保留接口

java示例代码_使用decorator模式时保留接口 查看详情

装饰模式(代码片段)

前言  装饰模式(Decorator),动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。一、Component抽象类1publicabstractclassComponent23publicabstractvoidOperationa();4  Component定义一个对象接口,可以给... 查看详情

设计模式——6.装饰模式(代码片段)

装饰模式(Decorator)动态的为一个对象增加额外的职责,为对象增加功能时,使用装饰模式比单纯的子类继承要更加的灵活。装饰模式结构图:C++BaseClass对象抽象基类://file:BaseClass.h#pragmaonceclassBaseClasspublic:BaseClass();virtual~BaseClass(... 查看详情

设计模式之装饰模式decorator

  代码实现publicinterfaceICar{voidmove();}抽象构建角色//具体构件角色(真实对象,被装饰角色)classCarimplementsICar{@Overridepublicvoidmove(){System.out.println("陆地上跑");}}具体构建角色//装饰角色classSuperCarimplementsICar{privateI 查看详情

设计模式之——decorator模式

Decorator模式又叫装饰者模式,这种模式是为了满足Java开发的“面向扩展开放,面向修改闭源”的开发原则设计出来的。在装饰者模式中,不修改源类的代码,却能修改源类中方法的功能。下面就以Angelababy化妆为例,详细介绍一... 查看详情

装饰器模式(代码片段)

一、模式名装饰者模式,Decorator二、解决的问题装饰者模式顾名思义,就是在原来的对象上加入一些修饰的部分,用以丰富原有对象的功能。但装饰器模式中的装饰器类和被装饰的对象保持一致,一般是继承或实现同一个父类或... 查看详情