谈谈设计对软件工程目标实现的影响
本文从个人经验出发,谈谈设计对软件工程目标实现的影响。
一、软件工程概念
首先明确下“软件工程的概念”。
我们看下百度百科中的定义软件工程(软件工程概述)_百度百科 (baidu.com)
看下原文(注意,原文也有一些问题,但总体没有大毛病):
软件工程一直以来都缺乏一个统一的定义,很多学者、组织机构都分别给出了自己的定义:
BarryBoehm:运用现代科学技术知识来设计并构造计算机程序及为开发、运行和维护这些程序所必需的相关文件资料。
IEEE:在软件工程术语汇编中的定义:软件工程是:1.将系统化的、严格约束的、可量化的方法应用于软件的开发、运行和维护,即将工程化应用于软件;2.在1中所述方法的研究
FritzBauer:在NATO会议上给出的定义:建立并使用完善的工程化原则,以较经济的手段获得能在实际机器上有效运行的可靠软件的一系列方法。
《计算机科学技术百科全书》:
软件工程是应用计算机科学、数学、逻辑学及管理科学等原理,开发软件的工程。
软件工程借鉴传统工程的原则、方法,以提高质量、降低成本和改进算法。
其中:
计算机科学、数学用于构建模型与算法
工程科学用于制定规范、设计范型(paradigm)、评估成本及确定权衡
管理科学用于计划、资源、质量、成本等管理。
比较认可的一种定义认为:软件工程是研究和应用如何以系统性的、规范化的、可定量的过程化方法去开发和维护软件,以及如何把经过时间考验而证明正确的管理技术和当前能够得到的最好的技术方法结合起来。
内涵:
一、软件工程过程是指为获得软件产品,在软件工具的支持下由软件工程师完成的一系列软件工程活动,包括以下四个方面:
1、P(Plan)——软件规格说明。规定软件的功能及其运行时的限制。
2、D(DO)——软件开发。开发出满足规格说明的软件。
3、C(Check)——软件确认。确认开发的软件能够满足用户的需求。
4、A(Action)——软件演进。软件在运行过程中不断改进以满足客户新的需求。
二、从软件开发的观点看,它就是使用适当的资源(包括人员,软硬件资源,时间等),为开发软件进行的一组开发活动,在活动结束时输入(即用户的需求)转化为输出(最终符合用户需求的软件产品)。
三个阶段:定义阶段:可行性研究初步项目计划、需求分析; 开发阶段:概要设计、详细设计、实现、测试;运行和维护阶段:运行、维护、废弃
原则:1、抽象;2、信息隐蔽;3、模块化;4、局部化;5、确定性;6,一致性;7、完备性;8、可验证性
既然有分歧,我只能选择自己认可的部分,即<<计算机科学技术百科全书>>所描述的:
软件工程是应用计算机科学、数学、逻辑学及管理科学等原理,开发软件的工程。软件工程借鉴传统工程的原则、方法,以提高质量、降低成本和改进算法。
其中:
计算机科学、数学用于构建模型与算法
工程科学用于制定规范、设计范型(paradigm)、评估成本及确定权衡
管理科学用于计划、资源、质量、成本等管理
二、关联的软件设计概念
从“软件工程”的定义看,涉及的内容非常之多。
本文限于篇幅,没有能力也没有必要阐述那么多,所以主要从技术管理者的角度,阐述如何利用计算机的设计技术参与达成软件工程的目标:
- 高质量完成项目
- 减低开发和维护成本
设计相关的内容非常之多,无法一一罗列,所以只列出以下内容:
- 软件架构
- 设计原则
- 设计模式
- 算法
其中“算法”专业性太强,需要耗费的篇幅也太多,所以本文略过。
1.软件架构
软件架构(software architecture),是一系列相关的抽象模式,用于指导大型软件系统各个方面的设计。软件架构是一个系统的草图。
软件架构描述的对象是直接构成系统的抽象组件,各个组件之间的连接则明确和相对细致地描述组件之间的通讯。
在实现阶段,这些抽象组件被细化为实际的组件,比如具体某个类或者对象。在面向对象领域中,组件之间的连接通常用接口(计算机科学)来实现
2.设计原则
在进行软件系统设计时所要遵循的一些经验准则,应用该准则的目的通常是为了避免某些经常出现的设计缺陷。
目前,较为公认的设计原则包括:开放-封闭原则、依赖倒置原则、里氏替换原则、接口隔离原则等
3.设计模式
软件设计模式(Design pattern),又称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。
使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性
三、设计如何影响工程管理目标的实现
作为软件管理者(例如CTO,高级工程师)通常情况下在项目中主要做以下工作:
- 设计
- 管理
- 必要的代码编写
实际做项目的时候,因为客户、项目特性、团队特性等因素,无法或者也没有必要做那么细致的设计,所以管理者更多工作是:
- 定义软件架构
- 定义具体的技术框架
- 定义开发规范
- 对核心/复杂的部分进行设计指导,如有必要亲自参与编写
- 其它一些管理工作
在管理的时候,主要工作:
- 设计指导
- 代码检查(review)
- 确认软件目标
一个项目正常情况下,只要规范和设计做好,通常技术上就不会有太大问题,技术管理者的主要工作也算基本完成。
在一些更大型的项目/组织中,作为技术负责人,甚至都不参与编码工作,因为设计工作和管理工作已经足够繁重。
技术主管在履行技术管理主要职责的过程中,所需要利用的知识和比较多,但本文只讨论三点:设计原则、软件架构、设计模式。
下面我们来简单讨论掌握和合理以上三点的重要性。
1.设计原则
某种程度上,是一个作业指南,类似开发规范、编码规范,但主要从技术的角度出发。它是一个指导性的文案,所有的设计必须遵守这些原则,再展开。
这些原则都较好理解,原则都是针对人的局限性而定制的。
例如单一原则,它要求一个接口或者一个函数或者是一个类应该尽量简单,因为如果复杂了那么可能会出现如下问题:
- 更多的代码量影响维护人的阅读效率和理解
- 当要修改的时候,相对容易发生错误,可能不小心修改了其它地方
- 测试工作量更大。例如一个方法涉及到工资的计算、存储、输出,那么就需要测试至少三个有关的功能。
- 管理型工作增加。代码审查时间增加
2.软件架构
它是一个系统草图,起到指导性作用。我们常常提到方向、指导、领袖、明灯,这是因为指明一个方向和目标是非常重要的。
没有正确定义工作/努力目标,那么后续的工作就会出现许多问题。所谓南辕北辙反映的就是没有正确指导的问题。
所以软件架构起到一个“指路“的作用,指出了各个软件功能/部件之间的构成方式--毕竟一般的软件都有许多的功能。
这之后,我们才会考虑概要设计、详细设计的问题。所以它非常重要。
不同的软件架构,对人员、硬件、项目周期、软件质量会又不同的影响。这个环节中,设计人员的工作就是结合实际选择合适的软件架构。
例如,一个大型工厂的设备管理系统,用于登记、维修、巡检、采购、报废、和监控等等。
一般情况下,我们会采用复合架构。总体上采用b/s(一般客户会这么要求),非监控部分采用简单的分层即可,而监控的采用管道+事件/消息+分层。
因为这个需求中,最大的问题就是硬件监控数据网络通信的高并发和即时性,而不是人类活动的高并发和即时性。
要不要试试微服务?
现在动不动就提到的微服务架构,并不适合用到这个项目。因为微服务的主要解决的问题是:针对需求和负载变化频繁的情况下,实现大量实例的快速部署,从而大大降低维护成本。
那么我们这里有没有大量实例了?不需要,最多部署几个实例或者主机即可,最多做一些负载均衡。
有没有频繁变更,频繁重新部署,大量部署的情况?作为核心问题,采集没有频繁变化的必要,也没有必要频繁重新部署。
如果一定要强上,那么会面临以下问题:
- 增加开发资源支出,因为现在cloud需要更好的硬件支持,这样有可能需要重新采购更好的设备,或者增加新的设备
- 增加设计难度和成本,从而导致设计周期更长
- 增加调试难度和成本,因为功能分布在多个小服务中,日志也多
- 增加运维成本,因为部署的程序更多,出现问题概念也更大,所以无论时间和难度都提升了
- 增加升级成本,进行升级的团队必须数量掌握cloud开发,本来任何团队都可以的
有人会说,需求没有太多变化不是正好可以不要那么多维护成本了吗?
那应该是因为没有考虑人员成本的问题。 例如如果我不做微服务框架,那么可能会以不需要掌握这个框架的程序员为主,这样是不是可以节约支出?
又有人说,我人员素质提高,效率就提升了,提升了效率就提高了单位产出。
问题是,无论怎么样还是要比采用非微服务的耗费更多的支出。还有从企业角度出发,为什么不想着节约支出,这些节约的支出用于提升团队的收益不是更好?
此外,就算这个项目多了不算很多的支出,但是从企业,组织的角度出发,难道所有的项目都需要cloud开发吗?组织总是有做不完的大项目(能够有很高回报的)吗?
事实上,从整个行业角度看,绝大部分的项目都低并发(tps<10000),关键数据少(值得重复利用,每年产生数据在几千万到一亿内)。
大部分的项目都不是那么赚钱,需要严格控制成本。
大部分公司也不是一直都有很赚钱的项目。
所以对于大部分小微公司/组织而言,控制成本就非常重要了。控制成本的最主要办法是控制人员薪资、同时提升工程效率。
这种情况下,这些公司/组织就没有必要所有的人员都是高素质(高成本)。自然对人员没有那么多的要求,就结合实际给他们安排相对简单又可以做的工作,而他们的工作又能够保证达成项目目标。
从客户的角度出发,更加复杂的软件架构,会导致他们的支出:更多的硬件资源支出、更多问题可能导致的成本、更长的工期等等。
所以选择核实的架构是很重要的,它会影响技术上的实现、项目目标达成、成本。
3.设计模式
设计模式是一个描述对象关系的套路,这些套路要么能够实现技术目标,要么是能够提升编码效率,降低维护成本,从而达成管理目标。设计模式是在具体设计和编码阶段所需要关注的。
例如单例模式主要是实现技术目标--强制一个实例,以保证对特定资源的控制。
例如转换器模式(适配器模式)可以节约开发时间,减少支出成本的管理目标。这是通过利用已有的功能的基础上达成。当然您要是不在乎,重新开发一个也可以。
四、小结
软件开发根本上和建大楼是一个道理,需要考虑项目目标(安全、适用等等)、能够赚钱。
所以,了解有关设计概念/技术,并合理地应用到项目中,是很重要的。
作为者是技术主管或者设计人员,需要把节约开支,提升效率的想法贯彻到每个项目中,这是他们的本职工作。
作为技术主管必须有管理思想,必须严谨对待自己的工作。如果他们不这么做,那么就是失职,毕竟企业是盈利机构。
作为普通的程序员,也必须理解这些概念,如此才能更好地理解团队目标,理解设计意图,贯彻设计意图。
至于非盈利项目和个人项目则是另外一回事,想怎么折腾就怎么折腾,例如用微服务实现企业的考勤需求,用b/s方式实现复杂的图形设计。