《大象 Thinking in UML》读书笔记:Process-oriented vs. Object-oriented
前言
面向过程 还是 面向对象?这不仅仅是个软件工程术语,其问题甚至可以追溯到亚里士多德:您把这个世界视为过程还是对象? 回归到现今的软件行业,这不仅仅是个某个具体编程技术问题,更是认识论问题。
认识论 vs. 工具
UML创始人之一的Grady Booch在2004年IBM Developer Works Live大会的访谈中讲过的一段流传甚广的话。
我对面向对象编程的目标从来就不是复用。相反,对我来说,对象提供了一种处理复杂性问题的方式。这个问题可以追溯到亚里士多德:您把这个世界视为过程还是对象?在面向对象运动兴起之前,编程以过程为中心,例如结构化设计方法。然而,系统已经到达了超越其处理能力的复杂性极点。有了对象,我们能够通过提升抽象级别来构建更大的、更复杂的系统——我认为,这才是面向对象编程运动的真正胜利。
感想:
写过几年C++代码的我,一度以为所谓的OO其实就是继承、封装、多态、复用。复用这个词还是工作后才深入体会,大学期间老师传授的知识一直都是类、继承、封装、多态。无论怎样界定OO,他们说的都没错,只是不全面,只是OO的表象。OO编程的目标从来就不是复用,如果是失败的抽象,复用非但不会简化系统复杂性,还会令原本复杂的系统变得更加难以开发、维护。OO的精髓在于抽象,OO的困难也在于抽象,OO的成功在于成功的抽象,OO的失败在于失败的抽象,正所谓成也抽象,败也抽象。
软件行业,OO运动兴起之前一直以面向过程为核心。虽然我们今天都在讲OO,但是OO与PO之间无所谓对错,只是适不适合。万事万物都有其内部结构以及外部表现,软件开发亦是如此。以PO为核心,对内构造更为复杂的系统,对外解释越来越复杂的现实世界,已经日渐力不从心。PO无法胜任这样的问题,但是对于小规模系统架构,复杂度较低,PO的方法还是很管用的。而OO则是我们目前采用处理复杂性问题的方式,无论对内构造更为复杂的系统,还是对外解释复杂的现实世界,软件行业几十年的发展都证明了其正确性。为啥PO不行,OO就行,深层次上讲是我们认识论出了问题,不是工具的锅。
认识论 与 工具
何为认识论,通俗的讲是我们如何认是这个现实世界,面向过程 or 面向对象是我们采取的方法,这个问题自古有之。而我们今天在软件开发领域采用的众多技术,只是采用某种认识论时所使用的工具。这些工具或者技术,是前人软件开发过程中归纳和总结的最佳实践,掌握这些技术是重要的。掌握这些技术意味着你已继承前人经验积累,这是个捷径。但是这背后更重要的还是其隐含的各种认识论,即各种思想。工具会随着时间兴跌更替,但是思想不会。没有认识论就不会有百花齐放的工具,正所谓“皮之不存,毛将焉附”。
现实世界是怎样的?
Process-oriented
世界的一切都不是孤立的,它们相互地紧密联系在一起,缺一不可,互相影响,互相作用,并形成一个个具有严格因果律的小系统;而更多的小系统组成了更大的系统,所有小系统之间的联系也是紧密和不可分割的。
面向过程方法还认为每个小系统都有着明确的开始和明确的结束,开始和结束之间有着严谨的因果关系。只要我们将这个小系统中的每一个步骤和影响这个小系统走向的所有因素都分析出来,我们就能完全定义这个系统的行为。
将世界视为过程的这个方法本身蕴涵着一个前提假设,即这个过程是稳定的,这样我们才有分析的基础,所有的工作成果都依赖于对这个过程的步步分析。同时,这种步步分析的过程分析方法还导致另一个结果,即过程中的每一步都是预设好的,有着严谨的因果关系。只可惜我们这个世界从来都不是一成不变的,尤其到了信息化时代,一切都无时无刻不在发生着变化,系统所依赖的因果关系变得越来越脆弱。
Object-oriented
这个世界的本质是由对象组成的,平时看上去相互无关的独立对象在不同的驱动力和规则下体现出不同的运动过程,然后这些过程便展现出了我们这个生动的世界。相互独立的对象之间没有因果关系,平时是“鸡犬之声相闻,老死不相往来”的状态。只有在某个外部力量的驱动下,对象之间才会依据某种规律相互传递信息。这些交互构成了这个生动世界的一个“过程”。在没有外力的情况下,对象则保持着“静止”的状态。
每个对象都只与有限的其他对象有关系。分析对象时不再需要动辄把整个世界拉下水,从头到尾分析一遍,我们只需要关心与它有关系的那几个对象。这使得我们在分析对象的时候需要考虑的信息量大大减少,自然的,这就减化了我们所面对问题领域的复杂程度。
过程并非世界本源,过程是通过特定规则组织起来的一些对象“表现”出来的,原始的对象既独立于过程,也独立于组装规则。
Object-oriented的困难
OO的难点在于抽象,现实世界 到 对象世界间存在一道“鸿沟”,鸿沟的名字就叫做抽象
跨越这道鸿沟,我们需要:
- 一种把现实世界映射到对象世界的方法。
- 一种从对象世界描述现实世界的方法。
- 一种验证对象世界行为是否正确反映了现实世界的方法。
漫谈软件开发
简易的软件开发流程分为3个阶段:分析、设计、编码
最初的OO是从编程领域开始,标志是smalltack语言。诞生之初,其目的仅是改进开发效率,编写更容易管理、复用的代码。此时我们现今常见的继承、封装、多态的概念已出现。此时的开发流程如下图
此时只有编码是OO的,分析、设计还是采用PO的做法。这引发很严重的问题,就是设计如何指导编码,表现在:
- 编码需要的对象不能够从设计中自然的推导出来
- PO强调连续性、结构化、过程化;OO强调离散对象、事件驱动,两者间有难以调的矛盾。
Programmer在编码一侧对这种问题感觉尤为强烈,programmer不会想到是分析,还是分析到设计之间某个环节出现问题,只能认为是设计的锅。设计也只是针对分析,依据自己的认识论得出设计结果,被无脑背锅自己也委屈。此时整个软件开发过程中,设计最难受。为了解决设计难题,必须对症下药,编码那侧需要面向对象的设计,那采用OOD方法做出OOD设计不就可以了吗?现实也的确如此,为此出现了Booch86、GOOD(通用面向对象开发)、HOOD(层次化面向对象设计)、OOSE(面向对象结构设计)等OOD方法。
随着上述方法的普及运用,设计——开发间困难得到了解决。随着程序进一步复杂,分析的问题变得比设计更为突出,虽然设计——开发让我们写出漂亮的代码,但是最终实现功能却与用户需求大相径庭,导致整个项目推倒重来。不满足用户需求,再好的设计也是白扯。于是分析也采用OO的认识论,形成OOA。至此,整个软件开发流程全部采用OO的思想。虽然软件各个环节都采用OO的思想,但是各环节彼此之间由于其分工,专注领域的差异,沟通还是个问题。这就好比韩国人,日本人,中国人,大家说着不同的语言,同本国人(环节内部)交流没问题,但是要想彼此明白对方讲什么就要一种大家都认可的语言——英语。UML就充当软件开发中打通各个阶段,大家统一交流的“英语”。关于UML的作用,体会下面这个例子。
目前,随着软件工程的不断成熟,软件开发越来越朝着专业化和横向分工化发展。以前人们认为从需求 到 代码是一个紧密联系的过程,是不可分离的。一旦分开就会导致高成本和高技术风险。然而与现代工业的分工越来越细致和专业化的趋势一样,软件行业的需求、分析、设计、开发这些过程也被分离开来并专业化了。需求由专门的需求团队来做,甚至会委托给一个咨询公司;分析由专门的系统分析团队来做;设计由专门的设计团队来做……以往,开发人员是项目的中心,一个开发人员常常从需求一直做到编码:而现在,程序员只负责根据设计结果来编码,设计师只负责根据需求分析结果来设计,项目组里还有架构师、质量保证小组等许多角色,各自负担着自己的职责要求,在软件工程的约束下相互协作来完成一个项目。专业化、横线分工化的作用如下:
一家软件公司,没必要承担软件开发的全部环节,对于软件产业链上设计等关节环节自己把握,争取做精,低附加值的环节可以横向分工,最显著的例子就是软件外包。外包项目质量由少数甲方人员把控,大部分开发工作外包给乙方,乙方人员薪资要低于甲方。这样可以大大减低项目成本。
专业化、横向分工化并不是完全割裂的,两者有时候会穿插使用。以甲方Huawei、乙方China-soft举例,甲方将OceanStore 9000 CM这一个模块外包给乙方,乙方可以自己采集甲方需求,自己设计,自己编码开发。也可以甲方采集需求、设计,编码外包给乙方。还可以乙方承接分析-设计-编码整个环节,但是实际施工时再将某个环节二次外包。
从上面可以看出,软件开发各个阶段不仅是被拆分,更甚至由不同团队,不同公司来做。这里面沟通对接问题就会至关重要,UML正是为大家沟通对接建立了一套标准。只要按着这个标准,大家都能理解彼此的表打意图。
《大象 Thinking in UML》读书笔记:Process-oriented vs. Object-oriented的更多相关文章
- 『重构--改善既有代码的设计』读书笔记----Replace Array with Object
如果你有一个数组,其中的元素各自代表不同东西,比如你有一个 QList<QString> strList; 其中strList[0]代表选手姓名,strList[1]代表选手家庭住址,很显 ...
- 【C++】深度探索C++对象模型读书笔记--关于对象(Object Lessons)
前言中的内容: 1.什么是C++对象模型? 1.语言中直接支持面向对象程序设计的部分 2. 对于各种支持的底层实现机制 2. C++ class的完整virtual functions在编译时期就固定 ...
- JavaScript读书笔记(5)-Object Date
1.Object类型 (1)创建Object实例 第一种方式:new操作符后跟Object构造函数 var person=new Object(); person.name=”Nicholas”; p ...
- 前端——语言——Core JS——《The good part》读书笔记——第三章节(Object)
本章介绍对象. 在学习Java时,对象理解为公共事物的抽象,实例为具体的个例,对象为抽象的概念,例如人为抽象的概念,具体的个例为张三,李四. Java对象种类多,包含普通类,JavaBean,注解,枚 ...
- 《大象Think in UML》阅读笔记之一
Think in UML这一书以UML为载体,将面向对象的分析设计思想巧妙地融合在建模UML当中,通过一些实例将软件系统的开发过程中的一些知识有机地结合起来.全书共分为四篇:准备篇.基础篇.进阶篇和总 ...
- uml精粹——11.活动图(及整个读书笔记分享)
11.活动图activity diagram 活动图是描写叙述过程化逻辑procedural logic.业务过程business process和工作流work flow的技术. 他和流程图fl ...
- 《大象Think in UML》阅读笔记(三)
Think in UML 阅读笔记(三) 把从现实世界中记录下来的原始需求信息,再换成一种可以知道开发的表达方式.UML通过被称为之概念化的过程来建立适合计算机理解和实现的模型,这个模型被称为分析模型 ...
- 《大象Think in UML》阅读笔记之二
Think in UML阅读笔记(二) 上一次读到面向对象和面向过程的区别和各自的优势,结合实例分析了面向过程在面对大数据的时候,已经不足以满足人们的需求,所以引入了面向对象,面向对象的方法把世界看做 ...
- TJI读书笔记12-接口
TJI读书笔记12-接口 抽象类和抽象方法 接口 完全解耦和策略模式 接口间的继承关系 工厂模式 乱七八糟不知道怎么归类的知识点 接口和抽象类为我们提供了更强又有力的接口和实现分离的方法. 抽象类和抽 ...
- TJI读书笔记11-多态
TJI读书笔记11-多态 再说说向上转型 多态的原理 构造器和多态 协变返回类型 使用继承进行设计 多态是数据抽象和继承之后的第三种基本特征. 一句话说,多态分离了做什么和怎么做(再次对埃大爷佩服的五 ...
随机推荐
- leetcode No.242 有效的字母异位词 valid-anagram (Python3实现)
题目描述 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词. 示例 1: 输入: s = "anagram", t = "nagaram&q ...
- 数学黑洞:卡普雷卡尔常数的php算法实现
首先看一篇文章: 英国广播公司报道,6174乍看没什么奇特之处,但是,自从1949年以来,它一直令数学家.数字控抓狂.痴迷. 不管你挑的四位数是什么,早早晚晚你都会遇到6174:而且,遇到6174就只 ...
- Postgresql常用命令汇总
sudo -u postgres psql #进入postgresql ALTER USER postgres WITH password 'postgres'; #修改postgres用户密码 ps ...
- git clean用法
git clean用法 想批量删除branch中新加的文件(untracked files),,git reset --hard不行- 首先确认要删除的文件 git clean -fd -n ...
- LeetCode 1089. 复写零(Duplicate Zeros) 72
1089. 复写零 1089. Duplicate Zeros 题目描述 给你一个长度固定的整数数组 arr,请你将该数组中出现的每个零都复写一遍,并将其余的元素向右平移. 注意:请不要在超过该数组长 ...
- [转帖]dfs和bfs
dfs和bfs https://www.cnblogs.com/wzl19981116/p/9397203.html 1.dfs(深度优先搜索)是两个搜索中先理解并使用的,其实就是暴力把所有的路径都搜 ...
- html 打开新页面
设置 target 页面 这样会点击一次就产生一个页面 页面 填任意名称,多个点击只产生于一个页面
- Locust性能测试_先登录场景案例
前言 有很多网站不登录的话,是无法访问到里面的页面的,这就需要先登录了实现场景:先登录(只登录一次),然后访问页面->我的地盘页->产品页->项目页 官方案例 下面是一个简单的loc ...
- NET Core 3.0 AutoFac替换内置DI的新姿势
原文:NET Core 3.0 AutoFac替换内置DI的新姿势 .NET Core 3.0 和 以往版本不同,替换AutoFac服务的方式有了一定的变化,在尝试着升级项目的时候出现了一些问题. 原 ...
- docker swarm yaml
https://www.cnblogs.com/bigberg/p/8867326.html 一.简介 Docker有个编排工具docker-compose,可以将组成某个应该的多个docker容器编 ...