认识复杂性
1、现实系统复杂性
比如,个人计算机结构(cpu结构),植物结构(细胞),动物结构,物质结构(原子),社会机构结构(各种机构)。我们都可以通过分解(分层)来认识和了解他们,通过分层,我们可以找到他们之间的共性,以及各个组成部分是怎么分工协作的。可以清楚的看到每部分的边界是什么。爱因斯坦说:”自然界必定存在简单的解释,上帝不是反复无常或者随心所欲的”。所以复杂的系统是能够被认识的,通过分解,分析找到共性是认知复杂系统的一种通用的方法。
2、软件的复杂性
1、问题域复杂性
2、管理开发过程困难
3、实现软件的灵活性
4、 描述离散系统的行
5、其他未知因素
3、复杂系统的5个属性(重点)
1、层次结构
“复杂性常常以层次结构的形式存在,复杂系统由一些相关的子系统组成,这些子系统又有自己的子系统,如此下去,直到达到某种最低层次的基本组件 ”
分层有两种方法,1、是一种(从上向下),2、组成部分(从外向内)。
2、相对本原
“选择哪些作为系统的基础组件相对来说比较随意,这在很大程度上取决于系统观察者的判断 ”。
比如看到一个植物,普通人群看到是植物的外观,植物学家看到的可能是细胞。每个人认知事物的视角不一样。
3、分离关注
“组件内的联系通常比组件间的联系更强。这一事实将组件中的高频动作(涉及组件内部结构)和低频动作(组件间相互作用)分离开来”
与编程中的思想 “低耦合,高内聚”,“面向接口编程” 有异曲同工之妙。
4、共同模式
“层次结构通常只是由少数不同类型的子系统按照不同组合和安排方式构成” 。
复杂系统具有共同模,这些模式就可以复用。能够快速识别事物的共同点,能够加速我们对复杂事物的理解(复用已有的知识)。
5、稳定的中间形式
“复杂系统毫无例外都是从能工作的简单系统演变而来的,从头设计的复杂系统根本就不能工作,
也不能通过打补丁的方式使其工作,必须从头开始,从能工作的简单系统开始”。
如果存在稳定的中间形式,从简单系统到复杂系统的演变将更快。随着系统的演变,曾经复杂的系统就变成了基础对象,在这些对象基础之上构建更复杂的系统。我们在分析和设计系统时,也需要识别哪些部分是稳定,哪些部分是可变的,可扩展的。要尽量保证稳定的部分不被修改。如果稳定的部分被修改了,那么后果将是严重的。与开闭原则有类似的地方。
如何控制软件复杂性
1、分解
1、算法分解,结构化设计。数据全局,方法分离
2、面向对象分解,每个部分负责计算自己内部数据,然后输出自己部分的结果。
2、抽象
一个人同一时刻只能理解大约7个信息。所以我们需要对信息进行整理,选取有用的信息。忽略它非本质的细节
处理这个对象一般化,理想化的的模型。比如JMM 模型,忽略 计算中的各种缓存。
3、分层 (是一种,组成部分)
1、组成部分分层:可以了解到不同对象之间交互方式。
2、是一种分层:我们只了解其中一个对象(类型)就可以,因为其他的都是一样的。
注: 我们可以通过分解,抽象,分层的方式 来 掌握这种复杂性,但是不能消除复杂性。
程序设计
1、结构化设计:结构化编程 系统中每个模块待办总体过程的一部分。每个模块共有全局数据
2、数据驱动设计,比如关系数据库。面向SQL 编程
3、面向对象设计,每个部分负责计算自己内部数据,然后输出自己部分的结果。
面向对象分析设计实现了面向对象的分解,通过面向对象设计,我们能够创建出灵活变化的软件,通过明智
分类他们的状态空间(与结构化设计最大不同点,结构化设计共享状态空间),我们对软件的正确性的信心
提高到了一个新的高度,最终降低了开发软件系统的复杂性。 面向对象涉及原则 分层,封装,抽象
对比:每种设计都有自己适用的场景,面向对象对设计对复杂系统,大型系统是有着明细的优势的。
面向对象的设计过程比较结构化设计和数据驱动编程难度要大很多,如果系统简单可以考虑用其他设计方法。
小结
1、 软件本质上是复杂的,尤其是企业软件,工业控制软件,软件系统的复杂性常常超出了人类智能的范围。
2、软件开发团队的任务就是制造出简单的假象。
3、复杂性常常以层次结构表现出来,层次划分需要用 part of 、is a 这样的方式。
4、 复杂系统是从稳定中间态演进而来。
5、人类认知有一些限制,我们可以通过分解,抽象,分层来克服这些限制。
6、面向对象分析和设计可以提高完成复杂系统的成功率。