软件开发的难点主要存在于两个方面,一种是技术难,代码量不一定多,但是解决的问题比较难,需要一些难的算法和技术方案,一种是复杂度,本身不难,但是涉及的面广,参与开发的人多,比如物流,财务系统,我们主要就是针对第二种的来说明
简单的Hello World程序,谁都能写的出来,但是如果这样的代码成千上万行,能保证程序的运行恰当和正确吗?
如何去应对这样的复杂系统的开发?
Unix就是一个很好的例子,代码量有百万行,我们就拿着Unix开源项目来说,来进行从容的应对
1.从设计角度来说,如何应对复杂度高的项目
2.研发管理和开发技巧,如何应对?
3.聚焦Code Review 如何利用重构保证质量
设计原则
1.封装和抽象
在Unix Linux中,可以说,万物皆文件,在Unix和Linux系统中,很多东西都被抽象为了文件的概念
比如Socket 驱动 硬盘 系统信息等,他们使用文件系统的路径作为统一的命名空间,使用统一的read wirte函数来进行方便
比如,查看CPU,我们在Linux中,只需要使用Vim,打开/proc/cpuinfo,就能看到对应的信息,查看运行时间,vim /proc/uptime
万物皆为文件,就是封装和抽象的特性
封装了不同类型设计的访问细节,抽象为了统一的文件访问方式,让其可以隔离底层设备区进行访问,统一的访问格式可以简化上层代码的编写,代码更容易复用
除此外,抽象和封装可以控制代码复杂性的蔓延,将复杂性封装在局部代码中,隔离实现的易变性,提供简单,统一的访问接口,基于抽象而非具体的编程
2.分层和模块化
像是Unix这样的复杂系统,没有人能够掌控所有的细节,于是将系统分为各个独立的模块,比如进程调度,进程通信,内存管理,虚拟文件管理,虚拟文件系统,网络接口,然后进行不同模块上组合,各个团队只负责一个独立的高内聚的模块开发,最后形成一个复杂的系统
而且对于计算领域的问题,可以通过增加一个中间层来进行解决,Unix亦是如此,分为了三层,应用层 系统调用层,内核层,每一层对于上一层封装内部实现,暴露接口来方便调用
3.基于接口去通信
我们在模块之间的通信,都是使用的接口,在设计模块和层的时候,我们尽可能的隐藏实现的细节
接口更加抽象,少涉及具体的实现细节
Unix的open()文件操作函数,底层的实现很复杂,涉及权限的控制,并发控制,物理存储,但是我们使用很简单,这就是基于了抽象而非具体的实现定义的
4.高内聚,松耦合
我们在修改或者阅读某一些的源码的时候,聚焦到了一个小范围的模块或者类中,不需要了解其他的模块的类,焦点不至于发散,而且修改代码的时候,也可以只修改一小点,不用牵一发动全身
我们利用一些设计模式,可以有效的实现代码的高内聚和低耦合,代码的分层和模块化合理,那么在进行重构的时候,改动不至于很大
5.为扩展而设计
如果复杂度高的项目,需要在前期的设计是哪个多花时间,提前考虑项目中的扩展点,方便添加新的功能,
做到代码可扩展,需要代码满足开闭原则,尤其是Unix这样的开源项目,有n多的人进行开发,代码满足开闭原则,基于扩展而非修改来添加新的功能,最小化的改动代码
为了满足开闭原则,做到代码的可扩展性,我们可以封装和抽象,基于接口编程
6.Kiss原则
越简单越好,任何大型项目开发的首要原则,只要可读性好,就可以方便的扩展,如果很难以读懂,那么很可能在修改的时候引入新的bug
7.最小惊奇原则
最小惊奇原则,这个原则就是等同于遵守开发规范,在进行设计和编码的时候要遵循统一的开发规则
让所有的代码都像是一个人写出来的,那么就能减少代码的阅读干扰,在实际的开发中,能够,是一种良好的编码习惯
本章重点:
我们说一下7种设计模式
封装和抽象
分层和模块化
基于接口
高内聚,低耦合
为了扩展而设计
KISS原则
最小惊奇原则
课后思考
哪一种设计模式在大型的软件开发中最有用呢?
这一篇教导的是一些实际开发中的经验,如果没有接触过实际开发的同学,可能会觉得对上面原则的取舍比较困难,这就需要在不断实战中积累
顺便一提今天的问题,在现在的开发中,最重要的必然是封装
操作系统将网络连接封装为了Socket函数,而浏览器和各种高级语言会对于Socket再进一次的封装,方便我们的开发,
并且如果没有封装,现在可能从事编程的人员需要各个从底层硬件开始了解,互联网也不会发展如此的快了