1。过度设计有意义吗?看着自己每次都基于设计原则和模式重构代码,虽然效果不错,但我也在反省:如果我的每一段代码都这样写,是不是设计过度了?掌握设计的程度需要很长时间。业界也总结出很多原则来帮助我们把握设计的度。它们是一种思维方式,一种行为准则。2.KISS保持简单,愚蠢,保持简单,愚蠢。提醒我们,大多数系统保持简单比复杂化效果更好。越是有经验的人,就越觉得这是有道理的。因为大佬们见识过复杂性带来的各种问题。如果函数太多,调整起来会很费力:?如果你有现成的库,不要自己写?如果你可以使用文本作为协议,就不要使用二进制?越短的方法,越多越好?如果你能通过一个基本流程,就可以发布软件没有那么多功能(MVP)确实对crudboy很有吸引力,但不能指导具体的工作。保持简单是什么意思,为什么叫复杂?这些都不是标准的。有的人根据自己的理解给出了具体的原则:3.YAGNIYouaren'tgonnaneedit,youdon'tneedit.除非必要,否则不要添加功能。软件设计反对的是需求规模:?通过努力,软件在需求规模扩大后仍能稳定发展?尽量控制需求规模。许多要求不需要完成。许多产品经理认为重要的功能实际上没有用。真正重要的特征只占20%左右。如果您执行更多功能,您将不会获得更多奖励。但是,如果你做的功能多了,软件本身就会不断膨胀,变得更难维护。所以,在现实中,我们经常会看到一些功能简单的东西,颠覆了更复杂的东西。比如Word虽然功能强大,但它只是一个书写工具,关键的排版功能很少用到。而Markdown只是简单的让我们专注于书写内容,日常交流中几个简单的排版标记就完全足够了。不该做的尽量不要做,从源头上杜绝问题。4.DRY不要重复自己,不要重复自己。在一个系统中,每条知识都必须有一个单一的、明确的、权威的表示。每一条知识都必须在系统中有一个单一的、明确的、权威的表示。也就是说,不要成为简历工程师。这还不够,DRY针对的是你的知识和意图的重复:两个东西在两个不同的地方有不同的表达方式,但表达内容可能是一样的。打印账户信息如下:publicvoidprintBalance(finalAccountaccount){System.out.printf("Debits:%10.2f\n",account.getDebits());System.out.printf("积分:%10.2f\n",account.getCredits());if(account.getFees()<0){System.out.printf("费用:%10.2f-\n",-account.getFees());}else{System.out.printf("费用:%10.2f\n",account.getFees());}System.out.printf("----\n");if(account.getBalance()<0){System.out.printf("余额:%10.2f-\n",-account.getBalance());}else{System.out.printf("余额:%10.2f\n",account.getBalance());}}这一段隐藏了一些重复。如果对负数的处理明显重复,可以通过增加一个方法来消除:StringformatValue(finaldoublevalue){Stringresult=String.format("%10.2f",Math.abs(value));if(value<0){返回结果+"-";}else{返回结果+"";}}voidprintBalance(finalAccountaccount){System.out.printf("Debits:%10.2f\n",account.getDebits());System.out.printf("积分:%10.2f\n",account.getCredits());System.out.printf("费用:%s\n",formatValue(account.getFees()));System.out.printf("----\n");System.out.printf("Balance:%s\n",formatValue(account.getBalance()));}数字字段格式重复,但是,格式和我们提取的方法一致,复用:StringformatValue(finaldoublevalue){Stringresult=String.format("%10.2f",Math.abs(value));if(value<0){返回结果+"-";}else{返回结果+"";}}voidprintBalance(finalAccountaccount){System.out.printf("Debits:%s\n",formatValue(account.getDebits()));System.out.printf("Credits:%s\n",formatValue(account.getCredits()));系统.out.printf("费用:%s\n",formatValue(account.getFees()));System.out.printf("----\n");System.out.printf("Balance:%s\n",formatValue(account.getBalance()));}打印格式其实是重复的。如果我要在label和amount之间加一个空格,相关的代码就要改,所以这也是可以去掉的重复:StringformatValue(finaldoublevalue){Stringresult=String.format("%10.2f",Math.abs(value));if(value<0){返回结果+"-";}else{返回结果+"";}}voidprintLine(finalStringlabel,finalStringvalue){System.out.printf("%-9s%s\n",label,value);}voidreportLine(finalStringlabel,finaldoublevalue){printLine(label+":",formatValue(value));}voidprintBalance(finalAccountaccount){reportLine("Debits",account.getDebits());reportLine("Credits",account.getCredits());reportLine("费用",account.getFees());System.out.printf("----\n");reportLine("Balance",account.getBalance());}重构后:更改金额打印格式,只需更改formatValue?更改标签格式,然后更改reportLine有人说这个调整的粒度太小了。如果你有这种感觉,就证明你的问题粒度太大了。细细品味这种修改,它与关注点分离和单一职责原则具有相同的效果:粒度要小。DRY不局限于写代码:?注释和代码之间存在重复,可以尝试把代码写得更清晰?内部API在不同用户之间存在重复,API可以定义成中性的格式,然后用toolsDocumentation,mockAPI等,开发者之间存在重复,可以建立沟通机制减少重复;...都在努力减少重复,这实际上降低了维护成本。5.SimpleDesignSimpleDesign由KentBeck提出,只包括以下规则,最后三个规则是重构的方向(1)通过所有测试,确保系统能够按预期工作。如何知道系统是否按预期运行,需要有配套的自动化测试,最好能TDD,最根本的是理解设计,否则,你的代码将无法测试。(2)消除重复就像DRY一样,你要能找到重复,你要分离关注点(3)表达程序员写表达性代码的意图,这也需要你了解“什么是表达性代码”知道。代码说的是做什么,而不是怎么做(4)Minimizethenumberofclassesandmethods尽量减少类和方法的数量,不要过度设计,除非你看得出来这是必须要设计的,比如离开适当的扩展点,否则,不要做。能够进行过度设计的前提是了解各种设计。只有这样,你才需要用简单设计的标准来约束自己。所谓简单的设计,对于大多数人来说并不“简单”。没有好的设计,代码就没有可测试的接口,TDD就无从谈起。如果不懂设计,重构只是一种简单的抽取方式,改个名字,对代码的提升是相当有限的。简单设计的前提是为编程打下坚实的基础。片面追求敏捷练习,而忽视基本功,就是追尾。
