先来说说jdk中哪一些类用了这种方法。
Java I/O中的filter类用到了这个方法,FilterInputStream继承自InputStream类,FilterOutputStream继承自OutputStream。FilterInputStream类主要有BufferedInputStream子类和DataInputStream子类。
我们举个示例来学习装饰设计模式。首先我们来看看它是干什么的?
看到名字,装饰,第一个想法就是包装某样东西,这就是答案了。
我们设计一个类让它继承某个接口,通过这个类将基类及其子类进行包装,以另外一种形式展现出来。这里需要主要两点:
(1)在设计这个类时,我们将其设计成接口类或者抽象类,提高扩展性、降低代码耦合;
(2)既然要将基类和其子类进行包装,那么该接口或抽象类的实现类则需要基类的;
以咖啡为例,看看如何应用装饰模式。想象一下,咖啡有很多品种、也可以加许多配料。不用质疑,这里的基本对象就是Coffe,其他都是在其基础之上建立的。因此首先创建Coffee类:
public abstract class Coffee {
String description = "Unknow Coffee";
//用于描述Coffee
public String getDescription() {
return description;
}
//用于子类计算价格
public abstract double cost();
接下去为Coffee实现两个子类:特浓咖啡类和黑咖啡
public class Espresso extends Coffee{
public Espresso() {
description = "Espresso";
}
@Override
public double cost() {
return 1.99;
}
}
public class HouseBlend extends Coffee{
public HouseBlend() {
description = "HouseBlend";
}
@Override
public double cost() {
return 0.89;
}
}
可以看到这两个类分别提供了不同的价格,但这只是最原始的咖啡。
下面来增加一点配料!这时就需要用到装饰了,可以理解一下装饰的含义,其实名字真的很贴切。
public abstract class CondimentDecorator extends Coffee{
public abstract String getDescription();
}
这个装饰抽象类,只提供了一个抽象方法,与基类不要混淆,完全不一样。
下面就要为Coffee添加几个配料了,Mocha(我也喜欢摩卡)和Whip(其实我也不知道这是什么东西,烘焙?好吧,只做方式也算一种装饰)
public class Mocha extends CondimentDecorator{
Coffee coffee;
public Mocha(Coffee coffee) {
this.coffee = coffee;
}
@Override
public String getDescription() {
return coffee.getDescription() + ", Mocha";
}
@Override
public double cost() {
return coffee.cost() + 0.20;
}
}
public class Whip extends CondimentDecorator{
Coffee coffee;
public Whip(Coffee coffee) {
this.coffee = coffee;
}
@Override
public String getDescription() {
return coffee.getDescription() + ", Whip";
}
@Override
public double cost() {
return 0.50 + coffee.cost();
}
}
这两个类都添加了各自的描述和价格,完成了装饰的功能,它可以交给下一个装饰者。
测试:
public static void main(String[] args) {
Coffee coffee = new Espresso();
coffee = new Mocha(coffee);
coffee = new Whip(coffee);
System.out.println(coffee.getDescription() + " $" + coffee.cost());
Coffee coffee2 = new HouseBlend();
coffee2 = new Mocha(coffee2);
coffee2 = new Mocha(coffee2);
System.out.println(coffee2.getDescription() + " $" + coffee2.cost());
}