java.io包内的类太多了,简直是......“排山倒海”。你第一次(还有第二次和第三次)看到这些API发出“哇”的惊叹时,放心,你不是唯一受到惊吓的人。现在,你已经知道装饰者模式,这些I/O的相关类对你来说应该更有意义了,因为其中许多类都是装饰者。下面是一个典型的对象集合,用装饰者来将功能结合起来,以读取文件数据:
你会发现“输出”流的设计方式也是一样的。你可能还会发现Reader /Writer流(作为基于字符数据的输入输出)和输入流/输出流的类相当类似(虽然有一些小差异和不一致之处,但是相当雷同,所以你应该可以了解这些类)。
但是JavaAI/O也引出装饰者模式的一个“缺点”:利用装饰者模式,常常造成设计中有大量的小类,数量实在太多,可能会造成使用此API程序员的困扰。但是,现在你已经了解了装饰者的工作原理,以后当使用别人的大量装饰的API时,就可以很容易地辨别出他们的装饰者类是如何组织的,以方便用包装方式取得想要的行为。
动态地将责任附加到对象上,想要扩展功能,装饰着提供有别于集成的另一种选择。
一、文件目录
二、继承关系图
三、代码
Beverage.jva
package decoratormode.interfa;
public abstract class Beverage {
protected String description = "Unknown Beverage";
public abstract double cost();
public String getDescription(){
return description;
} //这里的描述不是抽象的,正是因为它本身实现了
}
CondimentDecorator.java
package decoratormode.interfa;
public abstract class CondimentDecorator extends Beverage{
public abstract String getDescription();//所有的调料装饰者都必须重新实现
}
Espresso.java
package decoratormode.impl;
import decoratormode.interfa.Beverage;
public class Espresso extends Beverage {
public Espresso(){
description = "Espresso";
}
@Override
public double cost() {
return 1.99;
}
}
HouseBlend.java
package decoratormode.impl;
import decoratormode.interfa.Beverage;
public class HouseBlend extends Beverage {
public HouseBlend(){
description = "House Blend Coffee";
}
@Override
public double cost() {
return .89;
}
}
Mocha.java
package decoratormode.impl;
import decoratormode.interfa.Beverage;
import decoratormode.interfa.CondimentDecorator;
public class Mocha extends CondimentDecorator {
Beverage beverage;
public Mocha(Beverage beverage){
this.beverage = beverage;
}
@Override
public double cost() {
return .20 + beverage.cost();
}
@Override
public String getDescription() {
return beverage.getDescription() + ", Mocha";
}
}
Mai.java
package decoratormode;
import decoratormode.impl.Espresso;
import decoratormode.impl.HouseBlend;
import decoratormode.impl.Mocha;
import decoratormode.interfa.Beverage;
public class Mai {
public static void main(String[] args) {
Beverage beverage = new Espresso();
System.out.println(beverage.getDescription() + " $" +beverage.cost());
Beverage beverage2 = new HouseBlend();
beverage2 = new Mocha(beverage2);
beverage2 = new Mocha(beverage2);
System.out.println(beverage2.getDescription() + "$ " + beverage2.cost());
}
}
四、输出
Espresso $1.99
House Blend Coffee, Mocha, Mocha$ 1.29
Process finished with exit code 0