读书笔记_软件框架设计的艺术

总结:

好吧,不得不承认,现在的我看架构还早了一点,很多东西看过去毫无感觉,硬着头皮看完了……哪怕是NetBeans大佬写的书。大概是代码写得不够多,也没有涉及这方面工作的经历,所以感觉对现在的我没什么帮助。也罢,先不看架构类的书了,不如看看设计模式,看看源代码,搞搞框架的应用吧。

前言

只要API有可能被误用,就一定会有人去误用这个API。
API就如同恒星,一旦出现,便与我们永恒共存。
编写API库需要开发人员放眼未来,看到今后潜在的需求。
API一旦发布便与我们永恒共存。

第一部分 理论与理由

第1章 软件开发的艺术

无绪:不需要深入了解就使用,像我们现在使用的框架之类的,浅层理解,看电视不需要理解电视机原理,只要会用就行了。
针对性无绪:有些内容需要深入理解,大部分不需要。

第2章 设计API的动力之源

改进现有的系统设计技能,是一种“无绪”利益最大化的有效途径。
分布式开发;模块化应用程序;
并非所有项目的质量都要高得像API。特别是开发的应用程序是给最终用户使用时,应用部署完之后不会有太大的变化。本书中的各种原则,更适用于系统种那些关键的可复用组件。
经验主义编程方式:很少有人能够以合理的方式来分析一个新API,没有人在学习使用一个API的时候,尽力去理解该API背后的设计思路。不需要花费大量时间来思考、学习和理解相应的内容,开发人员秀可以通过哪个是调用API的某个方法来测试会否可以完成目的,如果测试结果正确,开发人员就会很开心,如果测试结果不正确,开发人员就会需调用别的方法,这种方式NetBeans称其为经验主义编程方式(先用一个API做个实验,如果不成功就试一下别的,经验第一,然后才是深入了解。不过有时候并不需要深入了解)。这就对API的结构提出了要求,API必须是自描述的,即用户不需要任何文档就可以正确使用该API。
返回值不能为空:虽然可以用obj!=null来避免NullPointerException,但是这样会使代码凌乱且难以阅读,建议除非声明可以为null否则绝不返回null。
开发第一个版本通常比较容易。问题往往来自于后续版本。要对一个API加以改变并加入一些新功能,但同时还不能影响原来的功能,这是一门精妙的艺术。既要考虑原有API被使用的所有方式,又要保证这些用法适用于新版本,这太困难了。
如果在设计API的时候就考虑到未来改进,而预留出相应的空间,那么即使出现升级的情况,也不会给其他用户添加额外的工作。

第3章 评价API好坏的标准

源代码地址:http://source.apidesign.org
API不仅是类和方法以及javadoc。
方法和字段签名(反射);文件及其内容(格式);环境变量和命令行选项;文件信息也是API;协议(针对文本内容的API);行为(组件对外行为也是一种API);国际化支持和信息国际化(ResourceBundle)(不允许移除键值或重命名键值)。
每个协议建立连接时,即使这个协议只是在本地系统上用于内部交互,第一件要做的事就是一个握手协议,明确一些关键信息。
API的广泛定义:不仅是类、方法、函数和签名这些东西,从简单的文本信息到那些复杂或者很难控制的组件行为,都可以算是API。
想要设计一个易于理解的API,对用户的知识和技巧猜测准确也属于一种颇具技术含量的方法。
一致性;可见性;简单的任务应该有简单的方案;保护投资;

第4章 不断变化的目标

判断一个API是否优秀,并不是简单根据第一版给出判断的,而是要看多年后改API是否还能存在是否仍旧保持得不错。
向后兼容。源代码兼容,不必花费过多的精力去做到绝对的源代码兼容,因为非常困难。二进制兼容,不需要重新编译就能和新版类库连接。功能兼容,阿米巴变形虫效应,功能的具体实现可能与其预期差别很大。
无绪定义:集中多个模块构建一个程序时,无须深入了解每一个模块。
面向用例的重要性。
API设计评审;唯一架构师的方式会受到规模的限制。用例驱动的API设计,API设计的一致性,简单明了的API,少即是多,支持改进。
一个API的生命周期:开发版,稳定版。
开发人员走捷径使用非正式API或其他手段,会增大软件熵,代码变乱,结构框架也变乱。

第二部分 设计实战

结合设计模式来设计API。

第5章 只公开你要公开的内容

API公开的内容越少越好。
通过编码技巧提高代码的可读性。
经验告诉我们:对于API设计者来说,其水平越差,他所编写的API越会公开大量不必要的内容。(往往是由于对用例的理解不足)
一切都以最终用户为中心,但要逐步来满足他们的需求。
方法优于字段。
工厂方法优于构造方法。(可返回子类,不一定每次都创建实例,利于同步控制,利用泛型可支持参数化的返回类型)
让所有内容都不可更改。
避免滥用setter方法。
尽可能通过友元的方式来公开功能。(同一个package内)不要在API中公开那些外部不应该调用的方法。
避免暴露深层次继承。

第6章 面向接口而非实现进行编程

接口多继承可以减少对内存的占用。
向现有接口中添加方法总是不太容易(兼容难而且代码会变复杂),final类是可以添加新方法的。
要为增加新参数做好准备。

第7章 模块化架构

按照逻辑功能进行功能分解,避免在逻辑模块间交叉引用产生依赖关系。
模块化架构将规范与具体实现分离,分别放置在不同的模块中;可以定义一个模块专用于放置规范,即其文档涵盖实际的接口抽象类等;需要实现规范的开发商可能会提供一个或多个单独的模块,用来实现具体的功能;这类设计通常有一个共同点就是:在规范所在的模块中,至少会有一个小的“入口点”,比如构造函数或者静态工厂方法,这样客户端代码就可以通过这样的入口获取具体的实现内容。
组件定位和交互。
通用的注册方式。(属性,XML等)
Spring和Lookup机制。
编写扩展点。
循环依赖的必要性。
Lookup的滥用。

第8章 设计API时要区分其目标用户群

合理分解API

第9章 牢记可测试性

第10章 与其他API协作

谨慎使用第三方API。
如果需要去读一个API的源代码,那么其设计上一定存在问题。

第11章 API具体运行时的一些内容

同步和死锁。

第12章 声明式编程

第三部分 日常生活

第13章 极端的意见有害无益

第14章 API设计中的矛盾之处

第15章 改进API

修复乱七八糟的问题:测试用例。结合无绪。
兼容性是一种约束。
本书的大部分章节都将优雅看做一个不重要的内容,认为向后兼容性比优雅更为重要,因为对兼容性的需求是很容易分析出来的。但是API也不能越来越难看,尽量优雅一些。

第16章 团队协作

在提交代码时进行代码评审。
说服开发人员为他们的API提供文档。
通常来说,所谓好的建议就是能将产品的开发成本降低,并缩短产品推向市场的时间。

第17章 利用竞赛游戏来提升API设计技巧

正确的判断来自于经验,而经验来自于错误的判断。

第18章 可扩展Visitor模式的案例

第19章 消亡的过程

版本的重要性,模块的重要性。
分解庞大的API。

第20章 未来

无绪长存。
事物是永远不会十全十美的,事物是会演化的。
方法论:敏捷API设计。
集成和改进现有代码或开源代码的能力可能更实用有效。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章