装饰者模式

Java I/O系统中的类的设计,大量使用了装饰者模式,所以理解装饰者模式,对于理解I/O流的设计来说,十分重要。

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

星巴克咖啡:星巴克提供了四种口味的咖啡:HouseBlend ,DarkRoast,Decaf,Espresso

                 顾客购买了一种口味的咖啡之后,可以要求往咖啡里加入调料:SteamedMilk (蒸奶) , Soy(豆浆) ,Mocha(摩卡),Whip(奶泡)。

                 星巴克根据不同的调料收取不同的费用 , 一杯咖啡的总花费是 咖啡+调料

设计原则:类应该对扩展开放,对修改关闭。允许类容易扩展,在不修改现有代码的情况下,就可搭配新的行为。

我们以饮料为主体,然后在运行时以调料来“装饰”饮料。比如,如果顾客想要DarkRoast咖啡,加入Mocha和Whip:

1.拿一个DarkRoast咖啡对象;

2.以Mocha对象装饰它;

3.以Whip对象装饰它;

4.调用cost()方法,并依赖委托(delegate)将调料的价钱加上去。

Mocha,Whip称为装饰者,DarkRoast称为被装饰者。     装饰者和被装饰者必须是一样的类型,也就是有共同的超类,因为最终装饰之后的对象,必须能够取代最初的被装饰者对象。

全局类的结构:

 Beverage超类:

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

CondimentDecorator类:

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

具体实现类:

咖啡相关的类:

public class HouseBlend extends Beverage {

    public HouseBlend()
    {
        this.description = "HouseBlend";
    }
    @Override
    public double cost() {
        return 1.99;
    }

}


public class DarkRoast extends Beverage {

    public DarkRoast()
    {
        this.description = "DarkRoast";
    }
    @Override
    public double cost() {
           return 2.99;
    }

}


public class Decaf extends Beverage {

    public Decaf()
    {
        this.description = "Decaf";
    }
    @Override
    public double cost() {
        return 3.99;
    }

}


public class Espresso extends Beverage {
    
    public Espresso()
    {
        this.description = "Espresso";
    }
    @Override
    public double cost() {
        return 4.99;
    }

}

调料相关的类:

public class Mocha extends CondimentDecorator {
    public Beverage beverage;
    
    public Mocha(){}
    
    public Mocha(Beverage beverage)
    {
        this.beverage = beverage ;
    }
    
    @Override
    public String getDescription() {
        return beverage.getDescription() + ",Mocha";
    }

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

}


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

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

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

最后 ,写个一个测试类:

public class TestClass {
   public static void main(String[] args) {
        Beverage beverage = new DarkRoast();
        beverage = new Mocha(beverage);
        beverage = new Whip(beverage);
        System.out.println(beverage.getDescription()  + "  $" + beverage.cost());
        
        //上面的写法类同与下面的写法:
        //Beverage beverage = new Whip(new Mocha(new DarkRoast()));
        //System.out.println(beverage.getDescription()  + "  $" + beverage.cost());
        
        Beverage beverage2 = new DarkRoast();
        beverage2 = new Mocha(beverage2);                
        beverage2 = new Mocha(beverage2);              //需要双份的Mocha就 两次包装 
        beverage2 = new Whip(beverage2);
        System.out.println(beverage2.getDescription()  + "  $" + beverage2.cost());
        
   }
}

运行结果:

原文地址:https://www.cnblogs.com/wangliyue/p/4200405.html