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

原创 2018年02月02日 09:19:30

装饰器模式(Decorator Pattern)能不断的为对象添加装饰。

Display.java

package com.test.dp.Decorator.Sample;

//抽象类,用于显示字符串
public abstract class Display {
    public abstract int getColumns();               // 获取横向字符数
    public abstract int getRows();                  // 获取纵向行数
    public abstract String getRowText(int row);     // 获取第row行的字符串
    public void show() {                            // 全部显示
        for (int i = 0; i < getRows(); i++) {
            System.out.println(getRowText(i));
        }
    }
}
StringDisplay.java

package com.test.dp.Decorator.Sample;

//子类,用于显示单行字符串
public class StringDisplay extends Display {
    private String string;                          // 要显示的字符串
    public StringDisplay(String string) {           // 通过参数传入要显示的字符串
        this.string = string;
    }
    public int getColumns() {                       // 字符数
        return string.getBytes().length;
    }
    public int getRows() {                          // 行数是1
        return 1;
    }
    public String getRowText(int row) {             // 仅当row为0时返回值
        if (row == 0) {
            return string;
        } else {
            return null;
        }
    }
}
Border.java

package com.test.dp.Decorator.Sample;

//抽象类,用于装饰边框
public abstract class Border extends Display {
    protected Display display;          // 表示被装饰物
    protected Border(Display display) { // 在生成实例时通过参数指定被装饰物
        this.display = display;
    }
}
SideBorder.java

package com.test.dp.Decorator.Sample;

//具体装饰的类,只显示右侧边框
public class SideBorder extends Border {
    private char borderChar;                        // 表示装饰边框的字符
    public SideBorder(Display display, char ch) {   // 通过构造函数指定Display和装饰边框字符 
        super(display);
        this.borderChar = ch;
    }
    public int getColumns() {                       // 字符数为字符串字符数加上两侧边框字符数 
        return 1 + display.getColumns() + 1;
    }
    public int getRows() {                          // 行数即被装饰物的行数
        return display.getRows();
    }
    public String getRowText(int row) {             // 指定的那一行的字符串为被装饰物的字符串加上两侧的边框的字符 
        return borderChar + display.getRowText(row) + borderChar;
    }
}
FullBorder.java

package com.test.dp.Decorator.Sample;

//具体装饰的类,用于显示上下左右边框
public class FullBorder extends Border {
    public FullBorder(Display display) {
        super(display);
    }
    public int getColumns() {                   // 字符数为被装饰物的字符数加上两侧边框字符数
        return 1 + display.getColumns() + 1;
    }
    public int getRows() {                      // 行数为被装饰物的行数加上上下边框的行数
        return 1 + display.getRows() + 1;
    }
    public 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.java

package com.test.dp.Decorator.Sample;

public class Main {
    public static void main(String[] args) {
        Display b1 = new StringDisplay("Hello, world.");
        Display b2 = new SideBorder(b1, '#');
        Display b3 = new FullBorder(b2);
        b1.show();
        b2.show();
        b3.show();
        Display b4 = 
                    new SideBorder(
                        new FullBorder(
                            new FullBorder(
                                new SideBorder(
                                    new FullBorder(
                                        new StringDisplay("你好,世界。")
                                    ),
                                    '*'
                                )
                            )
                        ),
                        '/'
                    );
        b4.show();
    }
}
执行结果:

Hello, world.
#Hello, world.#
+---------------+
|#Hello, world.#|
+---------------+
/+------------------------+/
/|+----------------------+|/
/||*+------------------+*||/
/||*|你好,世界。|*||/
/||*+------------------+*||/
/|+----------------------+|/
/+------------------------+/

总结:

优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

缺点:多层装饰比较复杂。

使用场景:1、扩展一个类的功能。2、动态增加功能,动态撤销。

注意事项:可代替继承。


【设计模式】之装饰器(Decorator)模式

【设计模式】之装饰器(Decorator)模式 通常给对象添加功能,要么直接修改对象添加相应的功能,要么派生对应的子类来扩展,抑或是使用对象组合的方式。显然,直接修改对应的类这种方式并不可取。在面...
  • Xiao_Spring
  • Xiao_Spring
  • 2017年03月29日 15:32
  • 617

设计模式 —— 装饰器模式(Decorator Pattern)

装饰器模式(Decorator Pattern)概念 装饰器模式 允许向一个现有的对象添加新的功能,同时又不改变其结构。装饰者可以在所委托被装饰者的行为之前或之后加上自己的行为,以达到特定的目的。...
  • wwh578867817
  • wwh578867817
  • 2016年05月23日 11:46
  • 837

设计模式总结之Decorator Pattern(装饰者模式)

装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。...
  • cooldragon
  • cooldragon
  • 2016年08月11日 00:49
  • 1631

[设计模式]-装饰器模式(Decorator)

定义: 动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式比生成子类更为灵活。 对象结构型模式...
  • qust_2011
  • qust_2011
  • 2016年11月30日 19:15
  • 488

Android设计模式之一个例子让你彻底明白装饰者模式(Decorator Pattern)

导读这篇文章中我不会使用概念性文字来说明装饰者模式,因为通常概念性的问题都很抽象,很难懂,使得读者很难明白到底为什么要使用这种设计模式,我们设计模式的诞生,肯定是前辈们在设计程序的时候遇到了某种困难,...
  • nugongahou110
  • nugongahou110
  • 2015年12月27日 19:40
  • 2973

大话设计模式之装饰器模式

装饰器模式,顾名思义就是在一个原有的类的上增加额外的功能,前提是不能修改类的代码。其实为一个类增加功能,可以用继承来实现,但是这样会使得类的数量层爆炸式增长,每增加一个功能,都会通过继承生成一个新类。...
  • u011811966
  • u011811966
  • 2016年09月27日 09:49
  • 307

装饰页面 decorators.xml

装饰                   /mobile/*         /rfid/*         *toCommodityQuery.htm*   ...
  • u014223536
  • u014223536
  • 2014年06月06日 10:17
  • 455

设计模式——装饰模式(Decorator)

要想正确理解设计模式,首先必须明确它是为了解决什么问题而提出来的。 设计模式学习笔记 ——Shulin 转载请注明出处:http://blog.csdn.net/zhshulin 1、概念 ...
  • u012909091
  • u012909091
  • 2014年08月18日 20:23
  • 18627

java设计模式--装饰器模式

转载 http://sishuok.com/forum/blogPost/list/5766.html22.1 场景问题22.1.1 复杂的奖金计算 考虑这样一个实际应用:就是如何实现灵活的...
  • lucas421634258
  • lucas421634258
  • 2015年11月16日 22:13
  • 790

[设计模式]装饰器模式

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。 意图 动态地给一个对象...
  • g777520
  • g777520
  • 2018年01月22日 21:30
  • 155
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:设计模式(十二)-装饰器模式(Decorator Pattern)——装饰边框与被饰物的一致性
举报原因:
原因补充:

(最多只允许输入30个字)