首先看一下我们设计类的过程:
专门用于读取数据的类
MyReader
l--MyTextReader:根据不同的功能会不断延伸很多子类
l--MyMeidaReader
l--MyDataReader
l--..........
为了提高以上子类的工作效率,需要加入缓冲区技术。所以又会出现下面的类的继承体系。
(体系1)
MyReader
l--MyTextReader:根据不同的功能会不断延伸很多子类
l--MyBufferedTextReader
l--MyMeidaReader
l--MyBufferedMediaReader
l--MyDataReader
l--MyBufferedDataReader
l--....................
那么随着这个类,不断的由新的子类出现,都要对这些子类进行功能的增强。而又都要通过子类的子类
去实现功能的增强。显然这样的它的扩展性不好,而且类的继承体系比较繁琐。
然而,功能增强所用的技术都是某一种技术(比如缓冲区技术)。
于是,java继承体系的架构就想到了,可不可以将这个功能增加的子类给抽取出来呢。
装饰类,就是他们最终选择的技术。
看下面这个类设计:
Class MyBufferedReader
{
MyBufferedReader(MyTextReader r){}MyBufferedReader(MyMediaReader r){}
MyBufferedReader(MyDataReader r){}
......
}
为了让上面的类更加优化,我们找出参数的共同属性,所以选择父类对象作为参数传递。
那么上面可以有化成如下,同时需要继承上一层父类。因为他也要具备MyReader的功能。
Class MyBufferedReader extend MyReader
{
Private MyReader r
MyBufferedReader(MyReader r)
{
this.r=r
}
//利用缓冲区技术进行功能增强。
........
}
注意:如果父类是抽象类,需要实现父类中的所有抽象方法。
如此上面设计出来的继承体系就变化成下面这样:
(体系2)
MyReader
l--MyTextReader:根据不同的功能会不断延伸很多子类
l--MyBufferedTextReader
l--MyMeidaReader
l--MyBufferedMediaReader
l--MyDataReader
l--MyBufferedDataReader
l--.MyBufferedReader:装饰类
那么比较体系2和体系1:得出的结果是体系2的结构更为优化,便于扩展。
总结:
装饰类的出现,是类的继承体系中。为了增强多种子类的功能继续通过继承给每个子类添加具备了新功能的子类。
而这个新功能又是运用同一种技术,比如说java的缓冲区技术。这时候,我们可以不再使用继承的方式,通过子类
实现,而是通过装饰类的方式,将父类的对象做为参数传递给一个装饰类的构造函数来简化顶层父类的继承体系。
这样也更好的使得体系便于扩展。从软件工程的角度来讲,也降低了耦合性。
JAVA设计模式-装饰设计模式-继承体系的由来和装饰类的优化