一、装饰者模式:运行时动态地将责任附加到对象上。
        1、装饰者与被装饰对象有相同的超类型
        2、一个或多个装饰者包装一个对象
        3、装饰者在所委托被装饰者的行为之前与/或之后加上自己的行为
        4、可在运行时动态地不限量地装饰
二、装饰者缺点:大量小类、增加实例化难度
三、java.io中装饰者应用
四、示例:
        1、设计UML图
        2、Coding
              1>.抽象组件类
//Component:abstract class
public abstract class Beverage{

    String description = "Unknown Beverage";

    public String getDescription(){
         return description;
    }

    public abstract double cost();

}
              2>.具体组件类
//具体组件类:Espresso
public class Espresso extends Beverage{

    public Espresso(){
         description = "Espresso";
    }

    public double cost(){
         return 1.99;
    }

}
//具体组件类:HouseBlend
public class HouseBlend extends Beverage{

    public HouseBlend(){
         description = "HouseBlend";
    }

    public double cost(){
         return .89;
    }

}
//具体组件类:DarkRoast
public class DarkRoast extends Beverage{

    public DarkRoast(){
         description = "DarkRoast";
    }

    public double cost(){
         return 2.59;
    }

}
//具体组件类:Decaf
public class Decaf extends Beverage{

    public Decaf(){
         description = "Decaf";
    }

    public double cost(){
         return 4.00;
    }

}
              3>.装饰者
//装饰者:抽象类CondimentDecorator
public abstract class CondimentDecorator extends Beverage{

    public abstract String getDescription();

}
//装饰者:Milk
public class Milk extends CondimentDecorator{

    Beverage beverage;

    public Milk(Beverage beverage){
         this.beverage = beverage;
    }

    public String getDescription(){
         return beverage.getDescription() + ",Milk";
    }

    public double cost(){
         return .55 + beverage.cost();
    }

}
//装饰者:Mocha
public class Mocha extends CondimentDecorator{

    Beverage beverage;

    public Mocha(Beverage beverage){
         this.beverage = beverage;
    }

    public String getDescription(){
         return beverage.getDescription() + ",Mocha";
    }

    public double cost(){
         return .20 + beverage.cost();
    }

}
//装饰者:Soy
public class Soy extends CondimentDecorator{

    Beverage beverage;

    public Soy(Beverage beverage){
         this.beverage = beverage;
    }

    public String getDescription(){
         return beverage.getDescription() + ",Soy";
    }

    public double cost(){
         return 1.56 + beverage.cost();
    }

}
//装饰者:Whip
public class Whip extends CondimentDecorator{

    Beverage beverage;

    public Whip(Beverage beverage){
         this.beverage = beverage;
    }

    public String getDescription(){
         return beverage.getDescription() + ",Whip";
    }

    public double cost(){
         return .99 + beverage.cost();
    }

}
              4>.测试
//Test class
public class TestD{

    public static void main(String[] args){
  
         Beverage beverage = new Espresso();
         System.out.println(beverage.getDescription() + "$" + beverage.cost()); 

         Beverage beverage2 = new DarkRoast();
         beverage2 = new Mocha(beverage2); 
         beverage2 = new Mocha(beverage2);
         beverage2 = new Whip(beverage2);
         System.out.println(beverage2.getDescription() + "$" + beverage2.cost()); 

         Beverage beverage3 = new HouseBlend();
         beverage3 = new Soy(beverage3);
         beverage3 = new Mocha(beverage3);
         beverage3 = new Whip(beverage3);
         System.out.println(beverage3.getDescription() + "$" + beverage3.cost());

    }

}
              5>.测试结果
五、java.io装饰者:大写转小写
       1、java.io.FilterInputStream装饰者
//java.io Decorator:change UpperCase to LowerCase
import java.io.FilterInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.lang.Character;

public class LowerCaseInputStream extends FilterInputStream{

    public LowerCaseInputStream(InputStream is){
         super(is);
    }

    public int read() throws IOException{
         int c = super.read();
         return (c == -1?c:Character.toLowerCase((char)c));
    }

    public int read(byte[] b, int offset, int len) throws IOException{
         int c = super.read(b,offset,len);
         for(int i = offset; i < offset + c; i++){
              b[i] = (byte)Character.toLowerCase((char)b[i]);
         }
         return c;
    }
}
       2、资源testl.txt
//testl.txt
import java.io.InputStream;
import java.lang.String;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;

public class TestL{

    public static void main(String[] arg) throws IOException{
         int c; 
         InputStream is = new LowerCaseInputStream(new BufferedInputStream(new FileInputStream("testl.txt")));
         while((c = is.read()) >= 0){
              System.out.print((char)c);
         }
         is.close();
    }

}
       3、测试类
//Test class
import java.io.InputStream;
import java.lang.String;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;

public class TestL{

    public static void main(String[] arg) throws IOException{
         int c;
         InputStream is = new LowerCaseInputStream(new BufferedInputStream(new FileInputStream("testl.txt")));
         while((c = is.read()) >= 0){
              System.out.print((char)c);
         }
         is.close();
    }

}
       4、测试结果