资深架构师的经验分享——软件项目开发和决策

这篇文章是关于什么的前端

参与项目决策的人必须意识到他们的决定对项目的成功和成本以及时间和金钱的影响。web

对于我20多年的软件开发经验和10多年的咨询工做,我做为架构师或开发人员参与了许多项目 - 其中大多数成功,有些失败,但每一个项目(不管成功与否)都涉及好的和很差的决策由各类人制做。面试

本文的目的是经过提倡根据个人经验作出的决定以及避免错误的决策来为项目成功奠基基础。算法

总的来讲,我拥有C ++,Java,C#和JavaScript的经验,但在过去的10年中,我一直主要致力于C#桌面应用程序。尽管如此,这里提出的许多想法都具备通常性。当我讨论一个C#桌面应用程序时,我明确地陈述它。数据库

软件开发始终存在一个“政治组件” - 本文不涉及这一点。本文的目的是提供建议,以最大限度地提升客户满意度,同时最大限度地减小支出。编程

项目开发主要指南后端

在这里,我介绍了软件开发的两个主要准则,这将在文章中进一步详细描述。缓存

  1. 在软件开发主题上有不少书籍,文章和更多的广告垃圾。用一粒盐吧!若是你读的东西与常识冲突 - 选择常识。服务器

  2. 在公司,项目或我的层面,需求的传播(特别是API需求)应该从使用它的人(客户)流向构建它的人,而不是相反。经过客户端,我也指同一项目中使用其余人构建的软件的开发人员。这个很是重要的规则经常被忽视,不利于项目的成功。架构

在项目的开始

在一个项目的开始阶段就要作出一些重要的决定。理论上,在项目开始时作出的错误决策能够稍后纠正。然而,错误的决定浪费的金钱或时间越多,后来纠正的可能性越小,由于纠正它们会引起能力问题。

选择一种语言

对于一门语言,我强烈建议不要使用C ++(除非你正在构建一些很是高性能的算法,由于它的编译时间很慢,所以一秒钟的分裂相当重要)。每一个软件开发(若是正确完成)都涉及不少原型设计,并从新启动应用程序或为应用程序运行测试。代码更改后的每次新运行都涉及编译。C ++模板的构建方式是在编译时必须生成代码,这样C ++一般编译起来很是慢。编译速度缓慢将致使原型设计速度缓慢,开发速度相应缓慢。没有模板,C ++没有现代强类型语言那么强大。

并且,Java和C#拥有许多内置于该语言的标准库,而C ++则依赖于第三方库。

最佳团队规模

在个人经验中,较小的团队能够更快地生成更好的软 例如,对于桌面三层项目,我会推荐一个3人团队 - 每一个层级一我的+一个建筑师+ 1-3个裁人。

我最成功的项目正是由3-7名成员组成的团队。我参与过的最不成功的项目之一是拥有20多名成员的团队,几年内没法实现几个月内小型项目将实现的目标。

Scrum或不Scrum

毫无疑问 - 对Scrum来讲!敏捷/ Scrum可能并不完美,但它比替代品更好。然而,Scrum的某些方面并不有效(我认为它们不该该成为过程的一部分,尽管大多数敏捷教科书都会提到它们)。如下是scrum的正面和负面特征列表。个人建议是:避免使用负面特征。

Scrum的积极

  1. 一般,在项目开始时,客户自己可能不清楚他们须要什么。它须要不少迭代(包括客户和开发人员的错误)让客户弄清楚须要构建什么,以及开发人员如何构建它。Scrum的迭代方法最适合这种范式。

  2. 在scrum之下,开发人员能够估计本身须要多长时间才能实现某个功能 - 他们一般能够作得比管理人员好得多。

  3. 每日更新对经理和开发人员都有益。双方均可以更好地了解项目的位置。此外,对于开发者来讲,这是一个与他人分享他们一直在努力工做的机会,以便了解他人正在作什么,而且通常来讲,在编程时能够锻炼大脑的非编程部分部分休息一下。

  4. Scrum会议结束后,包括演示和计划在内,也会因平常会议的缘由而受益,但规模较大。

Scrum的负面影响

  1. 一些Scrum版本倡导只跟踪整个团队的表现 - 不考虑我的开发者的贡献。虽然团队绩效很是重要,但认识我的努力仍然很重要。

  2. 在Scrum结束时召开了会议,人们捶胸说出了什么问题 - 越多越好。我历来没有看到从他们身上出现任何好东西。发生问题时,应由开发人员解决。更严重的问题应该升级到建筑师/经理,有时候应该改变项目程序。

对等编程

除非是短时间的,而且由两个愿意合做伙伴彻底自愿地分享知识,不然永远不会看到任何好的同伴节目。

我练习很是积极,快速,以结果为导向的编程 - 观看别人的节目让我想睡觉。我认识的每一个人都被迫作同侪编程,分享我对它的见解。

选择软件包和第三方组件

你应该很是当心选择3 次党库-你应该怀疑华而不实的演示和广告。选择一个3 次方包(不管是开源仍是须要付出的东西),只有当如下条件之一是true

  1. 这是一个众所周知的产品 - 如MS Visual Studio,Oracle DB,MS SQL Server,Telerik或DevExpress控件 - 拥有数千种证词

  2. 您的开发人员将直接使用该软件,并在合理的时间内对该软件进行试验,至少两周,而且使用起来很是温馨。

请记住,您为软件包支付的金额越多 - 以后将更换或更换副本越困难,由于您花钱的人会但愿确保这笔钱不会被浪费。

请记住,伟大的公司仍然能够有糟糕的产品。我多年前就有一个团队对Oracle的Stellent软件产生了负面影响 - 他们花费了大约25万美圆!对于甲骨文而言,他们当时刚刚购买了Stellent,所以它彻底是在Oracle以外开发的。

此外,还记得那花了一个月研究3 个在一开始方组件能够从字面上拯救你年后。

第三方组成部分的一些具体建议

本部分针对MS桌面系统。

UI控件的包

对于WPF前端,我推荐如下软件包:

  1. Telerik - 用WPF概念构建而成,易于修改和学习。

  2. DevExpress - 不须要 WPF(在我看来),因此定制起来不那么容易,但仍然灵活并且速度很快。它具备Telerik没有的一些控件,包括容许用户在运行时组装WPF视图和地理地图控件的设计器控件。

我对Xceed了解很少,但从我听到的状况来看,它的使用也至关不错。

我会警告反对Syncfusion - 至少几年前,它创建与WPF意识形态相反。

我会推荐反对Infragistics - 它具备最开箱即用的功能,但根据个人经验,这很难定制,而在WPF中,定制是游戏的名称!

全部上述WPF软件包在制图时都会遇到性能问题。我与之合做的WPF Chart软件包,我强烈建议使用SciChart。

不管您选择何种软件包 - 选择包含下载源代码权限的许可证。每当我使用Telerik或DevExpress时,我都必须研究他们的代码,以便可以产生个人客户所指望的效果。

IoC容器

大多数体面的规模项目都应该包含控制的倒置,以便为项目构建扩展点或便于交换实际测试实现的实现(例如,当涉及到对后端测试前端功能时)。

大多数状况下,我使用的MEF2有点复杂,但老是适合项目的目的。

我听到不少Ninject的正面评论(尽管我本身从未使用过)。

我正在开发Roxy IoC容器。它仍在进行中,特别是在IoC方面,因此我如今不能推荐它。但愿我能在几周内推荐它。

测试框架

无论怎样,Xunit是我所知道的最好的测试框架,我极力推荐它。这是免费的。它容许使用各类基于属性的输入来运行相同的测试。在其余框架中,您必须为每一个输入组合编写单独的代码。

中间层

在MS宇宙中,我会建议使用MVC控制器或WebApi或WCF构建自定义中间层。我也喜欢在中间层使用ADO Entity Framework。

WCF比ASP中间层解决方案更复杂,更强大。一般,ASP中间层对于此目的来讲已经足够了,但对于更复杂的需求,好比使用TCP链接而不是HTTP,WCF很棒。

后端

对于体面大小的项目,我建议使用Oracle或MS SQL Server。根据个人经验,最多不使用SQL数据库做为缓存机制与SQL数据库一块儿使用,或者用于某些特殊操做,例如全局搜索。

项目工具

我使用了许多工具,下面是我推荐的工具:

对于源代码控制,我推荐Git和Subversion; 都工做得很好,都是免费的 - 个人首选是Git。

做为需求/错误跟踪系统,我推荐Atlassian Jira或Rally。二者都是高度可配置,通过充分测试的解决方案。

为了构建,发布和持续集成,我推荐Atlassian Bamboo。

请注意,当用户数少于10时,Atlassian软件很是便宜。对于这样的团队,每一个产品的平均费率为每个月10美圆。

进步vs保守派

团队中总有人渴望并愿意学习新软件和新软件包(我就是其中之一),以及那些想要坚持熟悉的老软件和旧软件包的人。

如下是这些方法合理的一些例子。

进步是正确的

  1. 好久之前,因为缩短了编译时间和原生包,从C ++切换到Java极大地提升了项目的生产力。

  2. 切换到WPF和C#绝对是一个伟大的决定 - WPF是最好的基于Windows的桌面开发包,而C#如今比Java更强大,而且不断改进。

  3. 人们采用反应式扩展的速度很慢,但它绝对是一个很好的软件包,能够用来构建过去很是复杂的事情。

  4. Roslyn是一款出色的C#编译器,我相信它最终将令人们可以实现本身的语言特性,同时提供完整的IDE支持。

当保守派是对的

在过去的10年中,微软发布了许多失败的软件包。(这教会我当心)。

  1. 我对Silverlight仍然很是痛苦。我认为这是一个伟大的web开发包。我敢打赌Silverlight(尽管我明白它是微软的一种慈善行为,由于它破坏了本身的平台),我输了。

  2. Windows RT,曾经被MS积极推广的多个Windows Phone平台失败。(我已经更聪明了,从一开始我就感受不太好)

关于预测包裹什么时候失败或成功的一些想法

恐怕以100%肯定性来预测几乎是不可能的。

WPF是一个很好的包,我从第一眼就爱上了它的概念(以前我有过不少相似的想法)。

Silverlight也是由MS彻底维护的一个很好的软件包,当MS决定他们再也不须要时,它基本上已经死亡。

Windows RT是一个翻版,我以为它从一开始就会成为一个翻版,由于他们偏离了.NET并试图进入本地。

我猜的经验法则是:

  1. 当MS发布一款优秀的产品并在其背后放置一些肌肉时 - 产品就会蓬勃发展。

  2. 当MS发布一款优秀的产品并停产时 - 产品就会死亡。

  3. 即便MS肌肉也没法挽救糟糕的产品。

我想在本小节中对有关新的MS软件包的一些预测加以限制。

基于我掌握的有限信息,我相信Xamarin拥有光荣的将来 - 它有望成为智能手机和平板电脑编程的主要手段之一。

恐怕UWP不会飞,由于它只适用于Windows 10和Windows 10产品。您将没法在Windows 8或Windows 7上运行它,更不用说Linux或Mac。为何使用它,若是它只是WPF和WPF在任何Windows平台上运行的苍白阴影?

我之前错了,我可能又错了 - 时间会显示。

在项目开始前或开始时进行原型设计

尽管Agile具备迭代性,事实上客户可能只是对最终产品应该在一开始就应该有一个模糊的概念,但项目设计师在开始时至少想出了一个小原型是一个好习惯项目。

这样的原型应该结合一些UI,中间层和数据库功能以及基本的测试项目。应用程序的全部部分应该可操做并相互通讯,而且应该运行测试。

根据个人经验,我建议在原型上花费2周到1个月的时间。只有在建筑师要求的状况下,建筑师才能在别人的帮助下亲自完成。

该项目的其他部分将涉及扩大原始原型。

除了做为参考的初始参考点以外,这样的原型还可让管理人员和团队确信他们作出的决定以及他们使用的第三方组件将实际达到最终目标。

3层架构

这是标准的3层体系结构模式:

在图中 - 双面黑色箭头表示从UI客户端到中间层以及从中间层到数据库的请求 - 响应链接。

单侧红色箭头表示从实时馈送到中间层和客户(订阅它)的“热”(实时)链接。此外,它还显示一旦收到实时数据,它可能会记录到数据库中(从中间层到数据库的红色箭头)。

中间层能够有高速缓存,单个客户端高速缓存能够提升速度。一般,您缓存您知道在特定时间段内不会更改的数据。当时间间隔过去后,您将数据强制从缓存中移出或标记为“过期”,以便在下一次请求后刷新数据。

重要说明:根据个人经验,最好的中间层是没有任何业务逻辑的层。业务逻辑应该驻留在数据库和UI中。中间层应该是数据库基本功能中高度可配置的通用网关,而且不该在每次扩展业务逻辑时都进行修改。我用C#和Java在个人生活中屡次构建了这样的中间层。

也许第二个最好的中间层是在添加新的业务逻辑时仅须要较小的和标准化的修改的层。我也曾屡次与这样的中间层合做过。

运行项目

客户端 - 服务器API要求传播原则

多层开发的主要原则是客户端应该比他实现它的API有更多的发言权(API应该由客户端驱动)。

正如软件的客户(或客户端代理,如产品经理)对最终产品的外观应该有更多的说法,UI开发人员也应该对他从中间层使用的API有更大的发言权,后端。

我想清楚2点:

  1. 我并非说UI开发人员彻底肯定了API。应该在请求者和实现者之间的讨论中明确API - 有些事情可能不可能或很难实现。

  2. 服务器的实现仍然取决于服务器开发人员 - 我只谈论客户须要的公共API。

UI开发人员和后端/中间层开发人员之间的关系应该与最终用户和UI开发人员之间的关系彻底相同

这个原则一般不被遵循。实际上,人们从后端和中间层开始开发,而后UI必须围绕全部由此产生的API问题进行论述。

想象一下,UI开发人员会来到最终用户,并告诉他们,即便他没有与他们进行任何咨询,他所建的东西也能知足他们的需求。听起来至关荒谬,可是UI开发人员不得不常常处理相似的状况,当后端开发人员告诉他们如今他们拥有他们所须要的全部东西,即便他们没有与UI开发人员进行任何咨询。

个人经验一次又一次地证明了这个原则 - 需求,APIs甚至开发都应该从使用API的部分传播到实现它的部分。这不只适用于客户端 - 服务器部门,也适用于您本身编写重要软件的状况。你须要从软件的目的开始,而后填写'空格'。不然,若是你从'空白'开始,你可能会发现他们不太适合这个目的。

测试驱动开发的普及是对这种范式的另外一种证明。

建立API

在传统的'瀑布'哲学中,建筑师试图在项目的一开始就建立不少接口,以便开发人员可以为他们编程。从个人角度来看,这不是最好的方法 - 它把马车放在了马匹的前面。

在开始时应该建立不多的接口,而且架构师应该随时准备修改它们,若是发现它们不符合目的。

应该在须要时建立接口 - 例如,只要有方法或类须要处理知足某个接口但实现可能会有所不一样的对象时。不要过于努力地预见,你须要一个接口 - 首先(当只须要一个实现时)编程到一个类,可是当出现这样的需求时,准备将它改变为一个接口。

这在我的层面和建筑师层面都是如此。敏捷的迭代特性可以适应API修改。

建筑师的角色

这将我带入软件架构师的角色。

团队中的一位开发人员能够承担建筑师的角色(特别是在项目大小合理的状况下)。

这是软件架构师应该承担的任务:

  1. 概述发布过程 - 将产品移至用户或用户代理。

  2. 随时关注产品开发进度和产品需求变化。

  3. 在开始阶段 - 如上所述构建产品的很是稀疏的骨架(原型)(包括初始测试项目)。

  4. 解决各类开发人员之间的软件问题。

  5. 找出代码共同点并将它们分解成可供各类开发人员在各个地方使用的通用API。

最后一点也应该由各个开发人员为他们本身的代码实施,或者若是开发人员在多个开发人员领域中看到代码的共同性,他应该将其引入共同考虑范围,并让架构师决定是否须要分解通用性。

通常来讲,代码中的共同点应该不断重构,不管是由开发人员仍是架构师。

有些人认为他们须要提早找出并排除全部共同点。这不太可能。没有人可以作到这一点,就像没有人可以在项目开始时建立全部界面同样。没有理由花大量时间在一开始就考虑我的或架构师层面的共同点。在整个代码开发过程当中,您将可以找到要重构的代码。

我对建筑师的建议是在整个多层架构中考虑数据形状。在关系数据库中 - 数据一般放置在规范化的表格中。也有一些记录可能经过实时提要进行传播。该级别没有层次结构。然而,在UI方面,大多数记录须要一些层次结构,以用户想要的形状显示给用户。我打算写另外一篇专门讨论数据形状和数据形状转换的文章。

创建一个团队

根据个人经验,工做场因此外的非工做相关活动是创建人与人之间信任并让人感受本身是团队的好方法。如下是一些可行的活动:

  1. 清道夫狩猎

  2. 去一家餐馆或喝一杯

  3. 足球比赛

  4. 保龄球

人的问题

如下是我在整个项目中观察到的一些与人相关的问题

  1. 良好的领导能力和政治技能不足以执行一个项目。事实上,我看到项目失败了,由于他们是由具备良好领导才能和政治技能的人领导的,但没有任何软件开发意识或有一些软件开发意识,但不敢用它来反驳上司。

  2. 在会议上充满自信地发言的人不必定知道软件细节。重要的决定决不该该在一次会议上进行 - 只有在完全的书面讨论以后。

当没有线索的人试图接管某个领域的编码或项目领导时,我观察到了所谓的“庸医”问题。他们可能具备良好的领导能力和演讲技巧,其中一些甚至可能拥有技术技能,但在不一样的领域。不该容许这些人在他们不知道的领域作出决定。

检查一我的是不是某个领域的专家的一种方法是让他创建一个概念验证原型。若是他不能创建一个小概念证实,他不该该被容许接管这个项目。

我曾与一位表示制做原型的人合做须要太多时间,而且每一个人都只是跟随他的领导或者整个项目都将崩溃。这种“所有或所有”的方法确定是一种尴尬的迹象 - 应该始终能够创建一个小概念证实。这我的不得不离开这个项目,没有他,项目就成功了。

面试候选人

我在职业生涯中进行了许多面试,这里有几点我想分享一下:

  1. 切中要害 - 若是你想聘请Angular专家,不要问他关于WPF或SQL的许多问题。

  2. 例如,测试概念并非细节,例如,测试人们对关系数据库概念的理解老是很好的,可是(除非你专门雇用SQL专家),你没必要在MS SQL Server中测试他对临时表的了解。

  3. 有时候,记忆力好的人能够经过心灵学习不少信息,而后用它来进行面试。这就是为何让人们真正进入并进行简单的编码考试很是重要。这种方式老是能够看出该人是否拥有知识,或者在几天以前他就简单地挤满了全部东西。

编写,执行和测试要求

这个要求应该在开发者和订购需求的人之间进行肯定 - 它多是最终用户,也多是团队中的建筑师或其余开发人员。因为开发人员的屁股已经上线,开发人员应该常常仔细阅读这个要求,确保在开始工做以前不要留下任何碎片。

要求(或Jiras)一般应该考虑到单一功能。该功能多是用户功能,或者多是终端用户永远不会看到的功能,例如某些重构; 不管哪一种方式,大多数状况下,一个要求应该有一个功能。

一旦建立了需求,就不该该添加新的功能请求。它应该做为从请求者到质量保证的路线图。若是事实证实开发人员实施了这项要求,可是要求是错误的或者不完整 - 这是请求者的错,而且应该打开一个新的Jira来覆盖剩余的。可是,若是开发人员没有知足这个要求 - 这是开发人员的错,并且须要从新开放并从新分配给同一开发人员完成。

当涉及到UI开发时,也有一些小的,易于实现的需求(我称之为'UI烦恼'),尽管它们能够接触彻底不一样的功能,但它们均可以使用到单个Jira。你能够为他们打开特殊的'尼特'吉拉,在'单一功能'的条件是没有必要的。

​针对上面的技术我特地整理了一下,有不少技术不是靠几句话能讲清楚,因此干脆找朋友录制了一些视频,不少问题其实答案很简单,可是背后的思考和逻辑不简单,要作到知其然还要知其因此然。若是想学习Java工程化、高性能及分布式、深刻浅出。微服务、Spring,MyBatis,Netty源码分析的朋友能够加个人Java进阶群:744642380,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给你们。

结论

在本文中,我以建筑师和开发人员的长期经验为基础,提出了启动和执行多层项目的建议。

我相信遵循这些建议能够大大下降项目成本的时间和金钱,并提升产品的价值。

相关文章
相关标签/搜索