一 面向对象范型之前
功能分解:一种处理复杂问题的自然方法。
将问题分解成多个功能步骤,解决小的问题,比解决整个问题更简单。
存在的问题:1)能者多责:将功能分解为多个子功能,通常会产生一个主程序来负责控制子程序。主程序承担的责任太多了。
2)应对变化:无法对未来可能出现的变化未雨绸缪,也不能很好地对代码进行合适地改进。
许多bug都源于代码修改。
二 需求问题
需求总在变化,需求发生变化的原因:
1)用户对自己需求的看法,会因为与开发人员的讨论和看到软件新的可能性而发生变化;
2)开发人员对用户问题域的看法,随着开发使该领域自动化的软件的过程中,会对它更加熟悉而发生变化;
3)软件开发的环境发生了变化。
代码可以设计得使需求的变化不至于产生太大影响,代码可以逐步演进,新代码可以影响较少地加入。
我可能无法知道什么将会发生变化,但是我可以猜到在哪里会发生变化。
三 功能分解应对变化
1 模块化:用模块来封装变化,有助于提供代码的可理解性,容易理解将使代码更容易维护。但是模块化并不总是有助于代码应对多有可能遇到的变化。
2 内聚性(cohesion)例程中操作之间联系的紧密程度。
耦合性(coupling)两个例程之间联系的紧密程度。
低内聚,紧耦合。
3 不良副作用:在代码的某个地方修改了一个函数或一个数据,却对代码的其他地方造成了意想不到的影响。
只关注函数,就可能引发难以发现的副作用。
维护和调试中所耗费的大多数时间不是花在修改bug上,而是花在寻找bug,弄清如何避免在修改代码时导致不良副作用上了。
四 采用面向对象应对需求变更
采用不同的视角,责任转移。
软件开发过程中的视角
视角 | 描述 |
概念 | 呈现了所研究领域的各种概念,得出概念模型时应该很少或者不考虑实现它的软件,这个视角回答”软件要负责什么“ |
规约 | 现在我们考虑的是软件,但我们关注的是软件的接口,而不是实现。这个视角要回答的问题是”怎么使用软件“ |
实现 | 这时我们考虑代码本身。这可能是最常用的视角,但在许多方面,采取规约视角经常会更好。这个视角要回答的问题是”软件怎样履行自己的责任“ |
在一个层次(概念)上交流,而在另一个层次(实现)上去执行,这样请求者就无需准确知道具体操作细节了。
五 面向对象范型
面向对象范型以对象为重心,一切都集中在对象上,编写代码时是围绕对象而非函数进行组织的。
设计对象的原则:对象应该自己负责自己,而且应该清楚地定义责任。
从视角框架来观察对象:
在概念层次上,对象是一组责任。
在规约层次上,对象是一组可以被其他对象或对象自己调用的方法。
在实现层次上,对象是代码和数据,以及他们之间的计算交互。
对象的公开接口public interface :对象的很多方法都标识为可被其他对象调用,这些方法的集合就是对象的公开接口。
抽象类(abstract class):抽象类定义了一组类可以做什么,定义了一些相关类的行为,代表了某种特殊类型的相关行为的类。
具体类(concrete class)一个概念特定的,不变的实现。
抽象类不只是不能实例化。可以充当其他类的占位符。可以使用抽象类定义其派生类必须实现的方法。抽象类还可以包含派生类都可以使用的公共方法。派生类是使用抽象类的默认行为还是使用自己的有所变化的行为,由派生类自己决定。
可访问性:
公开public:任何对象都能够看见
保护protected:只有这个类及其派生类的对象可以看见
私有 private:只有这个类的对象能够看见
封装:不只是数据隐藏,一般意味着各种隐藏。
多态:同一个调用能够获得很多不同形态的行为。能够用一种方式引用一个类的不同派生类,但获得的行为对应于所引用的派生类。
六 特殊对象方法
构造函数 constructor
析构函数 destructor 或终结方法 finalizer