设计模式精解学习笔记(六)—— 面向对象的新视角

 通过前面的学习,从新的角度对OO概念有了进一步的认识。设计者如何看待对象、封装和抽象类这三个概念是非常重要的。传统的方法有太多的局限性。本节让我们从新的角度:概念视角、规格视角和实现视角来对OO概念做一点总结。

 

第八章:扩展我们的视野

一、对象:原来的观点和新的观点

1. 传统的对象观点:它们是伴随有方法的数据。

2. 新的对象观点:传统的观点是正确的,但它是基于实现视角的。更有用的定义是基于概念视角的对象是拥有责任的实体。这些责任让对象拥有自己的行为。也可以想象成拥有特定行为德实体

 

按照责任来考虑问题可以使问题更简单化,因为这样可以帮助我们定义对象的公共接口。如果对象有某种责任,就一定有某种途径来要求它履行自己的责任。但是,这并不对对象内容做任何暗示。关于对象责任的信息甚至可以不在这个对象内部。比如说,假设我拥有一个Shape对象,它的责任是:

l        应该知道自己的位置。

l        应该能够在屏幕上画出自己。

l        应该能将自己在屏幕上删除。

这些责任暗示出下列这些特定的方法(这里的方法名仅做参考,实际实现时可灵活)必须存在:

l        getLocation(…)

l        drawShape(…)

l        ubDrawShape(…)

但是关于“Shape对象内存在什么,并没有任何暗示。我只关心Shape对象对自己的这些行为负有责任。它的内部可能有一些属性,也可能有另一些计算方法,还可能引用其它的对象。

 

在这里可以这样理解:Shape对象的重点工作应该放在实现它的主要方法(责任)上, 对它的内部有些什么属性或方法,还是调用了其它类的什么属性或方法不去做重点关心。需要什么就将什么添加进来。这样为你的系统建模提供了灵活性。

 

二、封装:原来的观点和新观点

封装应该被想成热核形式的隐藏。换句话说,它可以隐藏数据。但它还可以隐藏实现细节、派生类或其他很多东西。

参看Adapter模式的UML图,展现了多种封装:

l        数据的封装——linesquare以及circle对象中的数据都对其他任何对象隐藏。

l        方法的封装——比如Circle类的display()方法。

l        子类的封装——Shape类的客户不会看到linesquarecircle类。

l        其他对象的封装——除了Circle对象之外的任何对象都不知道X_circle对象。

一种类型的封装这样实现:抽象类提供多态行为,于是抽象类的客户不必知道派生类真正表示的类型。

用这种方式看待封装的优点是:它给了我一种更好的切分(分解)程序的方法。封装层成为我将要设计的接口。

 

三、发现并封装变化点

GoF的书中,GoF给出以下建议:

考虑你的设计中那些是可变的。这个方法与关注引起重新设计的原因刚好相反。它不是考虑什么会迫使你的设计改变,而是考虑你想要什么变化却又不会引起重新设计。最主要的一点是封装变化的概念,这是许多设计模式的主题。

 

作为一种有效的做法,很多设计模式都使用封装来创建对象之间的分界层——让设计者可以在分界层的一侧做出修改,而不会对另一侧产生不良的影响。这促成了层次之间的松耦合。理解了这样的思考方式对Bridge模式的学习和用运是非常重要的。

 

OOP中,任何东西都是对象。即使内建数据类型也是对象,他们的行为就是算法。这一点对学习和理解OO概念是至关重要的。

 

四、共同点/变化点以及抽象类

在面向对象设计(OOD)的新视角中,我们可以这样说:

与抽象类的映射

讨论

抽象类à核心约束概念

抽象类表现将所有派生类捆绑在一起的核心概念。这个核心概念定义了派生类的共同点。

共同点à抽象类使用的

共同点定义了我需要使用抽象类

变化点à抽象类的派生类

从共同点中识别出的变化点成为抽象类的派生类。

规格à抽象类的接口

在概念层次与抽象类相对应的接口。

 

五、总结。

一致地处理概念上相同的不同具体类,这是比“特化”更好的使用继承的方式。

使用对象来包含行为的变化的概念与用数据成员来包含数据的变化的经验是想象的。他们都允许封装(并扩展)被包含的数据或行为。

总之:

l        发现并封装变化点。

l        优先使用对象组合,而不是类继承

发布了34 篇原创文章 · 获赞 0 · 访问量 5万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章