LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
12
返回列表 发新帖
楼主: 无双

设计模式再读 原创

[复制链接]
 楼主| 发表于 2004-6-26 21:50:53 | 显示全部楼层
后面再详细的介绍各设计模式的使用方法 与使用条件 另外还有优缺点

当然这些在书上都有


结构型模式

结构型模式是使用组合来实现设计的模式 通过组合类或对象来得到更大的结构(想想变形金刚tongue.gif)
类的组合是使用多重继承 把两个或以上的类组成一个类 新类有所有父类的性质
对象的组合是使用对象成员变量的办法来实现新的功能


根据上面的设计要求 优先使用组合而不是继承 所以理解结构型模式也是很重要的

结构型模式有如下八种

结构型类形式
适配器 adapter 将一个类的接口转换成客户希望的另外一个接口,使因为接口不兼容的类可以互相工作 这里是通过继承的方法实现接口的转换

结构型对象模式
适配器 adapter 将一个类的接口转换成客户希望的另外一个接口,使因为接口不兼容的类可以互相工作 这里是通过成员变量的方法来实现

上面两个都是适配器 功能都是因为现有的接口无法满足要求 需要转换
分开只是两个实现适配器的方法不同 一个通过继承 另一个通过成员变量


桥 bridge 将抽象部分与实现部分分离 使它们可以独立的变化
例子中 抽象就是window,这是一个窗口类 提供窗口的功能 如画框等高级功能
实现就是windowimp 是各平台上的具体显示办法的基类 主要包括画点 画线 画文字 windowimp只有低级的显示功能
window调用windowimp来实现自己的窗口功能
针对各平台的窗口子类从windowimp继承 并实现对应的windowimp功能
在这里抽象与实现的解释
window认为是抽象类 是因为其它类都是使用window类提供的高级显示功能 它们不与windowimp打交道
windowimp的子类提供具体的低层显示功能 被window类对这些功能进行封装提供更高级的显示功能
所以认为windowimp是实现类 window类是抽象类



组合 composite 将对象组合成树型结构以表示"部分-整体"的层次结构.composite使得用户对单个对象和组合对象的使用有一致性
对象和对象的组合在接口上一样 所以对它们的操作也一样 方便用户的使用

装饰 decorator 动态的给一个对象增加另外的职责
注意 是给一个对象而不是一个类增加功能 ,我们知道给类增加功能可以使用继承的办法,但是 给对象就没有必要那么麻烦 可以把这个对象嵌入另一个对象中 由另一个对象增加功能.我们称这个嵌入的对象为装饰
这个装饰与它装饰的组件接口一致 因此对使用这个组件的客户透明 当装饰接收到客户请求时 把请求转发给组件 并在转发前后增加一些附加的操作
由于透明所以可以递归嵌套多个装饰
看书上例子 装饰类与它被装饰的类都是从同一个父类中继承的 另外装饰类定义了指向被装饰类的指针



外观 facade 为子系统中一组接口提供一个一致的界面 facade模式定义了一个高层接口 这一接口使得这个子系统更易使用
这个 通俗的说 就是把子系统中接口进行了封装 只提供简单的接口 客户不必了解这个子系统中有什么对象 有什么接口 只需要那套简单接口就可以了
如果使用过库的话 那对这点还是可以理解的 如socket库 你只知道有那些简单接口(socket,bind ,send,recv)其它复杂部分已经封装了

享元 flyweight 运用共享技术有效支持大量细粒度对象
出现原因: 有些系统的对象数量太大而难以直接使用对象建模
每个对象都有内部状态与外部状态 使用flyweight时 对象的内部状态保存在flyweight中 外部状态在调用时传入 这样只需要一个flyweight对象 就可以保存很多的内部状态了 而不必生成大量的对象
书上使用文字编辑器举例 字符内容就是内部状态 字符显示位置就是外部状态



代理 proxy 为其它对象提供一种代理以控制外界对这个对象的访问
如果你不希望外界访问某个接口 或是对某个接口在某种条件下显示另一个结果 这时就可以使用代替
这个和我们平时使用上网代理一样的道理 也很相似
 楼主| 发表于 2004-6-26 21:54:57 | 显示全部楼层
行为模式

行为模式涉及到算法和对象职责间分配 行为模式不仅描述类或对象的模式 还描述它们之间的通信模式 这些模式刻划了运行时难以跟踪的复杂的控制流

行为类模式使用继承机制在类间分派行为 行为对象模式使用对象复合而不是继承 描述了它们怎样配合完成其中任意一个对象都无法完成的任务

下面把包括的模式说明一下

行为型类模式
解释器interpreter 给定一个语言 定义它的文法的一种表示 并定义一个解释器 这个解释器使用该表示来解释语言中的句子
最简单的使用是读配置文件了 最复杂的使用是用它来进行yacc或是lex语法文件的解释

模板方法template method 定义一个操作中的算法的骨架 而将一些步骤延迟到子类中.template method使可不改变一个算法的结构即可重定义该算法的某些特定步骤
书上例子是OpenDocument函数,它定义了这个函数的框架 也就是这个函数的主要步骤
但是CanOpeDocument和 DoCreateDocument 在子类中实现 这样可在子类中定义具体的操作方法
总结: 在父类中定义了操作的基本步骤 但是每个具体步骤的动作却在子类中实现 这就叫模板


行为型对象模式


责任链 chain of responsiblity 使多个对象都有机会处理请求,从而避免请求的发送者与接收者之间的耦合关系.将这些对象连成一条链 并沿着这条链传递请求 直到有一个对象处理它为此

如果你开发过界面编程的话 如windows GUI编程 那消息的处理方法就是职责链的形式 一个消息在消息处理对象组成的链中传送 如果哪个对象愿意处理它就处理


命令 command 将一个请求封装为对象 从而可使你对不同的请求进行参数化 对请求排除或是记录日志 及支持可撤消的操作
这可以认为是回调在面向对象中的扩展
书中例子是界面操作请求封装成对象的形式 每个对象内说明要进行的操作 如past请求对象的操作是从剪切板粘贴内容


迭代器 iterator 提供一种方法顺序访问一个聚和对象中各个元素 而又不暴露该对象的内部表示
如果使用过stl 的话 对这个就容易理解 每个容器都定义了一个迭代器用于访问这个容器内的各元素 同时使用iterator时不必知道各元素在容器内是怎样保存的 如是顺序保存还是链表方式保存的 没有暴露封装性

vector<int> a;
...赋值
for(vectir<int>::iterator iter = a.begin();iter != a.end();i++) 操作;
从上面看不出元素是怎样保存的 就是换成list一样可以成功运行




中介者 mediator 用一个中介者来封装一系列的对象交互.中介者使各对象不需要显式的相互引用,从而使耦合松散,而且可以独立的改变它们的交互
如果一个模块中有多个对象 并且它们又需要相互联系 这时就会降低它们的可复用性
这时可以引入一个中介者
中介者负责控制和协调一组对象间的交互 ,中介者充当一个中介 以使组中的对象不再相互显式引用 也就是 这些对象只知道中介者 从而减少相互引用的数目
书上例子是一个对话框 对话框窗体知道它包括的所有组件 并协调它们间的交互 看那个图很好理解 所有的对象都把消息传到中介者那里 再由中介者把这消息中转给其它对象



备忘录 memento 在不破坏封状性的情况下 捕获一个对象的内部状态 并在此对象之外保存这个状态 这样可以将此对象恢复到原先保存的状态
这个技术类似于数据库技术中的检查点 或是事务
备忘录的提出是为了提供类似事务的功能 对某些逻辑上取消比较麻烦的对象使用备忘录来直接还原
备忘录模式的参与者有两个对象 一个是备忘录(memento) 用于保存状态 另一个是原发者(originator)是被保存状态的对象


观察者 observer 定义对象间的一种一对多的关系 当一个对象的状态改变时 所有依赖于它的对象都得到通知并被自动更新
这一模式有两个关键对象 一个是目标(subject) 另一个是观察者(observer) 一个目标可以有任意多个依赖于它的观察者 一旦目标状态改变 所有的观察者都得到通知 每个观察者都向目标查询以同步状态
典型的应用是界面开发中数据改变时界面的显示了

状态 stat 允许一个对象在其内部状态改变时改变它的行为 对象看起来似乎改变了它的类
这个 简单的说就是对象的行为由它当前的状态决定 如对象内有tcpsend ,如果还没有连接那调用时是返回错误 如果已连接那调用时是返回成功


策略 strategy 定义一系列的算法 然后把它们封装起来 使它们可以相互替换.本模式使算法可独立于使用它的客户而变化
目标是为了可在运行时动态改变算法


访问者 visitor 表示一个任务于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下,定义作用于这些元素的新操作
具体来说 就是把对象的操作与数据分开 把操作放在一个独立的对象--访问者中
当访问者访问对象时,把访问者传送给当前访问对象
被访问对象接受访问者时 向访问者发送一个包含自身信息的请求
访问者对被访问对象提供的数据进行操作
发表于 2004-6-27 21:13:18 | 显示全部楼层
无双兄回来啦,呵呵。。。
我觉得《设计模式》这本书对一般人来说难了点,英文的《设计模式解析》比较容易入门,中文的《java与模式》也不错。
学习设计模式一定要掌握好面向对象的原则和思想,领会面向接口编程的奥妙。不然一定会稀里糊涂的。
发表于 2004-6-30 15:09:02 | 显示全部楼层
那对于用c编程的,还有需要嘛?
发表于 2004-6-30 21:35:49 | 显示全部楼层
不要只学C,至少还要学一门面向对象程序设计语言,C++与Java均可。否则,编程思想会受到限制。
发表于 2004-6-30 21:40:58 | 显示全部楼层
c也需要设计模式,可以参考大名顶顶的ice
楼主讲的东西太理论化了,光从理论上是看不出设计模式的重要性的
而且这些理论会使人望而却步
发表于 2004-7-1 11:12:28 | 显示全部楼层
gtk是C写的, 但是写的很面向对象. 面向对象的思维可以用在任何程序里面, 只是不同的语言,对面向对象的支持程度不同.
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表