阅读目录:程序员
最近对软件开发有了一个新的认识,这个认识源自连续看了两本Craig larman大师的书籍《UML与模式应用》、《精益与敏捷开发大型应用实战》和公司目前的项目状况这两件事情一块儿碰撞致使的感悟。数据库
先说下前者,为何会想到看Craig larman大师的书籍。其实我收藏的书籍已经上千本,在各个电商平台上都有账号,目的只有一个就是收藏好的书籍。家里也堆了不少,没事浏览新书是我如今最大的乐趣。我相信有这种感受和爱好的不止我一我的,家里堆上几十本书的在IT行业算是很正常的。编程
书多了有时候不知道要看些什么也很正常,个人原则就是随时调整,看目前所面临的困惑。根据我以往的经验总结,在实际问题面前寻找答案最容易让你有新的感悟和提高。我相信书中自有黄金屋、书中自有颜如玉,要在对的时间看对的书,说白了就是在有困惑的时候就去寻找给你答案的这方面书籍。为何要看Craig larman大师的书,是由于最近的工做内容有不少本身搞不懂的地方,但愿能经过大师的指点有所感悟,果真受益不浅。设计模式
再说下后者,最近一直在和这几个事情打交道:遗留代码、技术债务、项目管理、项目质量、开发进度、快速开发、重构、单元测试、敏捷开发、Scrum、XP,你可能会有点疑惑,有些东西是重复的,好比项目管理中包含了项目质量、开发进度,再好比敏捷开发与Scrum和XP,彷佛我在把一个大的概念拆解成多个小重复的概念。我之因此这么作,是由于我想强调这些概念的区别和真正的相互做用,从软件工匠的艺术角度出发来真正的看待这些概念。好比说,项目质量与代码有关系吗,开发进度与遗留代码有关系吗,项目管理与技术债务有关系吗等等,这些问题的本质是彻底不一样的,做为技术人员尤为是应用开发的技术人员必定要强调概念,必定要明白不一样的概念的本质含义,若是你不强调概念我想你的代码是写很差的,对业务的理解也不会深入。架构
最近我将本身的技术生涯的目标定为“软件工匠”,其实说实话我不在意title,我只在意本身的工做内容是什么。软件工匠是没有边界的,只要和软件开发有关系的内容都是属于工匠须要去专研的领域。若是工匠离开工具就丧失了工匠的真正价值所在,因此说千万别放弃写代码。无论你是一名架构师仍是一名开发经理,代码永远是产品的最终设计,一旦你离他而去就离产品的质量愈来愈远,后面我也会讲下为何代码如此重要。并发
这节的标题是不受欢迎的,你们知道为何吗。技术人员是能明白的,有过长达5-10年的开发出生的管理者也是能明白的,惟一不明白的就是没有太多开发经验的管理者,或者那些不喜欢开发的管理者,那些逃避开发的管理者,由于他们离真正的产品实现太遥远,他们离软件开发领域真正的问题太遥远,管理一旦忽视代码质量问题就会慢慢找上你,你的项目日后的质量越没法控制,度量、开发进度都会遇到瓶颈。app
说个当下的现象,我从事一线开发也有好几年了,陆陆续续看到不少人转做管理,可是你会发现作管理的人通常都是技术水平通常的人,或者对技术没有太多追求的人,更夸张的是在有些小公司的管理者可能就没写过代码。框架
为何会出现这种现象,其实主要缘由有两个,首要的就是我的的职业规划,在就是公司的价值导向。先说价值导向,每每写代码的人的价值没有项目管理的价值大,这在一些中小公司仍是很广泛的,真正的科技型公司这类问题几乎没有。而职业规划是彻底能够接受的,毕竟每一个人的兴趣和追求不一样,这无可厚非,应该尊重每一个人的选择。可是这里的问题是,一旦没有太多技术底蕴的技术人员坐上项目管理者的职位后会对技术的理解360度大转弯。这实际上是不对的,项目的成败不可忽视技术。编程语言
不继续讨论这个话题了,这不是本篇文章的重点,人各有志,选择是正常的,可是要明白的是选择的本质不是价值导向,而是兴趣导向,这才不会让你忽视另一个角度,由于一个软件产品的最终成功是要靠项目管理和软件工程相共同的努力,缺一不可。工具
这里想聊聊项目管理的三个重要的方面,质量、度量、进度。首先我不是一个专业的项目管理者,可是我是一名专业的软件工程师,我不知道项目管理的具体内容有哪些,可是我知道项目管理的最终目标是和软件工程的目标是一致的,都是为了项目高质量的完成。
项目的成败光靠项目管理是解决不了的,若是能够就不会出现《软件工程》、《设计本来》了。保证软件项目的真正成功是须要软件工程的支撑才行,而管理更加是对开发的组织、协调、沟通上的,这是两个层面两个角度互相做用的。项目管理中不会有设计、抽象、可维护性等这些内容。
这里尤为想讨论的就是软件项目的质量,如今看来衡量软件项目的质量忽视了代码的质量,客户验收、功能完成、稳定上线,没耽误进度,这就是完成了一个项目,咱们忽视了一个就是代码的质量,为何要关心代码的质量。
度量,度量是对开发周期内全部发生的事情进行数据可视化,BUG数、发布回退数、代码行数(比较特殊)、需求变动数等等,还有些我不是太清楚的度量数据,总之应该会有不少。度量的目的是为了什么,是为了可以在这些数据出来后改善项目的各方面质量,控制各个不稳定的方面。
开发进度,“质量”一段中我最后抛出了一个问题“为何要关心代码的质量”,由于他直接决定了你的项目进度,当你的代码质量愈来愈差的时候你就失去了对项目进度的控制。你再多的度量指标都是无心义的,就算你能够统计出BUG数上升了,可是你也控制不了BUG数降低,由于你已经偏离正常航线太远,就算你能够控制需求变动的速度和次数,可是你没法控制适应变动的代码的速度和次数。变动是没法避免的,你的代码没法面对这些复杂的变化,由于你的代码不是设计出来的而是堆出来的。最后你的项目质量也没法很好的保证。
(图1:项目管理与软件工程的结合才是完整的软件开发)
最近在看Michael C. Feathers 大师的《修改代码的艺术》一书,感触颇多。里面讲到了咱们面对遗留代码的时候,为了增长一个新的功能要付出多少时间和精力,出现明显的BUG机率有多高,出现隐藏的BUG机率有多高。遗留代码直接决定了上述三个项目管理的方面。Michael C. Feathers 大师强调了不少关于我上面讲到的项目管理和代码质量之间的关系,这本书很值得看。
其实真正推进软件开发不断发展的是软件工程、开发方法论,项目管理只是辅助于软件工程在时间和空间上有效实施。
这里还要区别下就是项目管理和团队管理的区别,这两个东西是不同的。项目管理基本上不须要软件工程的支持,可是团队管理在某些方面是须要软件工程的支持才能作的更好。
在《精益与敏捷开发大型应用实践》一书中是这样描述软件设计和架构的:
1:“软件架构借鉴了建筑的架构,但结果证明这是个不太恰当的类比,并且给软件开发带来了有趣的反作用。建筑是硬的,由于在这个领域,设计只在施工前进行一次,而后该建筑或者设计就几乎是永久不变的了。注意建筑师和施工工人是不一样的。可是软件不是一座建筑,软件是软的,并且编程也不是施工的过程,“软件架构”只不过是一大堆比喻列表中能够选择的一个不太完美类比而已”。
2:“......惟一确实看起来知足工程设计条件的软件文档是源代码“。
3:"我意识到图表和文档并非真正的设计,而源代码才是真正的设计。再次重申“......惟一确实看起来知足工程设计条件的软件文档是源代码“。
这几句话足以证实软件开发是一个很是复杂的过程,是思惟密集型脑力活动,并且体如今每个编码过程当中。在不少项目管理中都认为软件开发是一个很是简单的活动,主要架构设计好编码是比较简单的,难道真的是这样吗,咱们再看看书中怎么说的:
1:”源代码是真正的蓝图“。
2:”真正的架构在哪里,不管好坏、有意或偶然的?是在架构团队维护的文档中?仍是在上万个文件中?显然是后者,源代码是真正的设计,并且它的总和反映了真实的大型设计或架构。架构就是架构,不是某人的意愿“。
如今不少开发者还有一个明显的技术理解错误就是”写代码“是比较简单的活动。复杂的是软件架构,只要架构设计好后写代码应该是程序员的事儿,这里明显有一个错误的价值观,认为写代码的人都是廉价的,不具备任何的设计和创造新。这实际上是一个很不专业的见解。真觉得一个简单的PPT、WORD文档中的架构图就表示架构了。其实这个想法是很幼稚和肤浅的。用Craig larman大师的话讲,在整个软件生命周期的活动中,复杂的是编写代码,而代码才是架构,因此说架构的就是代码。你本来理解的架构才是真正难的地方其实也就是代码才是真正难的地方,不可浮于表面,这样才能更加的接地气才能真正的有价值。
架构师应该深刻到一线参与一些开发,这时会发现不少问题,而后将问题带到架构的位置,用架构的视角设计方案,在亲自把这个方案带到一线落实下去,这才是架构落地一个技术方案的正确方法。
软件开发是一项设计活动而不是建筑活动,软件是会不断变化的,而建筑一旦敲定是不会改变的。
这节我想聊聊快速开发。在圈子里面对快速开发的理解大部分都是和快速开发框架对应起来,以为应该有一个框架来支持快速开发。只要有了一个框架就能够进行快速开发。这样的见解或想法实际上是错误的,对快速开发的理解太狭隘。
《设计本来》做者,计算机科学巨匠Frederick P. Brooks说过,对于软件开发来讲没有银弹存在,没有所谓的可以用简单发方法来开发复杂的系统。越复杂的系统开发起来不会简单的,开发一个知足100我的使用的系统和开发一个知足1000我的使用的系统在复杂性上已经彻底不一样了。量变引发质变,当业务量、访问量、数据量等等这些软件指标超出必定的范围以后就和最初的设计彻底不一样,设计思路也彻底不一样。
回到当下。我如今常常面临这样的一个问题,我如今所从事的业务是比较复杂的,对系统的设计要求很高。若是用量来比喻的化,其实我如今所面对的业务量是比较大的,业务量中的业务复杂性的量其实相比于访问量、数据量等方面的量在设计方法要难的不少。一般作设计的架构师都只会考虑并发量、访问量而忽视业务量,好比业务的多变性、业务的扩展性,业务自己的复杂性,这尤为考研设计能力,考验抽象能力。这跟你用什么编程语言用什么数据库是没太大关系的。你脑壳里运用的是OO、实体关系,这些与具体技术框架不要紧的设计思惟。
业务量对于编写代码要求要高不少,同比于其余几个量来讲很难落地。访问量、并发量能够经过基础架构的调整优化升级来解决,而业务量的问题域是业务逻辑,是领域模型,当前所面对的业务域,任何一个细小的业务都须要在代码中体现。
最近陆续在作一些系统重构的工做,就在前两天我重构了一段代码,不是基础性的代码,是业务逻辑代码。大概状况是这样的。
在系统中有一个重要的领域概念“重量”,这个重量的概念存在不少个业务量的质变可能性,就是说它自己不是简单不变的,随时存在着变化,当咱们品类扩充的时候就立马会变化。
重量的定义是这样的:重量=单件重×数量,看上去好像很简单的样子,其实不是,这里的单件重是会变化的,有些时候是保留3位小数有些时候是保留6位小数。并且这个重量的业务逻辑是在N多个地方都须要用到的,查看代码下来大概有几十个地方都在重复着编写“重量“的业务逻辑。
后来我在同事的协助下重构了这块业务模型,为何我这里不用业务逻辑来形容个人重构工做,是由于我考虑业务的时候不会是过程式的,若是用”业务逻辑“来思考业务就会给人形成一个错觉就是”过程式“的代码结构。因此我考虑任何业务都是”模型驱动开发“方法,业务要抽象为模型才能重用、扩展、抗变化性。这实际上是OOA/D的精髓。业务逻辑只是在模型中的一小块一小块的具体动做,它是在模型的范围内使用的,而不能一上来就是业务逻辑,业务逻辑太细小不便于抽象化。
(图2:重量、单件重模型)
我用上面的这个模型对重量业务模型进行了重构。将本来很重要的业务概念重量、单件重、不一样类型的单件重,进行了概念显示化,保证这些重要的领域模型不被过程式的代码淹没。且用两个工厂封装了建立重量和单件重的业务逻辑。这样作以后咱们的模型就具备抗变化性,之后要是对Weight有任何的建立逻辑的变更咱们就能够在WeightFactory中处理,若是有新的品类扩充进来后须要对单件重相关的处理咱们只须要扩展下ItemCategory和PieceWeightFactory两个模型。若是你须要作为彻底配置化,这个时候模型就更有价值。好比,咱们能够将IitemCategory拿出去,经过品类扩展的时候自动生成相关的类型,若是你以为这还不够完美,咱们能够进一步将PieceWeightFactory中有关于“根据ItemCategory建立PieceWeight(Decimal) “,作成”Mapper模型“在进行配置化。
这里你会发现一个很奇妙的地方就是,一旦模型化后业务的量变引发的质变能够经过逐步重构模型、提取模型、精华模型来解决。
因此说简单的系统结构是没法表示复杂的业务模型的,若是能够的话OO语言就不会发展成今天的这样子。复杂的业务没法经过简单的系统结构或者说所谓的简单的快速开发框架之类的东西能够解决的。
不少时候咱们都在强调“多去了解业务、多去熟悉业务”,在业务驱动型公司这是必须的,公司中的任何角色的单位都须要熟悉公司的业务范围。这没有问题,我想说的是不一样的角色对于业务的理解最终的业务模型是不一样的。
无论是在传统的软件企业中仍是互联网企业中,咱们要用软件来服务于咱们或者客户,固然这里所说的是业务系统。业务系统的核心就是业务,系统的精神就是业务模型及模型之间的关系。
这节我想说的是,技术人员去了解业务后和产品经理去了解业务后最终的业务模型是怎样的。技术人员与产品经理是不一样的角色,具备不一样的职业背景,不一样的知识结构和专业度。如今存在一个广泛的认识错误是,技术人员理解业务后与产品经理理解的业务后的最终的模型是同样的,是怎样的呢。是没法抽象的业务,大概的业务,场景化的业务,没法落地到系统中的业务。此时技术人员并无用本身的专业度来对业务进行抽象和建模,并无直接带来真正的价值,而是在交谈和理解需求的时候感受上的价值错觉。
技术人员不可以业务技术化其实对于公司所说的“当技术人员理解业务后产生的价值是巨大的”实际上是不许确的。
产品对于业务的理解是总体上的,包括业务流程、数据流程,场景,在他们的脑子里是真实的业务场景,是必需要还原的业务场景,不可以有任何的其余模型在做怪。若是产品用任何的其余知识来抽象和强制理解业务是会出现问题的。
产品对于业务的最终模型是业务流程、数据流程和一个不须要表现的场景。
(图3:产品的业务理解最终模型—业务流程图)
因为数据流程图比较简单,当前例子中只会有“订单”的数据实体,画出来意义不大,我这里就只画一个业务流程图来表达意思便可。
在这个程度上是没法直接将流程图落到系统上的,它距离真正编写软件还有一段过程要进化,而下面那段过程才是技术人员理解业务后要发挥的价值和做用。
技术人员的了解业务要有所侧重,你理解的业务和产品理解的业务是不同的,技术人员须要将业务最终技术化才行。技术人员的最终的业务模型是有正确的模式能够参考的,就拿“建立订单”这个流程来讲,等待技术人员须要去提取和抽象的东西是比较多的也是比较复杂的,须要结合不少的知识来进行设计活动。
好比订单,你须要结合“四色原型”模式来提取“订单”的模型,包括“订单的类型“、”订单的跟踪“,须要结合设计模式来抽象”建立订单的逻辑“,根据”不一样的订单类型建立不一样的最终订单“。还须要进行设计模型的抽象,好比建立订单,各个对象的交互是如何的,每一个交互的输入和输出是什么。这些都须要技术人员理解了业务后应该具备的业务模型,若是须要将模型语言化就须要结合使用UML来建模。
若是技术人员理解业务后和产品经理理解业务后的结果是同样的,那技术人员要去理解有什么价值。技术人员理解业务后要系统化的将各个业务模型落地到具体的领域内或者说某个子系统子服务中,而后各个系统和服务是如何交互的,逻辑的归属究竟是哪边的。最终你写出来的代码才是知足业务的代码模型,才是有核心竞争力的业务系统有别于无核心竞争力的系统差距。
技术人员了解业务后,针对不一样的业务场景开始建立领域模型草图,根据领域草图再进行设计模型草图建立,固然这是一个敏捷的迭代的过程。
(图4:“建立订单”相关的领域模型)
有了领域模型以后就须要建立设计模型,也就是各个模型之间的协做关系。仍是要强调下,这是一个快速迭代的过程,且勿将其当作是瀑布的依赖过程。领域模型的精华也是没有止境的,当后面进行设计模型的过程时会有对领域模型有补充的灵感,此时不能够教条,要快速的精华领域模型而后再进行设计模型的过程。
(图5:“建立订单”相关的设计模型)
基于领域模型建立设计模型中的对象协做模型,设计模型不只仅只有协做模型一种还有其余的。协做模型是必须的也是最重要的。有了协做模型以后咱们就能够走查场景是否知足“建立订单”的这么一个业务动做。当八九不离十的时候就能够进入到编写代码阶段,进行一个快速的构建代码模型,由于这个时候仍是会有问题出现,只有在代码模型中没有问题后才是真的没有了。
我这里只是假设一个简单的业务场景做为示例,目的是为了介绍技术人员区别于产品对于业务理解后的最终模型是不一样的。技术人员必定要有完善的能将业务技术化的知识结构,这样才能真正的将业务发挥价值。
技术债务实际上是没法避免的,各类缘由,时间进度、需求变动、市场迫切等,都迫使研发开始堆积技术债务,代码逐渐开始腐烂,难道咱们做为技术人员就只有抱怨和推卸责任吗。这里我有一些我的见解,这些我的见解可能跟你的理解不同,你可能会说我太理想主义了,可是我想说的是:“做为一个技术人员必定要有情怀,必定要有追求。”用我最尊敬好朋友冯老师的话说:“写代码必定要考究“。就算在时间比较紧的时候能够先写,可是要记住你的工做并无彻底完成。
我是从开发作到架构,经历过不少项目磨练,也深知在项目时间比较紧急的时候本身是在一个什么精神状态下写代码的,本身也干过处处复制代码粘贴代码的时候,加班到12点,眼睛基本上已经很难看清代码,敲代码的速度已经赶不上功能交付的速度。我只能说这也没有办法,市场决定了项目的进度。咱们能够吐槽,可是不能抱怨,更不能消极。
其实现实状况下咱们作开发的基本上都是在这个节奏下工做,可是我是怎么处理这个问题的呢。首先写好代码是我的对技术的一个追求和职业素养的问题,若是你对代码没有美感你很难能编写出好的代码,你的代码也会处处留有坏味道,时间长了就是腐烂的遗留代码,严重的技术债务,研发成天怨声四起,各类抱怨,吐槽,这样下去实际上是很差的,团队里有追求的技术人员会流失。
实话实说,当本身今天晚上12点写好了代码提交了测试,可是个人工做并无完成,我一般会在早上很早就醒了,我会很早的来到公司对本身的代码进行重构和梳理,早上是大脑特别清醒的时候,在这个时候你进行代码的整理是很是不错的,并且这个时候公司通常都没什么人,特别安静,当你重构完代码舒服舒服的再去整理本身天天早上来的其余事务。
你可能会说那是你我的问题,我不必定会在次日早上能起的那么早,就算起的来我到了公司也不会对次日的代码进行整理,由于那已经上线了已是完成的功能,我该继续下一个需求。
用个人价值观来看的话,其实你的工做只完成了一半,你并无保质保量的完成工做,你的软件交付质量在产品层面是完成了,可是你在技术层面是有残缺的。你给软件带来了不少的技术债务,你给某个对象带来了腐烂代码的开始。
这点我如今的公司是很是不错的,公司高层对项目的管理者首要的要求就是必须懂技术。
我一没事就会和个人好朋友也是好同事冯老师交流技术,互相review代码,提意见,在互相重构,彼此学习。咱们有一个共鸣,就是让写代码有追求的人来把控项目是很是不错的,能够保质保量的完成功能,固然不是光说有写代码能力就OK的,须要综合性的。其实说白了,让一个精通技术的人在去精通业务作出来的软件应该是不错的。 (这里所说的精通技术是指应用开发方面的精通,不是指技术专家、系统层的技术专家)
做为应用开发人员,要时刻记住你所应该具备的专业的职业素养,写代码要讲究,要记住对你来讲代码意味着什么。
未完待续。。。。。。