结构模式之Decorator(油漆工)

news/2024/7/4 0:53:05 标签: decorator, string, border, class, null
class="baidu_pl">
class="article_content clearfix">
class="htmledit_views">

 

class="postbody">Decorator定义:
动态给一个对象添加一些额外的职责,就象在墙上刷油漆.使用Decorator模式相比用生成子类方式达到功能的扩充显得更为灵活.

class="postbody">为什么使用Decorator?
我们通常可以使用继承来实现功能的拓展,如果这些需要拓展的功能的种类很繁多,那么势必生成很多子类,增加系统的复杂性,同时,使用继承实现功能拓展,我们必须可预见这些拓展功能,这些功能是编译时就确定了,是静态的.

class="postbody">使用Decorator的理由是:这些功能需要由用户动态决定加入的方式和时机.Decorator提供了"即插即用"的方法,在运行期间决定何时增加何种功能.

class="postbody">程序举例:
Display.java:
public abstract class Display {
 public abstract int getColumns(); // 取得横向的字数

class="postbody"> public abstract int getRows(); // 取得直向的行数

class="postbody"> public abstract String getRowText(int row); // 取得第row个字串

class="postbody"> public final void show() { // 打印所有內容
  for (int i = 0; i < getRows(); i++) {
   System.out.println(getRowText(i));
  }
 }
}
Border .java:
public abstract class Border extends Display {
    protected Display display;          // 指装饰外框里面的「內容」??
    protected Border(Display display) { // 在产生对象实例时,以参数指定「內容」
        this.display = display;
    }
}

class="postbody"> StringDisplay .java:
public class StringDisplay extends Display {
 private String class="tags" href="/tags/STRING.html" title=string>string; // 打印的字串

class="postbody"> public StringDisplay(String class="tags" href="/tags/STRING.html" title=string>string) { // 以参数指定打印的字串
  this.class="tags" href="/tags/STRING.html" title=string>string = class="tags" href="/tags/STRING.html" title=string>string;
 }

class="postbody"> public int getColumns() { // 字数
  return class="tags" href="/tags/STRING.html" title=string>string.getBytes().length;
 }

class="postbody"> public int getRows() { // 行数为1
  return 1;
 }

class="postbody"> public String getRowText(int row) { // 仅在row为0时才返回
  if (row == 0) {
   return class="tags" href="/tags/STRING.html" title=string>string;
  } else {
   return null;
  }
 }
}

SideBorder.java:
public class SideBorder extends Border {
 private char class="tags" href="/tags/BORDER.html" title=border>borderChar; // 装饰字符

class="postbody"> public SideBorder(Display display, char ch) { // 以构造子指定Display和装饰字符
  super(display);
  this.class="tags" href="/tags/BORDER.html" title=border>borderChar = ch;
 }

class="postbody"> public int getColumns() { // 字数要再加上內容两边的装饰字符
  return 1 + display.getColumns() + 1;
 }

class="postbody"> public int getRows() { // 行数同內容的行数
  return display.getRows();
 }

class="postbody"> public String getRowText(int row) { // 指定该行的內容即为在內容之指定行的两边
  // 加上装饰字符

class="postbody">  return class="tags" href="/tags/BORDER.html" title=border>borderChar + display.getRowText(row) + class="tags" href="/tags/BORDER.html" title=border>borderChar;
 }
}

UpDownBorder .java:
public class UpDownBorder extends Border {
 private char class="tags" href="/tags/BORDER.html" title=border>borderChar; // 装饰字符

class="postbody"> public UpDownBorder(Display display, char ch) { // 以构造子指定Display和装饰字符
  super(display);
  this.class="tags" href="/tags/BORDER.html" title=border>borderChar = ch;
 }

class="postbody"> public int getColumns() { // 字数同內容的字数
  return display.getColumns();
 }

class="postbody"> public int getRows() { // 行数要再加上內容上下的装饰字符的行数
  return 1 + display.getRows() + 1;
 }

class="postbody"> public String getRowText(int row) { // 指定该行的內容
  if (row == 0 || row == getRows() - 1) {
   return makeLine(class="tags" href="/tags/BORDER.html" title=border>borderChar, getColumns());
  } else {
   return display.getRowText(row - 1);
  }
 }

class="postbody"> private String makeLine(char ch, int count) { // 以字符ch,建立重复count次的连续字串
  StringBuffer buf = new StringBuffer();
  for (int i = 0; i < count; i++) {
   buf.append(ch);
  }
  return buf.toString();
 }
}

class="postbody">
Main.java:
public class Main {
    public static void main(String[] args) {
        Display b1 = new StringDisplay("Hello, world.");
        Display b2 = new UpDownBorder(b1, '-');
        Display b3 = new SideBorder(b2, '*');
        b1.show();
        b2.show();
        b3.show();
        Display b4 =
                    new FullBorder(
                        new UpDownBorder(
                            new SideBorder(
                                new UpDownBorder(
                                    new SideBorder(
                                        new StringDisplay("您好。"),
                                        '*'
                                    ),
                                    '='
                                ),
                                '|'
                            ),
                            '/'
                        )
                    );
        b4.show();
    }
}

注意:display继承类中的getRowText方法
这个方法把所有的用法都继集成到一起
class="postbody">
class="postbody">
class="postbody"> 资源引用:
class="postbody"> http://www.blogjava.net/Swing/articles/121844.html

http://www.niftyadmin.cn/n/1052246.html

相关文章

应用程序中主键ID生成与UUID

应用程序中主键ID生成与UUID1.ID生成策略在一个数据库设计里&#xff0c;假如使用了逻辑主键&#xff0c;那么你一般都需要一个ID生成器去生成逻辑主键。    在许多数据库里面&#xff0c;都提供了ID生成的机制&#xff0c;如Oracle中的sequence&#xff0c;MSSQL中的ident…

测试代码的练习——python编程从入门到实践

11-1 城市和国家&#xff1a;编写一个函数&#xff0c;它接受两个形参&#xff1a;一个城市名和一个国家名。这个函数返回一个格式为City&#xff0c;Country的字符串&#xff0c;如Santiago&#xff0c;Chile。这个函数存储在一个名为city_functions.py的模块中。 创建一个名为…

freeMarker的list集合遍历

http://freemarker.org/docs/ref_directive_list.html

结构模式之Composite(组合)

Composite定义:将对象以树形结构组织起来,以达成“部分&#xff0d;整体” 的层次结构&#xff0c;使得客户端对单个对象和组合对象的使用具有一致性. 使用Composite首先定义一个接口或抽象类&#xff0c;这是设计模式通用方式了&#xff0c;其他设计模式对接口内部定义限制不多…

interface——关于虚函数的内存分配

之前学C的时候了解到&#xff0c;其中很多控件是基于com的&#xff0c;今天初学接口&#xff0c;写了一小段测试程序 接口为IX&#xff0c;IY 组件为CA&#xff0c;&#xff08;继承于IX和IY&#xff09; 客户为main函数 流程如下&#xff1a; 接口连接组件的功能是由虚函数实现…

mtr命令详解诊断网络路由

首先安装mtr​# yum -y install mtr ​​一般在windows 来判断网络连通性用ping 和tracert,ping的话可以来判断丢包率&#xff0c;tracert可以用来跟踪路由&#xff0c;在Linux中有一个更好的网络连通性判断工具&#xff0c;它可以结合ping nslookup tracert 来判断网络的相关特…

freemarker的日期转换和自定义日期

http://www.cnblogs.com/Ivan-j2ee/p/3924284.html http://freemarker.org/docs/

链表解决约瑟夫环问题

约瑟夫环问题 (1)链表解决约瑟夫环问题 算法描述&#xff1a; 编号为1,2,...,n的n个人按顺时针方向围坐一圈&#xff0c;每人持有一个密码&#xff08;正整数&#xff09;。现在给定一个随机数m>0&#xff0c;从编号为1的人开始&#xff0c;按顺时针方向1开始顺序报数&#…