美文网首页
Chapter3 装饰者模式

Chapter3 装饰者模式

作者: 小麻巧吃西瓜 | 来源:发表于2019-07-17 12:03 被阅读0次

    简单定义:

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

    UML类图:

    装饰者类图

    用例:

    Starbuzz咖啡类图
    HouseBlend,DarkRoast,Espresso,Decaf相当于ConcreteComponent,是待装饰的对象,CondimentDecorator是一个接口或抽象类,Milk,Mocha,Soy,Whip为装饰者。

    Beverage类(抽象组件):

    public abstract class Beverage {
        String description = "Unknown Beverage";
      
        public String getDescription() {
            return description;
        }
     
        public abstract double cost();
    }
    
    

    CondimentDecorator类(装饰者抽象类):

    public abstract class CondimentDecorator extends Beverage {
        Beverage beverage;
        public abstract String getDescription();
    }
    

    注:CondimentDecorator类必须继承Beverage类,因为装饰者与被装饰者必须为同一类型,继承同一超类。

    Espresso类(被装饰者,具体组件):

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

    Mocha类(装饰者,具体组件):

    public class Mocha extends CondimentDecorator {
        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 DarkRoast();
            beverage2 = new Mocha(beverage2);
            beverage2 = new Mocha(beverage2);
            beverage2 = new Whip(beverage2);
            System.out.println(beverage2.getDescription() 
                    + " $" + beverage2.cost());
        }
    }
    

    java.io包中的类——装饰者模式:

    java.io包类

    实例:

    编写一个装饰者,把输入流内的所有大写字符转成小写。

    LowerCaseInputStream类(装饰者,具体组件):

    public class LowerCaseInputStream extends FilterInputStream {
    
        public LowerCaseInputStream(InputStream in) {
            super(in);
        }
     
        public int read() throws IOException {
            int c = in.read();
            return (c == -1 ? c : Character.toLowerCase((char)c));
        }
            
        public int read(byte[] b, int offset, int len) throws IOException {
            int result = in.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 {
        public static void main(String[] args) throws IOException {
            int c;
            InputStream in = null;
            try {
                    //多层包装,正式装饰者模式,和咖啡加料很像
                in = 
                    new LowerCaseInputStream(
                        new BufferedInputStream(
                            new FileInputStream("test.txt")));
    
                while((c = in.read()) >= 0) {
                    System.out.print((char)c);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (in != null) { in.close(); }
            }
        }
    }
    

    本章要点:

    • 继承属于扩展形式之一,但不见得是达到弹性设计的最佳方式。
    • 除了继承,装饰者模式也可以让我们扩展行为。
    • 装饰者模式意味着一群装饰者类 , 这些类用来包装具体组件。
    • 你可以用无数个装饰者包装一个组件。
    • 装饰者会导致设计中出现许多小对象,如果过度使用,会让程序变得很复杂。

    相关文章

      网友评论

          本文标题:Chapter3 装饰者模式

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