`
java-mans
  • 浏览: 11435454 次
文章分类
社区版块
存档分类
最新评论

不要过度设计

 
阅读更多

高扩展性网站的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

分享到:
评论

相关推荐

    DesignPatternDemo:这是用于的示例代码

    关注点分离将相关数据和行为保持在一起信息隐藏内聚力好,耦合差程序到接口,而不是实现封装变化的隐藏你的决定进行稳定的抽象使您的系统打开以进行扩展,但关闭以进行修改不要过度设计您的解决方案如果可以改变,...

    机械设计课程设计减速器答辩问题汇总

    1.在传动系统总体设计中电机的型号是如何确定的?...不要太靠近轴肩处,以避免由于键槽加重过度圆角处的应力集中。应靠近轮毂装入 侧轴端端部,以利于装配时轮毂的键槽容易对准轴上的键槽。采用盘铣刀加工。

    软件开发培训之如何理解设计模式

    □ 设计模式解决的是设计不足的问题,但同时也要避免设计过度。一定要牢记简洁原则,要知道设计模式是为了使设计简单,而不是更复杂。如果引入设计模式使得设计变得复杂,只能说我们把简单问题复杂化了,问题本身不...

    Java 设计模式详解超详细(含示例代码)

    Java设计模式是软件开发中常见问题的标准解决方案,它们是经过时间考验和实践证明的有效设计方法。设计模式的目标是提高代码的可重用性、...同时,要注意不要过度使用设计模式,只在必要的时候使用它们来解决实际问题。

    基于新型界面的思政多媒体教学软件的设计研究

    随着思政教学越来越受到人们的重视,其也成为了教学课程...文中基于新型界面的思政多媒体教学软件的设计研究,在总结了常规多媒体教学软件的基础上,提升并优化了软件的界面,凸显了人机交互这一优势,达到了设计要求。

    樱花知识领域: 植物学, 日本文化,园艺 技术关键词: HTML, CSS, JavaScript, 网页设计, 网页开发 内容

    在使用樱花作为HTML的背景或装饰元素时,需要注意不要过度使用,以免影响页面的可读性和用户体验。此外,樱花效果可以通过CSS动画或JavaScript来实现,具体实现方式可以根据个人的需求和技术能力进行选择。 樱花的...

    Java开发常见问题总结.docx

    不要过度使用try-catch,应尽量抛出业务异常给上层处理。 使用finally块进行资源清理。 并发编程: 使用synchronized关键字或Lock接口进行同步控制。 利用ExecutorService进行多线程任务管理。 注意volatile关键字...

    围棋对弈小程序

    使用需要进行拆包,直接放到自己文件运行的workspase文件夹内就可以,适用于所有初学者,建议不要过度依赖,土豪随意。

    ppt模板精选(产品推广/行政文化/毕业答辩/项目策划/工作总结)

    考虑使用动画效果和过渡效果,但不要过度使用,以免分散观众注意力。 3.多样的版式和布局: 提供多种版式和布局选项,以适应不同内容类型的展示需求。 包括适用于项目介绍、数据分析、市场趋势、竞争对手分析等的...

    基于单片机的超速报警器电路设计.doc

    因此本设计就是使驾驶员起到重视 速度问题,并且及时监督提醒作用驾驶员不要超速。 由此,我觉得开发一个超速报警系统是很有必要的,对于驾驶员及其家人的生命财产 安全有重大意义,可以降低交通事故发生率。课题:...

    ORACLE9i_优化设计与系统调整

    §5.1.3 过度请求的影响 83 §5.1.4 调整以解决问题 83 §5.2 优化的执行者 84 §5.3 设置性能目标 84 第7章 系统优化方法 85 §6.1 何时优化效率最高 85 §6.1.1 系统设计阶段和开发阶段的优化 85 §6.1.2 改善产品...

    WinXP绿眼保护模式设置工具

    经常面对电脑会导致眼睛过度疲劳,白色对眼睛的刺激是最大的,所以,最好不要用白色做电脑背景色。因此,我特意编写这个软件,很容易修改系统资源管理器背景色,还有IE背景色。 我个人建议:修改资源管理器背景色就...

    从新手到大神:如何制作优秀的毕业论文答辩 PPT?.docx

    但要注意不要过度使用,以免分散观众的注意力。 练习演讲和掌握内容:在制作完PPT之后,要进行多次的演练,确保自己熟悉内容并能流利地演讲。同时,要准备好回答可能出现的问题,展现出对论文内容的深刻理解和掌握...

    .net core 3.1 WepApi 前后分离身份验证及webapi调试demo ,jwt+swagger

    所以在设计时候需要注意不要在JWT中存储太多的claim,以避免发生巨大的,过度膨胀的请求。 无法作废已颁布的令牌 所有的认证信息都在JWT中,由于在服务端没有状态,即使你知道了某个JWT被盗取了,你也没有办法将其...

    Pre-Work-Part-1

    电传打字前工作-第1部分 ...在stylesheet.css文件的注释中可以找到有关...尽量不要过度使用div元素,id属性或!important。您将有24小时完成此作业。成功完成此部分后,我们将与您联系以安排时间进行电传采访的第二部分。

    总结c++性能优化策略

    不可否认良好的抽象设计可以让程序更清晰,代码更看起来更好,但是她也是有损失的,在继承体系中子类的创建会调用父类的构造函数,销毁时会调用父类的析构函数,这种消耗会随着继承的深度直线上升,所以不要过度的...

    Modificator-crx插件

    语言:русский 修饰应用程序 这个插件是针对Prankiv(绘图)的朋友和熟人设计!...重要:不要过度吧!!!!!!重要提示:在绘画结束时,告诉我它仍然是一个抽奖!!!!重要提示:查看视频如何使用插件!!!

    pri_at_morse:一个使用@协议的P2P Flutter聊天应用

    这个概念出现在我的脑海中,思考如何保护隐私(但不要过度)。 该应用程序使用“ @公司”设计的@protocol在服务器级别提供隐私。 而且,它还通过将文本转换为Morse code在应用程序级别(前端)中提供,只需单击按钮...

    SOLID-Principles

    •确保不要过度简化代码,因为稍后您可能必须放置一堆依赖关系,这会使代码不可读和令人困惑。 •问问自己:班级的职责是什么? 如果您的答案中包含“和”一词,则很可能违反了单一责任原则。 开/关原则- •促进...

    Java面试宝典和大学生面试宝典

    淡看智力测试 之所以要强调这一点,是和市面上过度强调外企智力测试有关。实 际上笔者参加过的微软等外企笔试,智力测试只占很小的比例,约 3%~ 14 在3 种考试中 5%左右。而华为、神州数码等国内 IT 企业基本上...

Global site tag (gtag.js) - Google Analytics