A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 为梦而战 黑马帝   /  2011-12-23 23:34  /  2023 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 为梦而战 于 2011-12-24 23:32 编辑

装饰类是如何增强功能的,它与继承相比灵活性体现在哪里?望高手们说说自己的理解:handshake

评分

参与人数 1技术分 +1 收起 理由
王德云 + 1

查看全部评分

4 个回复

倒序浏览
当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有的功能,并提供加强功能。
那么自定义的该类称为装饰类。装饰类通常会通过构造方法接收被装饰的对象,并基于被装饰的对象的功能,提供更强的功能。
装饰与继承的区别
MyReader    //专门用于读取数据的类
        |--MyTextReader    //专门用于读取文本数据的类
                |--MyBufferTextReader    //通过引入缓冲,提高读取数据的效率
        |--MyMediaReader  //专门用于读取媒体数据的类
                |--MyBufferMediaReader  //通过引入缓冲,提高读取数据的效率
class MyBufferReader{
        MyBufferReader(MyTextReader text){}
        MyBufferReader(MyMediaReader media){}
}
通过继承可以使每一个子类都具备缓冲功能,但是这样的话,继承体系会变得很复杂,并不利于扩展。
class MyBufferReader extends MyReader{
        private MyReader r;
        MyBufferReader(MyReader r){}
}       
MyReader    //专门用于读取数据的类。
        |--MyTextReader
        |--MyMediaReader
        |--MyBufferReader
现在优化思想,单独描述一下缓冲内容:将需要被缓冲的对象,传递进来。也就是,谁需要被缓冲,谁就作为参数传递给缓冲区。这样继承体系就变得很简单,从而优化了体系结构。
装饰模式比继承要灵活,避免了继承体系的臃肿。而且降低了类于类之间的关系。
装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强功能。所以装饰类和被装饰类通常是都属于一个体系中(继承同一个类或接口)的。

评分

参与人数 1技术分 +1 收起 理由
杨玉揆 + 1

查看全部评分

回复 使用道具 举报
装饰模式是在不必改变原类文件和使用继承的情况下,动态的扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
装饰模式的特点;
(1) 装饰对象和真实对象有相同的接口。这样客户端对象就可以以和真实对象相同的方式和装饰对象交互。
(2) 装饰对象包含一个真实对象的索引(reference)
(3) 装饰对象接受所有的来自客户端的请求。它把这些请求转发给真实的对象。
(4) 装饰对象可以在转发这些请求以前或以后增加一些附加功能。这样就确保了在运行时,不用修改给定对象的结构就可以在外部增加附加的功能。在面向对象的设计中,通常是通过继承来实现对给定类的功能扩展。
装饰模式和继承的不同:

QQ截图20111224000619.jpg (33.73 KB, 下载次数: 29)

QQ截图20111224000619.jpg

评分

参与人数 1技术分 +1 收起 理由
杨玉揆 + 1

查看全部评分

回复 使用道具 举报
谢谢你们这么详细的讲解!辛苦了!{:soso_e183:}
回复 使用道具 举报
装饰设计模式和继承的区别?
装饰设计模式和继承的区别?

Writer
|--TextWriter.
|--MediaWriter

发现可以形成体系,就是无论操作什么数据,但都是操作数据,可以抽取。

操作数据的效率有些低,为了提高这个操作效率,
使用缓冲技术。通过面向对象三个特点中的继承,发现可以继承完成功能的增强。
那么对具体的功能对象进行子类的扩展。
形成了一下的体系。


Writer
|--TextWriter.
   |--BufferedTextWriter
|--MediaWriter
   |--BufferedMediaWriter

该体系是完全可以应用的。

但是一点不太爽,当该操作数据的体系中如果出现了新的功能对象。
Writer
|--TextWriter.
   |--BufferedTextWriter
|--MediaWriter
   |--BufferedMediaWriter
|--DataWriter---新的功能对象。
   |--BufferedDataWriter

如果后期出现了象DataWriter这样新的功能对象时,为了提高该对象的操作效率,
该对象也需要有一个子类带有缓冲技术。
导致每出现一个新功能子类,该子类都要有一个带缓冲技术的子类。
对于扩展较为麻烦。而且让这个继承体系因为不断扩展而变得非常臃肿。

需要对该体系进行优化。

以前是让每一个功能对象都具备缓冲技术。
现在可不可以单独定义一个缓冲技术对象,要缓冲谁,就把谁传进来即可。

class BufferWriter
{
BufferWriter(Writer w)
{
  
}
/*
BufferWriter(TextWriter tw)
{

}
BufferWriter(MediaWriter mw)
{
  
}
*/
}
将缓冲技术封装成对象后,那么每一个功能对象就没有必要在定义带有缓冲技术的子类对象了。
体系就变成了

Writer
|--TextWriter.
|--MediaWriter
|--DataWriter
|--BufferWriter
即具备了缓冲功能,又优化了继承体系。
这种优化方式,很爽。可以解决功能增强问题,并比继承更有灵活性。降低了继承体系的复杂性。

为了方便于以后继续使用该优化方式,就给其起了个名字:装饰设计模式。

要记住,装饰类通常和被装饰类都所属于同一个体系。或者同一个接口。

评分

参与人数 1技术分 +1 收起 理由
王德云 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马