设计模式————装饰者模式

装饰者模式

动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

 

每个组件都可以单独使用,或者被装饰者包起来使用。装饰者有一个实例变量以保存某个组件的引用。

一个咖啡例子,咖啡是被装饰者,调料是装饰者。

Beverage相当于抽象的Component类。

public abstract class Beverage {
    String description = "Unknown Beverage";

    public String getDescription() {
        return description;
    }

    public abstract double cost();
}

某一种咖啡,如HouseBlend(具体组件)

public class HouseBlend extends Beverage {
    public HouseBlend() {
        description = "House Blend Coffee";
    }

    @Override
    public double cost() {
        return 0.89;
    }
}

装饰者共同实现的接口(也可以是抽象类),所有调料装饰者都必须重新实现getDescription

public abstract class CondimentDecorator extends Beverage {
    public abstract double cost();
}

如摩卡

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

测试

public class StarbuzzCoffee {

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

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

结果

House Blend Coffee, Mocha, Mocha, Whip $1.44

 

Java I/O 中的装饰者

InputStream是抽象组件,FileInputStream等类是可以被装饰者包起来的具体组件,FilterInputStream是一个抽象装饰者,BufferedInputStream等类是具体的装饰者。

 

编写自己的Java I/O 装饰者

public class LowerCaseInputStream extends FilterInputStream {
    public LowerCaseInputStream(InputStream in) {
        super(in);
    }

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

    @Override
    public int read(@NonNull byte[] b, int off, int len) throws IOException {
        int result = super.read(b, off , len);
        for (int i = off; i < off + result; i++) {
            b[i] = (byte)Character.toLowerCase((char)b[i]);
        }
        return result;
    }
}

测试

public class StarbuzzCoffee {

    public static void main(String[] args) throws IOException{
        int c;
        try {
            InputStream in = new LowerCaseInputStream(new BufferedInputStream(new FileInputStream("D://test.txt")));

            while (( c = in.read()) >= 0) {
                System.out.print((char)c);
            }
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

D盘下test.txt中内容为I know the Decorator pattern therefor I RULE!

结果

i know the decorator pattern therefor i rule!

 

posted @ 2019-01-08 14:00  kyun  阅读(126)  评论(0编辑  收藏  举报