• 设计模式之装饰者模式


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

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

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

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

    装饰者是很多的调料。

    以下是代码:

    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的文件:

    运行结果:

  • 相关阅读:
    过河卒 NOIp 2002 dp
    [POI2014]KUR-Couriers BZOJ3524 主席树
    【模板】可持久化线段树 1(主席树)
    EXPEDI
    取石子游戏 BZOJ1874 博弈
    【模板】文艺平衡树(Splay) 区间翻转 BZOJ 3223
    关于表白
    POJ 1951
    Codeforces 1032F Vasya and Maximum Matching dp
    Codeforces 1016F Road Projects
  • 原文地址:https://www.cnblogs.com/yingbing/p/4397241.html
Copyright © 2020-2023  润新知