不要过度设计

高扩展性网站的50条原则》第1章化简方程,本章如何把大的架构问题分拆成小问题,用较少的工作实现同样的结果。在很多案例中,该方法都减少了(而不是增加了)解决问题所必需的工作量,简化了架构和解决方案,最终得到了更具可扩展性的解决方案或平台。本节为大家介绍原则1:不要过度设计。

第1章 化简方程

在我们的学习或工作中,都曾遇到过这样的情况:死盯着一个复杂的问题不放,以至于最后丧失了希望。我们应该从何处入手?如何在预定的时间内解决问题?或者说得极端一些,如何在有生之年解决这个问题?要做的事情太多了,这个问题太过棘手,是不能解决的,事实如此,就此罢手吧。游戏结束了……

等等,不要丧失希望。深呼吸,想想你的高中或者大学数学老师。就像解数学题,把大方程化简成易于计算的小方程一样,如果你遇到的是棘手的大型架构问题,那么可以把大问题分拆成小问题,把小问题分拆成更小的问题,直到这些问题可以轻易解决为止。

我们的观点是,任何大问题,只要分拆方法正确,都不过是一系列有待解决的小问题的集合。这一章介绍的就是如何把大的架构问题分拆成小问题,用较少的工作实现同样的结果。在很多案例中,该方法都减少了(而不是增加了)解决问题所必需的工作量,简化了架构和解决方案,最终得到了更具可扩展性的解决方案或平台。

本书各章所介绍的原则篇幅不一,复杂度也不同。有些普适的原则,适用于一个设计的多个方面。而有些原则只适合特定系统。

1.1 原则1:不要过度设计

目的:防止设计中出现复杂的解决方案。

适用情形:适用于任何项目,所有大型的或复杂的系统和项目都应该采用该原则。

应用方式:让同行来检查解决方案是否好理解,抵制过度设计的强烈欲望。

应用理由:复杂的解决方案实施成本高,而且会产生大量长期成本。

要点:过度复杂的系统会限制扩展能力。简单的系统更容易维护和扩展,且成本更低。

维基百科解释说,过度设计分为两大类[1]。一类是指设计与实现超出了有用需求的产品。出于完整性的考虑,我们只简单地讨论一下这个问题。相对于第二类问题来说,这类问题对可扩展性的影响较小。过度设计的另一类问题指过于复杂的产品。如前所述,我们最关心的是第二类问题对可扩展性的影响。不过,还是先来了解一下第一个问题吧。

要解释过度设计的第一类问题,即超出产品有用需求的问题,就要先搞清楚"有用的"这个术语的含义,这个术语在这里表示的只是"能够使用"。例如,为家庭住房设计一种空调,能够在室外温度为0开时把整个房子的温度加热到300华氏度,这毫无意义,纯属浪费,我们只需要一个能够在室外温度为 20华氏度时把房子加热到舒适温度的产品。这种过度设计会产生过度的成本,其中开发的成本会更高,实施该方案的硬件和软件成本也会更高。如果研发这种过度设计系统的时间比研发有用系统的时间更长,还可能拖延产品的发布,对公司造成进一步的影响。成本高,利润就低。研发时间长,收入或收益就会被延迟,所有这些成本都会影响到利益相关者。范围蔓延,或者最初的产品定义和最初的产品发布之间的范围差异,是过度设计的一种表现。

说个更接近我们工作的例子,是开发一个员工打卡系统,这个系统能够处理的员工数量是整个地球上人数的100倍。在这个软件的使用期限内,地球上的人口升至100倍的可能性是微乎其微的,而所有人都为一家公司工作的可能性则更小。我们当然想让构建的系统满足客户需求,但也不想浪费时间来实现和部署远远超出需求的系统。

过度设计的第二类表现是使系统过度复杂,或者用复杂的方式来实现它。简而言之,就是要花费过大的力气去完成一项工作,或者是让用户花费过大的力气去完成一项任务,或者是让程序员花费过大的力气去理解一个功能。让我们来逐一分析过度复杂的系统的这三种情况。

什么是花费过大的力气去完成一项工作呢?现实世界有最简单的例子。假设你让某人去杂货店买东西,你告诉他,店里面的所有商品都拿一个,排队结账时给你打电话。等他打电话给你时,你再告诉他到底想要哪几个,让他从所拿的无数篮商品中选出来,然后把其他商品都倒在地上。你一定会说:"别开玩笑了。"可是,你在自己的代码中用过select (*) schema_name.table_name这样的SQL语句,只是为了从返回的集合中找出自己想要的结果吗(参见原则35)?我们这个杂货店的例子,和上述的select(*)正是异曲同工。在你的代码中,有几个条件语句是处理个别情况的,它们是按照什么顺序执行的?是不是最可能发生的情况最先执行?你是不是经常刚查询完一个结果,又重复查询一次?是不是经常刚显示了一个HTML页面,又重新创建它?这种情况(反复做一项工作)随处可见,却又经常被忽视,我们将专门用一章(第6章)来讨论这个主题。

什么是让一位用户花费过大的力气去完成一项任务呢?答案非常简单。在许多情况下,少就是多。为追求系统的灵活性,我们总是想给它硬加上尽可能多的奇怪功能。但生活的情趣并不总在于多种多样。许多时候,用户只是想无干扰地尽可能快地从A到达B。如果你的市场中有99%的用户不需要把日志文件存成.pdf文件,那么就不要构建一个提示框询问他们是否想把日志文件保存成.pdf文件。如果你的用户想把.wav文件转换成MP3文件,那么他们已经不在乎损失精度了,所以不必再提示他们转换成无损压缩的FLAC文件,那样只会干扰他们。

最后一种情况,就是软件复杂得让其他程序员难以理解。创建复杂的代码让他人难以理解曾经非常流行(还有过比赛)。有时,代码写得复杂,是为了让它比一般程序员所开发的代码运行更快。而更多的情况是,代码的复杂度(就其理解的难度而言)成了程序员才华的象征,或者说是功夫高低的象征。那些开发的代码能让做代码检查的高级开发人员欲苦无泪的人反而颇受推崇。复杂度成了智慧的牢笼,编程极客们会在公司内部争强好胜。对于乐此不疲的人来说,这是很好的比赛,但对于公司和股东来说,则要为一场无人关心的牢笼大赛买单。对于那些仍然沉浸于这场极客盛宴的人,如果不想损害利益相关者的利益,又想真刀真枪地拼一场,那建议你参加国际混淆C代码竞赛,网址是www0.us.ioccc.org/ main.html。

我们都应该努力去写让每个人都能理解的代码。衡量一个伟大程序员的真正标准,是他能够多快把一个复杂的问题简化(见原则3),多快能开发出一个既容易理解,又容易维护的解决方案。容易执行的解决方案意味着一般程序员就可以快速地掌握系统,为它提供支持。容易理解的解决方案则意味着在查找问题时能够更快地发现问题,从而以更快的方式把系统恢复到正常工作状态。容易执行的解决方案可以提高公司和解决方案的可扩展性。

要测试系统是否太复杂,一个很好的方法是让负责解决复杂问题的程序员把他的解决方案陈述给公司内的一组程序员。这组程序员应该代表公司内不同的编码水平,不同的工作年限(加入这一条,是因为可能有些有经验的程序员在公司的工作经验不多)。要通过这一测试,需要这组程序员中的每一位都能够轻松理解该解决方案,能够在无帮助的情况下向他人描述它,而不只是知道它。如果这组程序员中的任何一位不能理解该解决方案,那么就要小组讨论该系统是不是过度复杂了。

过度设计是可扩展性的一个敌人。开发一个超出有用需求的解决方案,既浪费金钱又浪费时间。此外,还可能进一步浪费处理资源,增加扩展成本,限制系统的整体扩展能力(即系统能被扩展到什么程度)。构建过度复杂的解决方案会造成类似的后果。运行吃力的系统会增加成本,限制最终发展规模。让用户用起来吃力的系统,会放慢吸引客户的速度,从而限制业务增长的速度。太复杂以至于难以理解的系统,则会扼制公司的生产力,让你无从增加程序员,或者难以给系统增加功能。

原文出自:http://book.51cto.com/art/201206/342544.htm

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值