【Java学习】 —— 学习自《Thinking In Java》
接上篇。
除了用接口的方式实现,书上还介绍了第二种方式:装饰器。
其实我觉得这个更像那些“一层一层的包菜”…
到底是怎样的呢?
我们用例子来说明!
先写一个简单的类:
class MixObjectBasic {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}这个类就一个String属性,提供get/set方法访问和修改。
接下来定义一个“装饰器”:
class Decorator extends MixObjectBasic {
private MixObjectBasic basic;
public Decorator(MixObjectBasic basic) {
this.basic = basic;
}
@Override
public String getValue() {
return basic.getValue();
}
@Override
public void setValue(String value) {
basic.setValue(value);
}
}仔细看一下这个类是如何定义的,
可能一开始你会觉得,这可能更像是某种组合的方式?
再仔细看看类的定义!
好吧,这家伙,既是一个基本类的子类,又包含一个基本类的实例,
并且唯一的构造方式必须要接受一个基本类的实例!
这会产生什么效果?后面告诉你!
好,我们现在把装饰器搞定了,接下来怎样实现混型的效果呢?
我们将要进行混入的类,继承这个包装器,这里定义2个:
class ToMixObjectC extends Decorator {
public ToMixObjectC(MixObjectBasic basic) {
super(basic);
}
public String methodC() {
return "I'm method C";
}
}
class ToMixObjectD extends Decorator {
public ToMixObjectD(MixObjectBasic basic) {
super(basic);
}
public String methodD() {
return "I'm method D";
}
}
既然继承了包装器,而包装器有且仅有一个仅接受一个基本类的构造器,
那继承了包装器的类都必须对超类进行构造,也就是必须要有一个基本类,
这个基本类怎么来?不要凭空捏造!当然也从构造的时候接受一个。
来吧,我们看看main:
public static void main(String[] args) {
// 以装饰器的方式实现
System.out.println("Mix by Decorator:");
ToMixObjectD mixtureDecorator = new ToMixObjectD(new ToMixObjectD(
new MixObjectBasic()));
System.out.println(mixtureDecorator.getValue());
System.out.println(mixtureDecorator.methodD());
// 局限性就在这里:只有最外的那层包装的接口可用
// System.out.println(mixtureDecorator.methodC());
System.out.println();
}输出结果:
Mix by Decorator:
null
I'm method D
好,留意这一句:
ToMixObjectD mixtureDecorator = new ToMixObjectD(new ToMixObjectD(
new MixObjectBasic()));这里完全可以…… 一直包下去。。最后一个基本实例就好了!
只要是继承了装饰器的,就可以这样包!
按道理来说,是把所有继承装饰器的类都混合了下来。
实际情况也是这样,可这里有什么问题?
混合的实例,都在这一层一层的“装饰”里!!
但他们对外的接口,也因此被深深的埋藏了……
所以我注释里也说了局限性!
如果你要将他们接口都接到最外层,那要怎么办?
我能想到的就是,不断加代码…… 这不科学。。
那还有什么更好的方式?
大家再想一想……
本文详细解读Java装饰器模式的实现原理及使用场景,通过实例演示如何使用装饰器模式来实现对象的动态扩展,并指出其局限性及解决办法。
830

被折叠的 条评论
为什么被折叠?



