【转】从程序员到软件设计师
很久,没有读一些有关程序员类的“鸡汤”文了,今天看了一篇。
原文地址:https://www.cnblogs.com/liangxiaofeng/p/5395009.html
前言:软件产业发展到今天,分工越来越细。程序员做为一个通用的称谓已经无法确切定义各种工作的特点和分类。正因为软件开发中各种职责区分不清,无论是刚刚写代码的新手还是具有多年经验的老手,一概被扣上程序员的通用名称,这也使得很多进入这个领域的软件开发人员无法制定自己未来的技术职业发展之路。
实际上,软件公司也逐渐认识到了对程序员分类的重要性,开始将各种职位定义的更加准确。对于从事软件开发的程序员来说,更需要尽快明确自己的发展方向,并在此方向上将专业知识积累的更深厚,这能让你尽快逃脱对未来发展方向的迷茫。为此,我们专门推出程序员成长系列的特别策划,将分别深入探讨软件设计师、测试工程师、文档工程师、项目经理、产品经理几种角色的成长之路。
程序员成长系列之一
软件设计师可以预先构建软件结构,如同建筑架构师一般。比尔·盖茨被称为微软公司的首席软件设计师,首先是因为他是一个优秀的架构设计师,中国同样需要这样的人才。
-微软大中国区总经理黄存义
从程序员到软件设计师
2000年1月13日下午,世界软件业巨人、美国微软公司突然在位于华盛顿州雷德蒙德市的总部举行新闻发布会。比尔·盖茨把微软CEO宝座拱手让给长期伙伴史蒂夫-巴尔默,只保留董事局主席一职,但同时出任新职务“首席软件设计师”。比尔·盖茨说:“今后我将全力设计开发面向未来的新软件,同时研究制定微软的总体技术发展战略。” 比尔·盖茨的这一举动将软件设计师的称谓蒙上了高贵的面纱。从程序员的技术方向发展来看,软件设计师无疑是职业生涯的顶峰。
拿破仑说过“不想当元帅的士兵不是好士兵”,我想不想当软件设计师的程序员也不是好程序员。但首先要了解什么是软件设计师,如何才能成为软件设计师。明了这些,就有可能向软件设计师发展,创造更辉煌的程序人生。基于这些想法,我们采访了佳软CTO廖恒毅,用友软件副总工程师彭六三和U8产品总设计师邓适宜,这些中国软件产业技术带头人从他们的切身体会谈了对软件设计师的看法。
软件设计师的定义
软件设计师包括软件系统设计师(System Designer)和软件架构设计师(Architect)。系统设计师应对“系统结构”所使用的软件技术非常了解,自身具备良好编程技巧,才能成为优秀的系统设计师。系统设计师的职责是把结构模型对应到实现模型上,从概念到实现期间规划和组合模型的优劣是决定软件系统设计师好坏的标准。
而软件架构设计师是程序员技术方向的最终归属,也是成长链中最神圣的一环,架构设计师的贡献最大。架构设计师彻底摆脱了语言的束缚,知道软件发展趋势。他们会开发新一代产品或者制定新一代产品的方案。软件架构设计是面向未来的。全球大规模的软件公司并不多,很重要的一个原因是因为软件产品的发展都滞后于市场需求,即有需求后再研发产品,而不是预见需求,预先设计,因此往往软件设计局部是合理的,但从整体的角度看却不合理。要解决这些问题就要看软件架构设计师的能力了。
软件设计可以分三个层次。第一层属于标准层,像J2EE、.Net的框架设计;第二种属于系统层的设计,比如Delphi这样的开发工具就是工具系统级的设计;而应用最广泛的是第三层:应用软件设计。基于中国软件产业发展的现状,大部分设计都是这个层次上的基于应用的架构设计,本文所非特殊标明,提到的软件设计师泛指应用软件系统设计师,当然有些也是架构设计师的能力所在。
从软件开发历史看,软件设计经历了很多阶段。最早是结构化设计,只是把复杂的问题逐层分解,通过流程图形式将任务逐级细化;后来出现面向对象设计,从底层进行对象封装、继承、多态,这时更多的是考虑代码重用,面向的主要是类和对象。接下来出现组件设计,这主要是面向应用方面。这三种都是面向功能的设计。
从EJB、COBRA技术出现之后,人们开始基于框架进行设计,也就是架构设计。继续发展,就是基于规则的设计了,比如基于模块和工作流的设计,这时主要考虑客户化做的更详细以及产品的开放性、可扩展性、可靠性、效率方面的问题。
软件设计师的工作
随着大型软件开发越来越多,整体把握软件架构变的越来越重要。尤其当用户需求并不明确的情况下,就要开始做软件,如何防止交付的软件产品和用户的要求差的很远,这就需要软件系统设计师进行恰当的设计。
在应用软件开发中,软件设计师担当承上启下的角色,也就是把用户的需求,基于应用的问题变成计算机系统中可以解决的问题。设计可以分为功能上的设计和技术体系上的设计,但在实际工作中,这两者很难区分清晰。
彭六三谈到,NC(用友大型ERP系统)是通过总体设计组这个团队共同完成软件设计的。首先要进行产品定义,规定产品要做什么,以及相关的市场、产品周期和前景等问题,产品所应用的技术方向也会有一些描述。接下来是总体设计,总体设计要考虑技术架构以及与应用有关的问题。像跨地域的大型产品肯定要选择虑B/S架构。每个模块中功能节点也要定义,应用组件和描述的数据模型也要做出来,诸如形成哪些标准平台,软件如何分布,应用环节都属于总体设计的范畴。总体设计再向下细分就是详细设计。详细设计完成之后就是编写代码了。
对于软件设计,廖恒毅有自己的观点。他认为软件设计师如果面对很复杂的设计,即便将架构设计出来,别人如何去实现也是很困难的。既然自然语言不如程序语言表达的清晰,他喜欢先用代码的方式把整个框架架构好,并编写基本的组件和接口代码。这样其他的程序员就可以很方便的复用自己的基础组件,并利用预留的接口添写完整的代码。做为软件设计师,他能够提供一个平台性的开发环境,让其他的程序员方便的进行扩展开发。这不仅降低了开发难度,而且节省了大量的重复劳动。复用模块也可以提高系统的稳定性,因为这是经过多次测试的代码。
软件设计师的周围也有很多角色,应用专家对应用需求分析了解的更深。还有技术平台的专家,因为尽管设计师对技术平台有一定的了解,但对于细节的内容还要请教技术平台专家的,还需要程序员做出原型并进行验证,通过反馈和评估不断完善。最终用户的反馈也是软件设计师非常重视的。
软件设计师的要求
做为应用软件开发中最顶层的角色,软件设计师的能力要求更强,除了具备更强的编程技巧能力外,还需要了解系统结构、主流软件技术和软件趋势,同时要具备相当的专业知识。
多年编程经验:既包括在专业领域的经验,也包括在软件工程领域的经验。对于一个构架团队,这些素质要求可由各团队成员来分别承担,但其中至少要有一名构架设计师能够把握项目的全局。和任何行业一样,经验是最重要的。软件设计不是纸上谈兵,一个软件设计师首先要是非常好的程序员。软件设计师在编程的时候,用的工具和普通程序员没有任何差别,但使用深度是绝对不一样的。廖恒毅花了三天写了个处理表格的程序,因为考虑的很巧妙,代码不到一千行左右,但有人写只是画表格单元的代码就有二千多行,这就是经验的差距。做软件设计的时候,肯定要求是可实施和可测试的,如果没有做过程序员,就无法保证这个设计是可实施并进行测试。
抽象能力:一个程序员刚写程序的时候,无非就是为了解决某个功能而进行代码编写。随着程序编写越来越多,他对自己所做的应用方面的理解也越来越多。不同的企业有不同的需求,但把这些企业放在一起来看的话,就会发现他们的一些共性。将这些共性提炼出来,这就是抽象的过程。抽象出来的共性形成的模型可以把这些企业的需求都包含进去,这是做通用软件必须要走的一步。
哪些东西是可以抽象的呢?邓适宜举例说:企业管理软件内部有很多内部票据流程,票据传递有自己的规则,要把他们内部的关系比较灵活的组织起来,只能把流程做为管理对象,而不能把票据做为管理对象,因为票据只是一个载体。这样做,整个系统的柔性会更强,产品才能适合不同的企业,让企业可以灵活的控制,取得最好的效益。。
廖恒毅更是将抽象发挥的淋漓尽致。他整个管理流程抽象成不断矩阵运算的过程,软件本身就是做矩阵运算的乘法器和分解器。其他程序员只需要将具体的业务抽象为以XML表达的矩阵,放入到这个矩阵中,利用乘法器做运算就可以了。
面向对象的思想:面向对象是软件开发出现以来最伟大的创新之一,这是每个程序员都追求的,但是否真正掌握了面向对象的思想,这是需要探讨的。面向对象并不受开发工具和语言的限制。很多程序员在用C++写面向对象的代码时候,实际上还是在写C代码。甚至使用C#这种完全面向对象的语言写出来的还是流程化的程序。
很多时候学习面向对象用屏幕上画图的方法,新的形状可以从标准的形状中转化而来,用来学习继承的概念。但廖恒毅认为这远远不够,因为屏幕上对象相互之间是独立的,是没有作用的离散关系。要真正学习面向对象,就要去学画表格。表格是由行组成的,同时也是由列组成的,行中又有独立的单元格组成。作为一个行,要整体去操作这些格,做为列,也要去操作这些格,到底是以行为单位还是以列为单位去操作单元格。如果能把这个搞清楚,那才表明你对面向对象理解的够深刻。廖恒毅笑着说:“有的程序员在程序中把所有的东西都继承到一起,爷爷动的时候,孙子跟着跳,孙子动的时候,爷爷跟着晃。实际上,写面向对象的代码,一定不要用太多的继承。最关键的是如何传递消息和产生动作,以及考虑各个模块之间通过什么接口来联系,而不是再继承。”
面向对象可以应用的领域非常广泛。不仅在写代码的过程中要考虑到面向对象,实际上在设计和分析阶段也可以用面向对象的方法。
舍得抛弃:软件设计是一个渐进过程,是通过不断碰壁,不断调整提高的。要想取得突破,就需要舍得抛弃。廖恒毅说:“通常情况下,我写的第一版程序是要被扔掉的。对于一个功能,我上来就写,也不做设计,什么都不想,写到最后,自己都烦了,然后就把这些代码删除掉再重新写,这些脑中有了很多体会和印象,写完第二版之后,也会扔掉,继续写第三版的代码。这时程序逻辑架构和关系自然就很清晰了。只有用这种不断消灭自己以前的东西方面才能够成长的特别快,这就像相当于脱壳,不过这需要自己对自己要求很严格,否则又会回到原来的老路子上了。”很多人舍得扔掉自己的代码的,往往是不断的修改,最后进入一个恶性的循环。当然,这种抛弃也是有继承的抛弃,不同时期产品的架构之间也有连续性,不是一个架构就会完全取代前面的架构,好的东西还是可以继承的,像微软的.NET架构就是从DNA架构上发展来的。
领悟和突破:程序员技术成长一种是通过学习技巧而成长,一种是通过思想领悟而得到成长,后者更为重要。如果不能领悟开发的思想,仅仅掌握了技巧,一旦改换了平台和语言,又要从头学起,所以很多人在转型过程中失败了。而掌握了编程的思想,自动就移过去了。廖恒毅表示:“语言本身从来不对我产生任何障碍,各种语言没有任何本质的差别,就象练武一样,刀背也可以当锤子用。”
即便是很小的软件,也可以锻炼突破性的编程思维。廖恒毅以自己写拼音加加的经历讲了一个例子。“输入法体系结构和流程很简单,就是原生数据库和后生数据库加上一个简单的界面。但在处理退格的时候,你会发现这是一个很复杂的问题,如果按照常规的方法考虑各种出现的情况,程序几乎是无法写下去了。其实方法很简单,只要做一个正向编辑器,定义好一个字母产生什么样的操作,二个字母产生什么样的操作,一个字符串产生什么样的操作,并抽象成为每个操作对应后台进行什么样的操作。删掉一个字母,无非就是把字符串去掉一个,重新处理一遍就可以了。这个问题就变得很简单。总结出来一种基本的设计原则和思路,就是程序设计千万不要回溯,否则就会崩溃,这是脑袋碰墙多少次之后才明白的。所以说尽管编程序写了十几年了,到现在还不敢称完全领悟软件设计,而是一直在找这种感觉。”
非软件知识:提起软件设计师,人们很喜欢那建筑师做比较,的确这两个行业有很多相似之处。古罗马建筑师维特鲁威说“理想的建筑师应该既是文学家又是数字家,他还应通晓历史,热衷于哲学研究,精通音乐,懂得医药知识,具有法学造诣,深谙天文学及天文计算。”软件设计师同样如此。
廖恒毅说“所有让人去思考,一切美的东西都会吸引我,我欣赏每个行业中有内涵的东西。”甚至包括周易五行,他都觉得这对开发软件有很大的帮助。“周易五行的一套自我完备运行的体系结构,它也有自己的对象和作用关系。各种对象之间不是独立的,而且衍生出来的作用关系让整个系统运转的更加自然。我编程的时候也用这种思路,努力去寻找整个程序中的内部作用关系。”
邓适宜也有自己的看法,他觉得软件系统比起建筑来,更象一台机械。因为建筑一旦完成之后就很少改变它的结构,但机械不一样,它是一台可以通过改装改变不断增加功能的系统。“现在机械制造中经常是把机器分解为多个组件,分别生产,只有到最终销售的时候,才根据用户的需求把各个组件拼接组合起来产生不同的功能,这称为延迟制造。这种想法在我们的软件开发中也经常用到。我们也开发了很多灵活的可视化组件,在实施的时候才根据用户的需求进行组装,不仅满足了客户的个性化需求,而且也降低了开发成本。U8软件中的ERB模块要提供第三方软件的接口程序,为了保证稳定性和下一代产品的延续性,我们做了一些模块,可以通过注册扩展功能,很象机械中的插件。”
向软件设计师发展
当然,并不是每一个程序员都适合向软件设计师角色发展的。除了自身的努力之外,还同所处的环境有很大的关系,如果只是几个人的小公司,对软件设计的要求不明确,自然也就无法得到锻炼。邓适宜说自己早期接触的软件开发环境都是比较大型的基于UNIX的大型数据库环境,从中学到了很多东西,受益菲浅。
彭六三介绍说,在用友这样开发大型软件的公司中,程序员成长是很快的。一个普通的程序员,在代码编写多之后,首先可以成为一个主程序员。除了他的编程能力更强,在一个开发小组中起主导作用之外,他实际上也具有了一定的设计能力。接下来,就是和深入的了解具体的应用。除了面向对象的程序设计一定要具备,对具体应用的深入了解也是必不可少的,否则无法去设计产品。要想继续发展,接下来的工作就是要更多了解技术标准方面的知识了。
不过,即便你是一个普通的程序员,没有机会参与大型的软件开发项目,也可以在开发中向软件设计师的思维靠近,提升自己对软件开发的认识。一个播放软件,不同的用户对界面有不同的需求,如何满足不同的需求也是需要设计的,而播放软件对不同格式文件的支持也是需要考虑的,尤其是为未来的格式预留接口,这些问题是需要在架构中考虑。不管软件大小,都可以应用设计模式的东西。