`

Decorator-装饰器模式-1

阅读更多

作用:装饰器模式,动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator 模式相比生成子类更为灵活。Java I/O 中就应用了这一模式(如FilterInputStream,FilterOutputStream)。

 示例-装饰器模式:

示例1(比较直观)

//------------------------------------------接口Work 和类SquarePeg ---------------------------------------------------------------

 

package decorator_1;

public interface Work

{

    public void insert();

}

 

package decorator_1;

 

public class SquarePeg implements Work{

    public void insert(){

    System.out.println("方形桩插入");

    }

}

/*

 * 接口Work有一个具体实现:插入方形桩或圆形桩,这两个区别对Decorator

 *无所谓.我们以插入方形桩为例

 */

//------------------------------------------Decorator---------------------------------------------------------------

package decorator_1;

public class Decorator implements Work {

    private Work work;

    // 在构造器中使用组合new方式,引入Work对象;

    public Decorator(Work work) {

       this.work = work;

    }

    public void insert() {

       System.out.println("挖坑");

       work.insert();

       System.out.println("钉木板");

    }

}

/*

 * 现在有一个应用:需要在桩打入前,挖坑,在打入后,在桩上钉木

 */

//------------------------------------------测试类---------------------------------------------------------------

package decorator_1;

public class Main {

    public static void main(String[] args) {

       Work work1 = new SquarePeg();

       work1.insert();

       System.out.println("--------经过装饰后~----------");

       Work work2 = new Decorator(work1);

       work2.insert();

    }

}

示例2(比较实际)

类一览表;

名称

说明

Display

打印字符串的抽象类

StringDisplay

只有一行的打印字符串用的类-相当于核心对象

Border

表示“装饰外框”的抽象类-装饰器抽象类

SideBorder

在左右外框加上装饰外框的类-装饰器具体类1

FullBorder

在上下外框加上装饰外框的类-装饰器具体类2

Main

测试用的类

 类图查看图片附件:类图-Decorator _1

//------------------------------------------ Display---------------------------------------------------------------

package decorator_2;

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));//row==0,设计是从这里开始的~~

           }

    }  

}

//------------------------------------------ StringDisplay---------------------------------------------------------------

package decorator_2;

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(){

       return 1; 

    }

    public String getRowText(int row){

       if (row == 0) {

           return string;

       } else {

           return null;

       }

    }

   

}

//------------------------------------------ Border---------------------------------------------------------------

package decorator_2;

public abstract class Border extends Display{

    protected Display display; //指定装饰外框里面的内容

    protected Border(Display display){//在产生对象实例时,以参数内容指定内容

           this.display = display;

    }  

}

//------------------------------------------ SideBorder---------------------------------------------------------------

package decorator_2;

public class SideBorder extends Border{

    private char borderChar; //装饰字符

    public SideBorder(Display display, char ch){

           super(display);//以构造函数指定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---------------------------------------------------------------

package decorator_2;

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){//已字符ch,建立重复count次的连续字符串

              StringBuffer buf = new StringBuffer();

              for(int i =0; i < count; i++){

                     buf.append(ch);

              }

              return buf.toString();

       }

      

}

//------------------------------------------测试类---------------------------------------------------------------

package decorator_2;

public class Main{

    public static void main(String[] args){

           Display b1 = new StringDisplay("Hello ,world.");//打印“Helloworld”没有任何装饰

           b1.show();

           Display b2 = new SideBorder(b1, '#');//把装饰符”#“加在b1的两边

           b2.show();       

           Display b3 = new FullBorder(b2); //b2去不加上装饰外框

           b3.show();

//         Display b4 =

//                       new SideBorder(

//                          new FullBorder(

//                              new FullBorder(

//                                 new SideBorder(

//                                    new FullBorder(

//                                       new StringDisplay("您好。")

//                                    ),

//                                    '*'

//                                 )

//                              )

//                          ),

//                          '/'

//                       );

//         b4.show();

          

    }  

}

解析:

装饰器模式对装饰外框和内容是一视同仁的,就如在程序示例中表示装饰外框的Border类是表示内容的Display的子类,这既是一视同仁,换句话说,Border类(及其子类)具有内容表示内容类Display相同的接口。

装饰器模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案,提供比继承更多的灵活性。动态给一个对象增加功能,这些功能可以再动态的撤消,增加由一些基本功能的排列组合而产生的非常大量的功能。就如我们每个人穿衣服一样,我们个体是不变的核心对象,穿上不同样式的衣服(这就是装饰),就能完成我们想要的视觉效果(所需的对象)。

 

 

  • 大小: 41.6 KB
  • 大小: 32.4 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics