美文网首页
结构型-装饰者模式

结构型-装饰者模式

作者: 松松木tell | 来源:发表于2022-05-11 19:16 被阅读0次

    1、一个实例

    在一家咖啡店有很多种咖啡,但都基于一种基本饮料开发出来的,每一种咖啡也可以加入很多不同的配料。
    饮料有:HouseBlend(首选咖啡),Espresso(浓缩咖啡),DarkRoast(焦炒咖啡),Decaf(脱因咖啡)
    调料有:Milk(牛奶)、摩卡(mocha)、豆浆(Soy)、奶泡(Whip)
    这时候用户下单要打印票据显示配方和价格,该如何做呢?

    //被装饰者父类
    public abstract class Beverage {
        String description = "Unknown Beverage";
    
        public String getDescription() {
            return description;
        }
    
        public abstract double cost();
    }
    //创建几个实现类
    public class HouseBlend extends Beverage {
        public HouseBlend() {
            description = "House Blend Coffee";
        }
    
        @Override
        public double cost() {
            return 0.89;
        }
    }
    public class DarkRoast extends Beverage {
    
        public Espresso() {
            description = "DarkRoast";
        }
    
        @Override
        public double cost() {
            return 1.99;
        }
    }
    
    
    • 装饰类(写法1)
    //创建装饰者
    public abstract class CondimentDecorator extends Beverage {
        public abstract String getDescription();
    }
    // 创建具体的装饰者
    public class Mocha extends CondimentDecorator {
        Beverage beverage;
    
        public Mocha(Beverage beverage) {
            this.beverage = beverage;
        }
    
        @Override
        public double cost() {
            return 0.2 + beverage.cost();
        }
    
        @Override
        public String getDescription() {
            return beverage.getDescription() + ",Mocha";
        }
    }
    
    public class Milk extends CondimentDecorator {
        Beverage beverage;
    
        public Milk(Beverage beverage) {
            this.beverage = beverage;
        }
    
        @Override
        public double cost() {
            return 0.1 + beverage.cost();
        }
    
        @Override
        public String getDescription() {
            return beverage.getDescription() + ",Milk";
        }
    }
    
    • 装饰类(写法2)
    //创建装饰者父类
    public abstract class CondimentDecorator extends Beverage {
        protected Beverage beverage;
    
        public CondimentDecorator(Beverage beverage) {
            this.beverage = beverage;
        }
    
        public abstract String getDescription();
    
    }
    // 创建具体的装饰者
    public class Mocha extends CondimentDecorator {
        public Milk(Beverage beverage) {
            super(beverage);
        }
    
        @Override
        public double cost() {
            return 0.2 + beverage.cost();
        }
    
        @Override
        public String getDescription() {
            return beverage.getDescription() + ",Mocha";
        }
    }
    
    public class Milk extends CondimentDecorator {
        public Milk(Beverage beverage) {
            super(beverage);
        }
    
        @Override
        public double cost() {
            return 0.1 + beverage.cost();
        }
    
        @Override
        public String getDescription() {
            return beverage.getDescription() + ",Milk";
        }
    }
    
    • main方法
    public class StartbuzzCoffee {
        public static void main(String[] args) {
            Beverage beverage = new DarkRoast();
            //一杯不加调料的咖啡
            System.out.println(beverage.getDescription() + ",价格:" + beverage.cost());
            //用摩卡和牛奶装饰下
            Beverage beverage2 = new DarkRoast();
            beverage2=new Mocha(beverage2);
            beverage2=new Milk(beverage2);
            System.out.println(beverage2.getDescription() + ",价格:" + beverage2.cost());
    
            Beverage beverage3=new Milk(new Mocha(new DarkRoast()));
            System.out.println(beverage3.getDescription() + ",价格:" + beverage3.cost());
        }
    }
    输出
    DarkRoast,价格:1.99
    DarkRoast,Mocha,Milk,价格:2.29
    DarkRoast,Mocha,Milk,价格:2.29
    
    1652267688(1).png

    2、什么是装饰者模式

    2.1、定义装饰者模式

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

    2.2 特征

    • 装饰者和被装饰者有相同的超类型。
    • 可以用一个或多个装饰者包装一个对象。
    • 对象可以在任何时候被装饰

    怎么看出来是使用了装饰模式呢?
    当你看到 new BufferedInputStream(new FileInputStream("test.txt"));这种写法就差不多了。

    • 装饰者和被装饰者有相同的超类型
    • 装饰者持有超类型的引用,这样装饰者就可以不断的修饰 被装饰者

    3、 java中的实例

    1652342401(1).png

    上图是java中的inputStream。我们可以看出来FilterInputStream就是我们的装饰者。

    //被装饰者父类
    public abstract class InputStream{
        public abstract int read() ;
    }
    //实现类(具体被装饰者)
    public class FileInputStream extends InputStream{
      public FileInputStream(File file){}
      public int read() throws IOException{}
    }
    public class StringBufferInputStream extends InputStream {
      public synchronized int read(){}
      public StringBufferInputStream(String s) { }
    }
    public class ByteArrayInputStream extends InputStream {
        public ByteArrayInputStream(byte buf[]) {}
        public synchronized int read(){}
    }
    
    
    • 装饰类
    //创建装饰者
    public class FilterInputStream extends InputStream {
      protected volatile InputStream in;
      protected FilterInputStream(InputStream in) {
            this.in = in;
        }
      public int read() throws IOException {
            return in.read();
        }
    }
    // 创建具体的装饰者
    public class BufferedInputStream extends FilterInputStream {
      public synchronized int read(){}
    }
    
    
    • 具体使用
     public static void main(String[] args){
      InputStream in = new BufferedInputStream(new FileInputStream("test.txt"));
    }
    

    相关文章

      网友评论

          本文标题:结构型-装饰者模式

          本文链接:https://www.haomeiwen.com/subject/nvyrurtx.html