Swing


          天行健 君子以自強不息

          posts - 69, comments - 215, trackbacks - 0, articles - 16
             :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          設計模式:結構模式之Decorator(油漆工)

          Posted on 2007-06-04 15:09 zht 閱讀(358) 評論(0)  編輯  收藏 所屬分類: 設計模式

          Decorator定義:
          動態給一個對象添加一些額外的職責,就象在墻上刷油漆.使用Decorator模式相比用生成子類方式達到功能的擴充顯得更為靈活.

          為什么使用Decorator?
          我們通常可以使用繼承來實現功能的拓展,如果這些需要拓展的功能的種類很繁多,那么勢必生成很多子類,增加系統的復雜性,同時,使用繼承實現功能拓展,我們必須可預見這些拓展功能,這些功能是編譯時就確定了,是靜態的.

          使用Decorator的理由是:這些功能需要由用戶動態決定加入的方式和時機.Decorator提供了"即插即用"的方法,在運行期間決定何時增加何種功能.

          程序舉例:
          Display.java:
          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));
            }
           }
          }
          Border .java:
          public abstract class Border extends Display {
              protected Display display;          // 指裝飾外框里面的「內容」??
              protected Border(Display display) { // 在產生對象實例時,以參數指定「內容」
                  this.display = display;
              }
          }

          StringDisplay .java:
          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;
            }
           }
          }

          SideBorder.java:
          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;
           }
          }

          UpDownBorder .java:
          public class UpDownBorder extends Border {
           private char borderChar; // 裝飾字符

           public UpDownBorder(Display display, char ch) { // 以構造子指定Display和裝飾字符
            super(display);
            this.borderChar = ch;
           }

           public int getColumns() { // 字數同內容的字數
            return display.getColumns();
           }

           public int getRows() { // 行數要再加上內容上下的裝飾字符的行數
            return 1 + display.getRows() + 1;
           }

           public String getRowText(int row) { // 指定該行的內容
            if (row == 0 || row == getRows() - 1) {
             return makeLine(borderChar, getColumns());
            } else {
             return display.getRowText(row - 1);
            }
           }

           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();
           }
          }


          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方法
          這個方法把所有的用法都繼集成到一起
          主站蜘蛛池模板: 南木林县| 南溪县| 景东| 永胜县| 西丰县| 石门县| 沿河| 讷河市| 蚌埠市| 启东市| 漳浦县| 扬州市| 运城市| 尉犁县| 连山| 汕尾市| 芜湖市| 吴堡县| 施甸县| 玉环县| 鄂伦春自治旗| 堆龙德庆县| 米林县| 潜山县| 阳山县| 行唐县| 武平县| 东乡族自治县| 商河县| 巫山县| 云林县| 静安区| 上杭县| 湖北省| 色达县| 石棉县| 黔江区| 云阳县| 城固县| 叙永县| 沂水县|