我们的开发理念(1):架构、设计模式和编程原则

2018-03-26   出处:www.git-tower.com  作/译者:Tobias Günther/初心  

      当软件项目变得更大更复杂时,你可能会达到一个临界点:有一天,代码质量变得至关重要。在小型项目中,你可以侥幸地轻易修复一些问题。但是,只要项目的复杂度增加,你就会开始为迄今为止所做的每一项妥协感到难过。

      随着Tower用户的逐步增加,现在已经有10万的用户,在这个过程中我们确实得到了一些痛苦的教训。这篇文章将谈到我们在这方面学到的一些重要的经验。

                 


      即使是最小的软件应用程序也是大多数公司的重大投资。你的团队将花费几天,几周,几个月甚至几年来构建该应用程序。但这不仅是一笔巨大的一次性投资,你还必须在其整个生命周期中继续投入时间和精力。当应用程序发布后,开发工作和投资都不会停止。

      以我们自己的产品Tower为例:我们用12个月来开发出了1.0版并将其推向市场。但在此后的六年中,我们生产了比原始产品多出许多倍代码。

应用程序的维护和扩展是持续不断的,这意味着其基础变得至关重要。就像房子一样,为了省钱而建立一个廉价的地基并不是一个聪明的主意。

      从逻辑上讲,我们最大的目标之一是尽可能简单和安全地扩展和改进应用程序。这就是应用程序架构发挥作用的地方。只有应用程序有一个非常好的架构,我们才能尽可能地避免对应用程序的巨大投资。我们将更深入地探究“好”的结构意味着什么。但是在每一个项目中你都应该尽可能地实现:稳健性,可维护性,可扩展性。

      改进和重构应用程序的体系结构通常看起来非常奢侈——或者甚至像是在浪费时间。但实际上,它应该被视为一种必需的行为,作为一名经验丰富的软件工程师的一项重要职责。当我们问自己是否应该投资于软件结构改进时,答案通常应该是肯定的。


      选择无聊的解决方案

                     

      当解决一个复杂问题时,很多时候你可能想要尝试用一种很多独特的解决方案。这个独特地解决方案不仅能够解决问题,同时也能够让你的同事留下深刻的影像,对你更加赞赏。然后,可能你需要却是另一个没那么独特的解决方案,这个解决方案更加容易被大家理解,甚至刚加入团队的成员也能够理解(包括你自己,在你写完代码的几周之后你依然能够很好地理解)。
所以但犹豫的时候,请使用更容易让人理解的解决方案吧!

      用乐高的方式编码

               

      假设现在有这样一个问题:如果你有可用的建模粘土和乐高积木,你会选择什么来构建你的应用程序?假设你使用了造型粘土:容易塑造,鲜艳的色彩,草莓味道——你还想要什么?但是,如果你想改正、扩展或改进你已经构建的东西,问题就来了。因为当你把所有黏土混合在一起之后,你就无法轻松地分离各个部分。

    另一方面,如果你选择了乐高积木,当你想要改进的时候,事情就变得很容易:黄色的“认证”模块不够大?把它拿出来,换上一个更大的。绿色的“导出格式”块需要使用PDF选项进行扩展?只需在其旁边放一块额外的浅绿色砖。

      模块化是乐高积木象征的概念,与应用程序的可扩展性、可维护性和长久性同义。无论你喜欢哪种框架,语言或编程原则,请始终在代码中争取模块化吧!


      立志于简洁之道

      “保持简单,愚蠢”提醒我们,简单的解决方案将永远胜过过度复杂的解决方案。有很多原因让我们这样做,当我们看到采用过度复杂算法所带来的问题时,这一原则可能会更容易理解:

      1、复杂的代码是错误的完美藏身之所。

      2、复杂的代码很难理解,对于你的同事和你自己。

      3、复杂的代码不容易被扩展。

      4、复杂的代码不能重复使用。而且,最后但并非最不重要的是,编写复杂的代码会导致你的队友对你产生怨念。

      但一个简单的解决方案就可以解决问题时,请使用它!

      当你意识到你的解决方案根本不需要时,你应该放弃它。用户是否真的需要这个功能?他们会在功能中使用这个选项吗?这些问题当然会转化为我们的代码:我们是否真的需要那个类/模块/例程?


      不断地重定义“边界案例”

                  

       这一点可能不适用于所有的应用程序。但随着Tower被全球超过80,000人使用,我们需要不断重新定义术语“边缘案例”。
      如果你的应用程序为庞大的用户群提供服务,那么在考虑人们如何使用它时,你将不可避免地需要进行更加彻底地思考。当用户数目为1000时很少发生的事情随着用户数目增大可能就会成为日常活动。
      因此 “边缘案例”对每个团队来说各不相同,每个团队都必须自己定义认为的边缘案例。另外,随着用户群的增长你们需要不断重新定义这个术语:当前的边缘案例可能会变得过于常见而不足以被称为边缘案例;并且可能会出现新的边缘案例。
      通过这种方式,你可以在编写原始实现时对这些案例进行优雅处理。这要比几个星期后去重新找到它要容易得多——当你对问题的记忆不再清晰时,以及无辜的小边缘案例不知何故变成了一个完整的错误时。

      编写好的API
      我确信在你的开发职业生涯中你一定使用过第三方API,例如,在你的CRM中创建新的联系人,通过时事通讯服务发送电子邮件,或通过第三方完成其他的任务。
      如果你已经使用过一些第三方的API,你肯定会注意到它们之间的一些区别:其中一些可能比另一些使用起来更加愉快。很容易注意到哪个API是由有经验的开发人员精心设计的。而使用以糟糕和不合理的方式设计的API会令人沮丧。
      大多数开发人认同我们应该以一种谨慎和深思熟虑的方式设计公共API,没有人希望使用糟糕的API进行工作 ——而且没有人愿意开发糟糕的API来加重使用者的工作量。
现代软件设计非常重视“应用程序编程接口”的概念。然而,正如大多数开发人员已经知道的那样,这个概念要深入许多,而不是专用于公共接口。相反,你应该在应用程序内部构建API,以供内部使用。
      以完全相同的方式开发这些内部API可以产生巨大的差异:你的同事(和你)将希望与你所开发的部分进行交互。尽可能简化这些人员的互动是你可以拥有的最佳目标之一。
      一个简单而周到的API可能是你的软件质量最重要的部分。你的同事可能会原谅你在这个或那个方法的内部所编写的凌乱的代码,但他们不会(也不应该)原谅你创建了一个糟糕的API。

      设计模式

           

      有时候,解决方案可能非常优美,你希望你有正确的问题来应用它。但不幸的是,问题总是先出现。如果这个解决方案不能解决你手头的问题,那么它就不再是完美的解决方案。

现在,让我们回到软件开发——设计模式视为你的工具箱。你了解(并理解)的每种设计模式都是你的工具, 拥有其中很多人真是太棒了!

      然而,当你开始使用设计模式编写代码时,问题就出现了。设计模式应该帮助你解决问题(能够使用该设计模式的问题),你应该在适合的地方使用,而不是强行套用。请记住,你应该根据你的应用需求设计你的程序 ,而不是采用美观的设计模式。

      只有当你使用了适合你当前问题的设计模式,它才会发挥应有的效果。此外,请确保你真正理解了该设计模式并清楚它对编码的影响。


      拥抱最佳实践

           

      很难找到尚未被其他人解决的编程问题。而且,世界各地的开发者每天都在无数次地重新造轮子。我想大多人应该尝试下面的一些做法:

      1、“我讨厌在我的项目中有400个第三方库。

      绝对可以理解,没有人会喜欢这样。问题是:当我谈论解决问题时,一个成熟的解决方案不一定要采取使用现成代码的形式。它也可能仅仅是一种概念,一种设计模式,或者只是与隔壁家伙讨论,你知道他已经解决过类似的问题。解决方案可以有多种形式,所以不要将自己局限于和其他形式的完整解决方案。

      2、“这只是一个小小的挑战,我很快就会有自己的解决方案。”

      每个有超过一天经验的开发者都学到了非常宝贵的经验:问题(几乎总是)比他们看起来更复杂。有经验的开发人员将会学到另一个教训:即使有了不断增长的经验,我们仍让无法准确评估出一个问题所包含的所有潜在复杂问题简而言之:我们倾向于低估一次又一次的问题。所有这些意味着我们应该彻底评估手头的问题是否真的必须由你自己解决。

      3、“我不喜欢现有的解决方案,我可以创造更好的东西。”

      这很可能是另一种低估形式。特别是如果一个解决方案已经存在一段时间并在许多项目中使用,你就应该仔细检查你对该解决方案的评估是否真正正确。再次,我们往往倾向于低估问题的复杂性,即使是最简单的问题也隐藏一定的复杂性。此外,如果我们谈论的解决方案是一种普遍认可的解决这样一个问题的方式(无论是在团队还是在技术平台上),那么在你走自己的路之前,你应该再三考虑,至少你应该做的是与你的队友讨论你的反对意见。

      所有这些 “最佳实践(经过验证的概念、惯例、模式和高质量的书籍)应始终是你的第一参考点。在仔细验证那些最佳实践不适合你的特殊情况后,你可以自由行事。


      流行驱动的开发

            

      只需一会儿,请想象我们会陷入八十年代:我们处在一个有着旋转手机,喇叭裤和可怕的理发的年代,多么令人不安的想法!但幸好世界已经发展:技术(和时尚)的进步使事情成为可能,而这在以前是不可能的。新技术使我们能够创造新事物。

      但是,“旧”技术呢? 那昨天创建的软件框架和库怎么样? 在许多领域,特别是在网络上,很容易得到这样的印象:框架越新,它就越好。上周创建的所有东西都是落后的,并且应该被抛弃。但是,一味地追随每一个新趋势,我们就没有精力改进我们已有的东西,并且无法保证代码的质量。

      质量需要时间。一款新开发的软件注定还不够完美,在它的内部不可避免的会存在缺陷以及需要大量时间和工作的bug。因此新鲜的技术并不总是最好的。

      质量需要协作。如果随着时间的推移,我们也寻求其他人的建议和反馈,我们就有机会来制作更好的软件。 请注意,这种意义上的协作可以有多种形式:如反馈和直接贡献,但也可以以使用和试用的形式出现,例如,在实际项目中使用新开发的库程序。

      质量从失败中增长。新事物还没有失败的机会。技术也不例外,软件在被视为成熟之前必须经过失败并得到改进。

      尽管潜心研究新技术很重要,但我们需要密切关注我们用来评估它的标准。 新奇不是令人兴奋的标准,但有用。 新技术需要为现有解决方案提供实际价值。

      在我们发现新事物的同时,我们不必将更老的、经过验证的技术丢掉。在购买下一个新东西之前,确保你了解旧技术和新技术。


      Stack-Overflow驱动的开发

              

      感谢StackOverflow.com。如果没有它,我真的无法想象我的(编程)生活。我和Stack Overflow之间有很长的友谊。当我陷入困境时,它帮助我无数次。这让我看到其他人如何解决同样的问题,有时候这些人帮我解决了我的问题。有时他们给了我一个可能的解决方案的提示,有时候阅读他们的问题,至少让我知道,我并不孤单。
      但是有时候你必须小心并且抵制看起来很好的代码的诱惑。你在Stack Overflow中找到的(除了极少数情况外)不是一种解决方案,而是一种线索。它当然可以成为一个伟大的指导,但它并没有写出你的确切问题/需求/约束/代码库/应用程序。有时候,它可能只是一个肮脏的黑客。拥抱Stack Overflow对某些问题的良好的指导。但也要花时间彻底和诚实地评估你是否找到了一个真正的,强健的解决方案。


      【英文原文】 https://www.git-tower.com/blog/dev-philosophy-1
      {测试窝原创译文,译者:初心}
      译者简介:初心,东南大学在读硕士研究生




欢迎给测试窝投稿或参与内容翻译工作,请邮件至editors@testwo.com。也欢迎大家通过新浪微博(@测试窝)或微信公众号(测试窝)关注我们,并与我们的编辑和其他窝友交流。
181°|1815 人阅读|0 条评论

登录 后发表评论
最新文章