资深架构师的经验分享——软件项目开发和决策
这篇文章是关于什么的
参与项目决策的人必须意识到他们的决定对项目的成功和成本以及时间和金钱的影响。
对于我20多年的软件开发经验和10多年的咨询工作,我作为架构师或开发人员参与了许多项目 - 其中大多数成功,有些失败,但每个项目(无论成功与否)都涉及好的和不好的决策由各种人制作。
本文的目的是通过提倡根据我的经验做出的决定以及避免错误的决策来为项目成功奠定基础。
总的来说,我拥有C ++,Java,C#和JavaScript的经验,但在过去的10年中,我一直主要致力于C#桌面应用程序。尽管如此,这里提出的许多想法都具有一般性。当我讨论一个C#桌面应用程序时,我明确地陈述它。
软件开发始终存在一个“政治组件” - 本文不涉及这一点。本文的目的是提供建议,以最大限度地提高客户满意度,同时最大限度地减少支出。
项目开发主要指南
在这里,我介绍了软件开发的两个主要准则,这将在文章中进一步详细描述。
-
在软件开发主题上有很多书籍,文章和更多的广告垃圾。用一粒盐吧!如果你读的东西与常识冲突 - 选择常识。
-
在公司,项目或个人层面,需求的传播(特别是API需求)应该从使用它的人(客户)流向构建它的人,而不是相反。通过客户端,我也指同一项目中使用其他人构建的软件的开发人员。这个非常重要的规则常常被忽视,不利于项目的成功。
在项目的开始
在一个项目的开始阶段就要做出一些重要的决定。理论上,在项目开始时做出的错误决策可以稍后纠正。然而,错误的决定浪费的金钱或时间越多,后来纠正的可能性越小,因为纠正它们会引发能力问题。
选择一种语言
对于一门语言,我强烈建议不要使用C ++(除非你正在构建一些非常高性能的算法,因为它的编译时间很慢,因此一秒钟的分裂至关重要)。每个软件开发(如果正确完成)都涉及很多原型设计,并重新启动应用程序或为应用程序运行测试。代码更改后的每次新运行都涉及编译。C ++模板的构建方式是在编译时必须生成代码,这样C ++通常编译起来非常慢。编译速度缓慢将导致原型设计速度缓慢,开发速度相应缓慢。没有模板,C ++没有现代强类型语言那么强大。
而且,Java和C#拥有许多内置于该语言的标准库,而C ++则依赖于第三方库。
最佳团队规模
在我的经验中,较小的团队可以更快地生成更好的软 例如,对于桌面三层项目,我会推荐一个3人团队 - 每个层级一个人+一个建筑师+ 1-3个裁员。
我最成功的项目正是由3-7名成员组成的团队。我参与过的最不成功的项目之一是拥有20多名成员的团队,几年内无法实现几个月内小型项目将实现的目标。
Scrum或不Scrum
毫无疑问 - 对Scrum来说!敏捷/ Scrum可能并不完美,但它比替代品更好。然而,Scrum的某些方面并不有效(我认为它们不应该成为过程的一部分,尽管大多数敏捷教科书都会提到它们)。以下是scrum的正面和负面特征列表。我的建议是:避免使用负面特征。
Scrum的积极
-
通常,在项目开始时,客户本身可能不清楚他们需要什么。它需要很多迭代(包括客户和开发人员的错误)让客户弄清楚需要构建什么,以及开发人员如何构建它。Scrum的迭代方法最适合这种范式。
-
在scrum之下,开发人员可以估计自己需要多长时间才能实现某个功能 - 他们通常可以做得比管理人员好得多。
-
每日更新对经理和开发人员都有益。双方都可以更好地了解项目的位置。此外,对于开发者来说,这是一个与他人分享他们一直在努力工作的机会,以便了解他人正在做什么,并且一般来说,在编程时可以锻炼大脑的非编程部分部分休息一下。
-
Scrum会议结束后,包括演示和计划在内,也会因日常会议的原因而受益,但规模较大。
Scrum的负面影响
-
一些Scrum版本倡导只跟踪整个团队的表现 - 不考虑个人开发者的贡献。虽然团队绩效非常重要,但认识个人努力仍然很重要。
-
在Scrum结束时召开了会议,人们捶胸说出了什么问题 - 越多越好。我从来没有看到从他们身上出现任何好东西。发生问题时,应由开发人员解决。更严重的问题应该升级到建筑师/经理,有时候应该改变项目程序。
对等编程
除非是短期的,并且由两个愿意合作伙伴完全自愿地分享知识,否则永远不会看到任何好的同伴节目。
我练习非常积极,快速,以结果为导向的编程 - 观看别人的节目让我想睡觉。我认识的每个人都*做同侪编程,分享我对它的看法。
选择软件包和第三方组件
你应该非常小心选择3 次党库-你应该怀疑华而不实的演示和广告。选择一个3 次方包(无论是开源还是需要付出的东西),只有当以下条件之一是true
:
-
这是一个众所周知的产品 - 如MS Visual Studio,Oracle DB,MS SQL Server,Telerik或DevExpress控件 - 拥有数千种证词
-
您的开发人员将直接使用该软件,并在合理的时间内对该软件进行试验,至少两周,并且使用起来非常舒适。
请记住,您为软件包支付的金额越多 - 之后将更换或更换副本越困难,因为您花钱的人会希望确保这笔钱不会被浪费。
请记住,伟大的公司仍然可以有糟糕的产品。我多年前就有一个团队对Oracle的Stellent软件产生了负面影响 - 他们花费了大约25万美元!对于甲骨文而言,他们当时刚刚购买了Stellent,因此它完全是在Oracle之外开发的。
此外,还记得那花了一个月研究3 个在一开始方组件可以从字面上拯救你年后。
第三方组成部分的一些具体建议
本部分针对MS桌面系统。
UI控件的包
对于WPF前端,我推荐以下软件包:
-
Telerik - 用WPF概念构建而成,易于修改和学习。
-
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保守派
团队中总有人渴望并愿意学习新软件和新软件包(我就是其中之一),以及那些想要坚持熟悉的老软件和旧软件包的人。
以下是这些方法合理的一些例子。
进步是正确的
-
很久以前,由于缩短了编译时间和原生包,从C ++切换到Java极大地提高了项目的生产力。
-
切换到WPF和C#绝对是一个伟大的决定 - WPF是最好的基于Windows的桌面开发包,而C#现在比Java更强大,并且不断改进。
-
人们采用反应式扩展的速度很慢,但它绝对是一个很好的软件包,可以用来构建过去非常复杂的事情。
-
Roslyn是一款出色的C#编译器,我相信它最终将使人们能够实现自己的语言特性,同时提供完整的IDE支持。
当保守派是对的
在过去的10年中,微软发布了许多失败的软件包。(这教会我小心)。
-
我对Silverlight仍然非常痛苦。我认为这是一个伟大的web开发包。我敢打赌Silverlight(尽管我明白它是微软的一种慈善行为,因为它破坏了自己的平台),我输了。
-
Windows RT,曾经被MS积极推广的多个Windows Phone平台失败。(我已经更聪明了,从一开始我就感觉不太好)
关于预测包裹何时失败或成功的一些想法
恐怕以100%确定性来预测几乎是不可能的。
WPF是一个很好的包,我从第一眼就爱上了它的概念(之前我有过很多类似的想法)。
Silverlight也是由MS完全维护的一个很好的软件包,当MS决定他们不再需要时,它基本上已经死亡。
Windows RT是一个翻版,我觉得它从一开始就会成为一个翻版,因为他们偏离了.NET并试图进入本地。
我猜的经验法则是:
-
当MS发布一款优秀的产品并在其背后放置一些肌肉时 - 产品就会蓬勃发展。
-
当MS发布一款优秀的产品并停产时 - 产品就会死亡。
-
即使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点:
-
我并不是说UI开发人员完全确定了API。应该在请求者和实现者之间的讨论中明确API - 有些事情可能不可能或很难实现。
-
服务器的实现仍然取决于服务器开发人员 - 我只谈论客户需要的公共API。
UI开发人员和后端/中间层开发人员之间的关系应该与最终用户和UI开发人员之间的关系完全相同。
这个原则通常不被遵循。实际上,人们从后端和中间层开始开发,然后UI必须围绕所有由此产生的API问题进行论述。
想象一下,UI开发人员会来到最终用户,并告诉他们,即使他没有与他们进行任何咨询,他所建的东西也能满足他们的需求。听起来相当荒谬,但是UI开发人员不得不经常处理类似的情况,当后端开发人员告诉他们现在他们拥有他们所需要的所有东西,即使他们没有与UI开发人员进行任何咨询。
我的经验一次又一次地证实了这个原则 - 需求,APIs甚至开发都应该从使用API的部分传播到实现它的部分。这不仅适用于客户端 - 服务器部门,也适用于您自己编写重要软件的情况。你需要从软件的目的开始,然后填写'空格'。否则,如果你从'空白'开始,你可能会发现他们不太适合这个目的。
测试驱动开发的普及是对这种范式的另一种证实。
创建API
在传统的'瀑布'哲学中,建筑师试图在项目的一开始就创建很多接口,以便开发人员能够为他们编程。从我的角度来看,这不是最好的方法 - 它把马车放在了马匹的前面。
在开始时应该创建很少的接口,并且架构师应该随时准备修改它们,如果发现它们不符合目的。
应该在需要时创建接口 - 例如,只要有方法或类需要处理满足某个接口但实现可能会有所不同的对象时。不要过于努力地预见,你需要一个接口 - 首先(当只需要一个实现时)编程到一个类,但是当出现这样的需求时,准备将它改变为一个接口。
这在个人层面和建筑师层面都是如此。敏捷的迭代特性能够适应API修改。
建筑师的角色
这将我带入软件架构师的角色。
团队中的一位开发人员可以承担建筑师的角色(特别是在项目大小合理的情况下)。
这是软件架构师应该承担的任务:
-
概述发布过程 - 将产品移至用户或用户代理。
-
随时关注产品开发进度和产品需求变化。
-
在开始阶段 - 如上所述构建产品的非常稀疏的骨架(原型)(包括初始测试项目)。
-
解决各种开发人员之间的软件问题。
-
找出代码共同点并将它们分解成可供各种开发人员在各个地方使用的通用API。
最后一点也应该由各个开发人员为他们自己的代码实施,或者如果开发人员在多个开发人员领域中看到代码的共同性,他应该将其引入共同考虑范围,并让架构师决定是否需要分解通用性。
一般来说,代码中的共同点应该不断重构,无论是由开发人员还是架构师。
有些人认为他们需要提前找出并排除所有共同点。这不太可能。没有人能够做到这一点,就像没有人能够在项目开始时创建所有界面一样。没有理由花大量时间在一开始就考虑个人或架构师层面的共同点。在整个代码开发过程中,您将能够找到要重构的代码。
我对建筑师的建议是在整个多层架构中考虑数据形状。在关系数据库中 - 数据通常放置在规范化的表格中。也有一些记录可能通过实时提要进行传播。该级别没有层次结构。然而,在UI方面,大多数记录需要一些层次结构,以用户想要的形状显示给用户。我打算写另一篇专门讨论数据形状和数据形状转换的文章。
建立一个团队
根据我的经验,工作场所以外的非工作相关活动是建立人与人之间信任并让人感觉自己是团队的好方法。以下是一些可行的活动:
-
清道夫狩猎
-
去一家餐馆或喝一杯
-
足球比赛
-
保龄球
人的问题
以下是我在整个项目中观察到的一些与人相关的问题
-
良好的领导能力和政治技能不足以执行一个项目。事实上,我看到项目失败了,因为他们是由具有良好领导才能和政治技能的人领导的,但没有任何软件开发意识或有一些软件开发意识,但不敢用它来反驳上司。
-
在会议上充满自信地发言的人不一定知道软件细节。重要的决定决不应该在一次会议上进行 - 只有在彻底的书面讨论之后。
当没有线索的人试图接管某个领域的编码或项目领导时,我观察到了所谓的“庸医”问题。他们可能具有良好的领导能力和演讲技巧,其中一些甚至可能拥有技术技能,但在不同的领域。不应允许这些人在他们不知道的领域做出决定。
检查一个人是否是某个领域的专家的一种方法是让他建立一个概念验证原型。如果他不能建立一个小概念证明,他不应该被允许接管这个项目。
我曾与一位表示制作原型的人合作需要太多时间,并且每个人都只是跟随他的领导或者整个项目都将崩溃。这种“全部或全部”的方法肯定是一种尴尬的迹象 - 应该始终可以建立一个小概念证明。这个人不得不离开这个项目,没有他,项目就成功了。
面试候选人
我在职业生涯中进行了许多面试,这里有几点我想分享一下:
-
切中要害 - 如果你想聘请Angular专家,不要问他关于WPF或SQL的许多问题。
-
例如,测试概念并不是细节,例如,测试人们对关系数据库概念的理解总是很好的,但是(除非你专门雇用SQL专家),你不必在MS SQL Server中测试他对临时表的了解。
-
有时候,记忆力好的人可以通过心灵学习很多信息,然后用它来进行面试。这就是为什么让人们真正进入并进行简单的编码考试非常重要。这种方式总是可以看出该人是否拥有知识,或者在几天之前他就简单地挤满了所有东西。
编写,执行和测试要求
这个要求应该在开发者和订购需求的人之间进行确定 - 它可能是最终用户,也可能是团队中的建筑师或其他开发人员。由于开发人员的屁股已经上线,开发人员应该经常仔细阅读这个要求,确保在开始工作之前不要留下任何碎片。
要求(或Jiras)通常应该考虑到单一功能。该功能可能是用户功能,或者可能是终端用户永远不会看到的功能,例如某些重构; 无论哪种方式,大多数情况下,一个要求应该有一个功能。
一旦创建了需求,就不应该添加新的功能请求。它应该作为从请求者到质量保证的路线图。如果事实证明开发人员实施了这项要求,但是要求是错误的或者不完整 - 这是请求者的错,并且应该打开一个新的Jira来覆盖剩余的。但是,如果开发人员没有满足这个要求 - 这是开发人员的错,而且需要重新开放并重新分配给同一开发人员完成。
当涉及到UI开发时,也有一些小的,易于实现的需求(我称之为'UI烦恼'),尽管它们可以接触完全不同的功能,但它们都可以使用到单个Jira。你可以为他们打开特殊的'尼特'吉拉,在'单一功能'的条件是没有必要的。
针对上面的技术我特意整理了一下,有很多技术不是靠几句话能讲清楚,所以干脆找朋友录制了一些视频,很多问题其实答案很简单,但是背后的思考和逻辑不简单,要做到知其然还要知其所以然。如果想学习Java工程化、高性能及分布式、深入浅出。微服务、Spring,MyBatis,Netty源码分析的朋友可以加我的Java进阶群:744642380,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给大家。
结论
在本文中,我以建筑师和开发人员的长期经验为基础,提出了启动和执行多层项目的建议。
我相信遵循这些建议可以大大降低项目成本的时间和金钱,并提高产品的价值。
上一篇: c#获取excel中的所以sheet名称(自用笔记)
下一篇: 控制台操作之字体颜色