面向对象的理解

今天发现一本好书,设计模式精解,作者是Alan Shalloway和James R.Trott,薄薄的一本,但是讲的很清楚,也让我对面向对象和设计模式有了多一点的理解。记得去三星实习生面试的时候面试过就问过一个问题,谈谈对面向对象的理解,我当时就只说了一个多态,而且感觉没有条理,所以今天趁着看过书,总结下这个问题。

Object Oriented,OO这个概念已经知道很多年了,但是感觉距离真正的理解还差的很远,要想深刻理解可能需要一些大型的项目经验,通过实践成长。OO的思想已经运用的很广泛了,还有什么Object database,分布式系统,cad技术等很多方面。三个特征多态、继承、封装,貌似很简单的东西。

OO的最根本目的是什么?

OO可以实现代码复用,可以实现多态,可以实现信息的封装,但是都不是本质的。我觉得是容易维护,当用户的需求变化的时候,系统容易维护!所以如果需求不改变(不可能的。记得哲学上还有个什么事物总是发展变化的原理~),那么可能就不会有OO,结构化的程序设计思路清晰,设计实现速度快,而且代码运行上速度可能更快(创建销毁对象是要消耗性能的)。 百度百科上的定义“首先根据客户需求抽象出业务对象;然后对需求进行合理分层,构建相对独立的业务模块;之后设计业务逻辑,利用多态、继承、封装、抽象的编程思想,实现业务需求;最后通过整合各模块,达到高内聚、低耦合的效果,从而满足客户要求”最后那句,“达到高内聚、低耦合的效果”,其实也是OO的根本目的,耦合度描述了一个子程序(模块)与其它子程序(模块)之间的联系的强度,耦合度越低当一个子程序(模块)被替换变更的时候就越容易(例如一个算法模块),内聚度描述了“程序中的操作之间联系紧密的程度”,可以理解成子程序内部成分之间相互联系的强度,联系越紧密,理解其中的含义就越容易。

举个例子,来说明OO是如何来处理变化的需求的。假设一位讲师,参加他课程的人不知道下一节课去哪里上,讲师的责任就是保证每个人都知道哪里去上下一节课程,如果按照结构化的程序设计方法,可能步骤是这样的:

1.获得学生名单
2.对于每个学上在名单上查找他的下一节课地点

第二种方法,直接把学生课程和课程地点张贴出来,并告诉他们去自己查。 两种方法的最大的不同就是责任的转移,第一种方案中,讲师负责所有责任,第二种方案中,学生对自己的行为负责,这样做的最大的好处就是可以使得当需求变化的时候,代码的变动最小,容易维护。当有一类特殊的学生,例如是毕业生,这类学生在上下节课之前必须去先一个地方提交课程评价,如果是按照方案一,那么当每一种这样的需求出现时候都要去修改控制程序。而第二种方案,只要为毕业生编写一个附加的程序就可以了,新的类型的学生对自己的行为负责。 上面这个例子也是多态的思想。面向对象的核心是“对象”的概念。所有东西都聚焦于对象,围绕对象而非函数来组织代码,使用对象可以定义对自己负责的东西。 使用OO的设计,可以通过封装改变程序会隐含产生的一些“副作用”bugs,维护容易。如果不采用封装,那么一个数据结构或者函数的变化,可能会影响到后面很多的方法,可能会产生很多隐藏的“副作用”bugs,但是如果采用对象封装,那么唯一影响一个对象的方法就是调用其中的方法,对象的数据和实现其责任的方法都被屏蔽起来,不受其他对象变化的影响。 总结下: OO可以实现代码重用(继承和封装)和接口重用(多态),但是最根本上是使得程序容易扩展和维护:

  1. 多态解决需求变化
  2. 封装解决修改时副作用
  3. 多态的接口统一可以使得程序改动的时候编译效率增加

**以上为2012-06-26内容**

设计原则

REP CRP原则

在dubbo的服务化最佳实践中开始:

建议将服务接口、服务模型、服务异常等均放在 API 包中,因为服务模型和异常也是 API 的一部分,这样做也符合分包原则:重用发布等价原则(REP),共同重用原则(CRP)。

比如基于spring cloud开发的微服务,定义的feign-client、异常、枚举、模型等都可以打包为product-service-client为单独的模块,对于thrift服务,可以把idl文件,和需要暴露的一些common都放到一个xxx-common模块中。

参考

服务化最佳实践
架构师修炼 III - 掌握设计原则

Table of Contents