[译]Java 设计模式之装饰器

(文章翻译自Java Design Pattern: Decorator – Decorate your girlfriend

1.装饰模式的来历

让我们假设你在寻找一个女朋友。有来自像没美国中国日本法国等等的不同国家的女孩。她们有不同的习惯和个性。在一个像eharmony.com的约会网站,如果每个类型的女孩都是一个独立的Java类,这样就会有成千上万个类。这样就会导致一个严重的叫做类爆炸的问题。还有就是这个设计不同扩展的。不管在任何时候只要有一个心的女孩类型,一个新的类就需要被创建。

让我们改变这个设计,让每一个习惯性格能够可以动态应用到一个女孩身上的装饰器。

2.类图

java-design-pattern-decorator-650x626

女孩是一个顶层的抽象类,我们有来自于不同国家的女孩。使用一个GirlDecorator 类,我们可以通过增加新的装饰器去装扮有任何特征的女孩。

3.装饰模式Java代码

Girl.java

public abstract class Girl {
	String description = "no particular";
 
	public String getDescription(){
		return description;
	}
}

American.java

public class AmericanGirl extends Girl {
	public AmericanGirl(){
		description = "+American";
	}
}

EuropeanGirl.java

public class EuropeanGirl extends Girl {
	public EuropeanGirl() {
		description = "+European";
	}
}

GirlDecorator.java

public abstract class GirlDecorator extends Girl {
	public abstract String getDescription();
}

Science.java

public class Science extends GirlDecorator {
 
	private Girl girl;
 
	public Science(Girl g) {
		girl = g;
	}
 
	@Override
	public String getDescription() {
		return girl.getDescription() + "+Like Science";
	}
 
	public void caltulateStuff() {
		System.out.println("scientific calculation!");
	}
}

我们能够不受限制对每一个装饰器增加更多的方法像Dance()

Art.java

public class Art extends GirlDecorator {
 
	private Girl girl;
 
	public Art(Girl g) {
		girl = g;
	}
 
	@Override
	public String getDescription() {
		return girl.getDescription() + "+Like Art";
	}
 
	public void draw() {
		System.out.println("draw pictures!");
	}
}

Main.java

package designpatterns.decorator;
 
public class Main {
 
	public static void main(String[] args) {
		Girl g1 = new AmericanGirl();
		System.out.println(g1.getDescription());
 
		Science g2 = new Science(g1);
		System.out.println(g2.getDescription());
 
		Art g3 = new Art(g2);
		System.out.println(g3.getDescription());
	}
}

输出:

+American
+American+Like Science
+American+Like Science+Like Art

我们可以向下面这样做:

Girl g = new Science(new Art(new AmericanGirl()));

4.在Java标准库中使用到的装饰器设计模式

一个典型使用装饰器设计模式就是JavaIO类

下面是一个简单的例子-BufferedReader 装饰InputStreamReader

BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
//System.in is an InputStream object

InputStreamReader(InputStream in) -从byte流到character流的桥。InputSteamReader读取字节而且将他们转换成使用执行字符编码格式的字符。

BufferedReader(Reader in) - 为了提供更加有效的读取范式(readLine())从一个字符流和缓存字符读取文本

原文地址:https://www.cnblogs.com/zhangminghui/p/4214785.html