设计模式之装饰者模式

装饰者模式就是建立一个装饰者,然后把被装饰者传进去,出来就已经装饰上了。

比如我传一个房子进去,出来的时候房子就种上了一朵花,这是一个种花的装饰者;

我再传进另一个装饰者,出来就把墙刷了,这是一个刷墙的装饰者。

现在我们我们的被装装饰者是咖啡,很多各类的咖啡,所以需要一个超类。

装饰者是很多的调料。

以下是代码:

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

    public String getDescription() {
        return description;
    }

    public abstract double cost();
}
public abstract class CondimentDecorator extends Beverage {
    public abstract String getDescription();
}
public class Espresso extends Beverage {
    public Espresso() {
        description = "Espresso";
    }

    @Override
    public double cost() {
        return 1.99;
    }
}
public class HouseBlend extends Beverage {
    public HouseBlend() {
        description = "HouseBlend";
    }

    @Override
    public double cost() {
        return .89;
    }
}
public class Mocha extends CondimentDecorator {
    Beverage beverage;

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

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

    @Override
    public double cost() {
        return beverage.cost() + .20;
    }
}
public class Soy extends CondimentDecorator {
    Beverage beverage;

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

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

    @Override
    public double cost() {
        return beverage.cost() + .15;
    }
}
public class Whip extends CondimentDecorator {
    Beverage beverage;

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

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

    @Override
    public double cost() {
        return beverage.cost() + .10;
    }
}

以下为测试类:

public class StarBuzzCoffee {

    @Test
    public void test() {
        Beverage beverage = new Espresso();
        beverage = new Soy(beverage);
        System.out.println(beverage.getDescription() + " $ " + beverage.cost());

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

 运行结果:

需要注意的点就是:

装饰者需要继承被装饰者,因为要重写被装饰者的方法。。。

如果有必要的话,则需要在装饰者内部声明一个被装饰者,存储先前的被装饰者,存储的对象用于重写时的调用(非强制性要求)。。。

在jdk中的I/O就是使用的装饰者模式。

以下使用装饰者模式写了一个让流中的字母全部变小写的实现:

public class LowerCaseInputStream extends FilterInputStream{

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

    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 result = super.read(b, offset, len);
        for(int i = offset; i < offset+result; i++) {
            b[i] = (byte) Character.toLowerCase((char)b[i]);
        }
        return result;
    }

}

测试类如下:

public class InputTest {

    @Test
    public void testInputStream() throws IOException {
        int c;
        try{
            InputStream in = new LowerCaseInputStream(new BufferedInputStream(new FileInputStream("H:\workspace\idea\dp\src\test\resource\test.txt")));
            while((c = in.read()) >= 0) {
                System.out.print((char) c);
            }

            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

新建一个test.txt的文件:

运行结果:

原文地址:https://www.cnblogs.com/yingbing/p/4397241.html