java代码整洁之道
java整洁之道,有助于我们写出更为精炼的代码44.17函数头664418非公共代码中的Javadoc¨664.4.19范例¨664.5文献69第5章格式5.1格式的目的……25.2垂直格式“7252.1向报纸学习735.2.2概念间垂直方向上的区隔735.2.3垂直方向上的靠近¨145.24垂直距离755.2.5垂直顺序795.3横向格式¨795.3.1水平方向上的区隔与靠近¨8053.2水平对齐815.3.3缩进¨825.3.4空范围…8454团队规则¨845.5鲍勃大叔的格式规则85第6章对象和数据结构¨876.1数据抽象¨876.2数据、对象的反对称性¨896.3得墨忒耳律9163.1火车失事916.3.2混杂¨926.3.3隐藏结构926.4数据传送对象¨936.5小结6.6文献∵第7章错误处理¨957.1使用异常而非返回码¨¨¨967.2先写 Try-Catch-Fnay语句¨977.3使用不可控异常987.4给出异常发生的环境说明¨¨7.5依调用者需要定义异常类¨………997.6定乂常规流程¨1007.7别返回nu值¨1017.8别传递nu值¨1027.9小结¨1037.10文献104第8章边界¨1058.1使用第三方代码1068.2浏览和学习边界10783学习og410884学习性测试的好处不只是免费1108.5使用尚不存在的代码1108.6整洁的边界1118.7文献112第9章单元测试1139.1TDD三定律…1149.2保持测试整洁¨11593整洁的测试……1169.3.1面向特定领域的测试语言¨1189.3.2双重标准11994每个测试一个断言1219.5 FIRS,T1229.6小结¨239.7文献124第10章类¨12510.1类的组织……126102类应该短小…12610.21单一权责原则12810.2.2内聚12910.2.3保持内聚性就会得到许多短小的类130103为了修改而组织136104文献…139第11章系统¨14111.1如何建造一个城市14211.2将系统的构造与使用分开11.2.1分解main14311.2.2工厂¨14311.2.3依赖注入14411.3扩容¨145114Java代理14811.5纯 Java AoP框架150116 AspectJ的方面15211.7测试驱动系统架构15311.8优化决策¨¨154119明智使用添加了可论证价值的标准¨15411.10系统需要领域特定语言1541111小结15511.12文献¨155第12章迭进…5712.1通过迭进设计达到整洁目的¨15712.2简单设计规则1:运行所有测试¨¨15812.3简单设计规则2~4:重构¨…58124不可重复12.5表达力161126尽可能少的类和方法16212.7小结162128文献¨162第13章并发编程16313.1为什么要并发16413.2挑战¨16513.3并发防御原则16613.31单一权责原则16613.32推论:限制数据作用域¨16613.33推论:使用数据复本¨16713.34推论:线程应尽可能地独立167134了解Java库…16713.5了解执行模型16813.5.1生产者-消费者模型…16913.5.2读者-作者模型691353宴席哲学家16913.6警惕同步方法之间的依赖¨¨¨16913.7保持同步区域微小17013.8很难编写正确的关闭代码¨¨170139测试线程代码1711391将伪失败看作可能的线程问题1711392先使非线程代码可工作¨17113.93编写可插拔的线程代码¨1721394编写可调整的线程代码¨17213.9.5运行多于处理器数量的线程1721396在不同平台上运行¨17213.97装置试错代码17313.98硬编码17313.99自动化17413.10小结¨17513.11文献¨175第14章逐步改进176141Args的实现¨177142Args:草稿¨¨18314.2.1所以我暂停了¨…9514.2.2渐进¨19514.3字符串参数…197144小结……234第15章 JUnit内幕235151υUnt框架¨236152小结249第16章重构 SerialDate25116.1首先,让它能工作252162让它做对254163小结…266164文献¨267第17章味道与启发…269171注释¨27017.2环境¨27117.3函数¨27117.4一般性问题¨27217,5java¨¨¨¨28817.6名称291177测试…2417.8小结¨29517.9文献¨96附录A并发编程Ir¨297A1客户端/服务器的例子297A.1.1服务器“297A.1.2添加线程代码298A.13观察服务器端299A.14小结…301A.2执行的可能路径301A.2.1路径数量¨302A.2.2深入挖掘303A.23小结……305A3了解类库305A3.1 Executor框架305A32非锁定的解决方案306A33非线程安全类307A4方法之间的依赖可能破坏并发代码¨308A4.1容忍错误309A4.2基于客户代码的锁定…309A4.3基于服务端的锁定¨311A.5提升吞吐量…312A51单线程条件下的吞吐量¨313A5.2多线程条件下的吞吐量¨313A.6死锁…314A.61互斥…315A.6.2上锁及等待315A.6.3无抢先机制315A.6.4循环等待…¨315A.65不互斥“316A.6.6不上锁及等待316A.6.7满足抢先机制317A.6.8不做循环等待317A7测试多线程代码317A.8测试线程代码的工具支持320A9小结…320A.10教程:完整代码范例321A10.1客户端/服务器线程代码321A.102使用线程的客户端/服务器代码324附录 B org jfree date Seria dat327结束语389l阅读本书有两种原因:第一,你是个程序员;第二,你想成为更好的程序员。很好。我们需要更好的程序员这是本有关编写好程序的书。它充斥着代码。我们要从各个方向来考察这些代码。从顶向下,从底往上,从里而外。读完后,就能知道许多关于代码的事了。而且,我们还能说出好代码和糟糕的代码之间的差异。我们将了解到如何写出好代码。我们也会知道,如何将糟糕的代码改成好代码。11要有代码有人也许会以为,关于代码的书有点儿落后于时代一代码不再是问题;我们应当关注模型和需求。确实,有人说过我们正在临近代码的终结点。很快,代码就会自动产生出来,不需要再人工编写。程序员完全没用了,因为商务人士可以从规约直接生成程序。扯淡!我们永远抛不掉代码,因为代码呈现了需求的细节。在某些层面上,这些细节无法被忽略或抽象,必须明确之。将需求明确到机器可以执行的细节程度,就是编程要做的事。而这种规约正是代码我期望语言的抽象程度继续提升。我也期望领域特定语言的数量继续増加。那会是好事一桩。但那终结不了代码。实际上,在较髙层次上用领域特定语言撰写的规约也将是代码!它也得严谨、精确、规范和详细,好让机器理解和执行那帮以为代码终将消失的伙计,就像是巴望着发现一种无规范数学的数学家们一般。他们巴望着,总有一天能创造出某种机器,我们只要想想、嘴都不用张就能叫它依计行事。那机器要能透彻理解我们,只有这样,它才能把含糊不清的需求翻译为可完美执行的程序,精确满足需求。这种事永远不会发生。即便是人类,倾其全部的直觉和创造力,也造不出满足客户模糊感觉的成功系统来。如果说需求规约原则教给了我们什么,那就是归置良好的需求就像代码一样正式,也能作为代码的可执行测试来使用记住,代码确然是我们最终用来表达需求的那种语言。我们可以创造各种与需求接近的语言我们可以创造帮助把需求解析和汇整为正式结构的各种工具。然而,我们永远无法抛弃必要的精确性一所以代码永存12糟糕的代码最近我在读 Kent beck著 Implementation Patterns(中译版《实现模式》)一书的序言。他这样写道本书基于一种不太牢靠的前提:好代码的确重要……”这前提不牢靠?我反对!我认为这是该领域最强固、最受支持、最被强调的前提了(我想Kent也知道)。我们知道好代码重要,是因为其短缺实在困扰了我们太久。20世纪80年代末,有家公司写了个很流行的杀手应用,许多专业人士都买来用。然后发布周期开始拉长。缺陷总是不能修复。装载时间越来越久,崩溃的几率也越来越大。至今我还记得自己在某天沮丧地关掉那个程序,从此再不用它。在那之后不久,该公司就关门大吉了。20年后,我见到那家公司的一位早期雇员,问他当年发生了什么事。他的回答叫我愈发恐惧起来。原来,当时他们赶着推出产品,代码写得乱七八糟。特性越加越多,代码也越来越烂,最后再也没法管理这些代码了。是糟糕的代码毁了这家公司。你是否曾为糟糕的代码所深深困扰?如果你是位有点儿经验的程序员,定然多次遇到过这类困境。我们有专用来形容这事的词:沼泽( wading)。我们趟过代码的水域。我们穿过灌木密布、瀑布暗藏的沼泽地。我们拼命想找到岀路,期望有点什么线索能启发我们到底发生了什么事;但目光所及,只是越来越多死气沉沉的代码你当然曾为糟糕的代码所困扰过。那么一为什么要写糟糕的代码呢?是想快点完成吗?是要赶时间吗?有可能。或许你觉得自己要干好所需的时间不够;假使花时间清理代码,老板就会大发雷霆。或许你只是不耐烦再搞这套程序,期望早点结束。或许你看了看自己承诺要做的其他事,意识到得赶紧弄完手上的东西,好接着做下一件工作。这种事我们都干我们都曾经瞟一眼自己亲手造成的混乱,决定弃之而不顾,走向新一天。我们都曾经看到自己的烂程序居然能运行,然后断言能运行的烂程序总比什么都没有强。我们都曾经说过有朝一日再回头清理。当然,在那些日子里,我们都没听过勒布朗( Leblanc)法则:稍后等于永不(Later equals never)。13混乱的代价只要你干过两三年编程,就有可能曾被某人的糟糕的代码绊倒过。如果你编程不止两三年,也有可能被这种代码拖过后腿。进度延缓的程度会很严重。有些团队在项目初期进展迅速,但有那么一两年的时间却慢如蜗行。对代码的每次修改都影响到其他两三处代码。修改无小事。每次添加或修改代码,都得对那堆扭纹柴了然于心,这样才能往上扔更多的扭纹柴。这团乱麻越来越大,再也无法理清,最后束手无策。随着混乱的増加,团队生产力也持续下降,趋向于零。当生产力下降时,管理层就只有一件事可做了:增加更多人手到项目中,期望提升生产力。可是新人并不熟悉系统的设计。他们搞不清楚什么样的修改符合设计意图,什么样的修改违背设计意图。而且,他们以及团队中的其他人都背负着提升生产力的可怕压力。于是,他们制造更多的混乱,驱动生产力向零那端不断下降006时间图1-1生产力vs时间131华丽新设计最后,开发团队造反了,他们告诉管理层,再也无法在这令人生厌的代码基础上做开发。他们要求做全新的设计。管理层不愿意投入资源完仝重启炉灶,但他们也不能否认生产力低得可怕。他们只好同意开发者的要求,授权去做一套看上去很美的华丽新设计。于是就组建了一支新军。谁都想加入这个团队,因为它是张白纸。他们可以重新来过,搞出点真正漂亮的东西来。但只有最优秀、最聪明的家伙被选中。其余人等则继续维护现有系统。现在有两支队伍在竞赛了。新团队必须搭建一套新系统,要能实现旧系统的所有功能。另外,还得跟上对旧系统的持续改动。在新系统功能足以抗衡旧系统之前,管理层不会替换掉旧系统。竞赛可能会持续极长时间。我就见过延续了十年之久的。到了完成的时候,新团队的老成员早已不知去向,而现有成员则要求重新设计一套新系统,因为这套系统太烂了假使你经历过哪怕是一小段我谈到的这种事,那么你一定知道,花时间保持代码整洁不但有关效率,还有关生存。132态度你是否遇到过某种严重到要花数个星期来做本来只需数小时即可完成的事的混乱状况?你是
用户评论