只公开你要公开的内容
添加容易,移除困难
发布第一个版本时,移除不必要的内容
方法优于字段
除了static和final声明的基本类型、string常量、枚举和不变对象外,其他字段都不应该被公开
工厂方法优于函数
工厂方法返回值不一定是声明类型的实例,可以是子类的实例
每次返回的对象也不一定是新建的对象,可以将其缓存
同步控制,对创建对象前后的代码进行统一处理
让所有内容不可更改
如不希望拥有子类,就应该让其不可被继承
避免滥用setter方法
如无必要,绝不要在正式的API中声明setter方法
setEnable
可能上下文敏感
isEnable判断,使setEnable失去意义
尽可能通过友元方法来公开功能
java默认的package访问方式,内部类
避免暴漏深层次继承
代码复用
功能复用
“继承”不是用来改变具体的行为,而是用来添加一些额外的动作
如果去继承一个类,只是为了切换某些方法的执行路径,那么这种做法应予以避免
建议:避免深层次继承,定义程序接口,并让用户来实现这些接口
面向接口而非实现进行编程
抽象定义(接口)与实现分离
合作
向API用户讲清楚:使用APi时,应该遵循正确的原则。如果需要使用一个API就要遵守API的原则,不要破坏
清楚的说明API的需求,定义相应的用例,帮助API设计者实现这样的API
protected方法不可移除,导致子类修改
在接口中增加抽象方法,会强迫其非抽象子类实现该方法
模块化架构
面向对象并不能避免意大利面条式的编程
模块化的目的:实现各组成部分的松耦合
模块化架构将规范与实现分离
在规范所在的模块中,至少会有一个小的“入口”
依赖注入
Spring
Netbean lookup
扩展
P111 2001年,我们给JavaOne大会提交了一份名为“组件定位与协作”的议题,该议题中的内容与本章多少有些关系,我们认为该议题涉及的内容对于所有的模块化程序都很重要。然而,当时的JavaOne会议的组委会可能仅仅因为觉得这个议题的名称不够酷,或者可能因为他们觉得组件这个词用得太滥了,要知道“组件”这个词几乎包含了所有可以想象的内容,所以没有接受该议题。直到2006年,我和同事Tim Boudreau又提交了一份类似的议题,名为“模块化架构中那些发现注入和依赖注入的模式”。果然,如我们所料,议题被组委会接受了。这说明一定要找到能够贴近目标人群的术语才能打动他们。一旦听到“依赖注入”这个词,他们的心就被打动了。就像API这个词一样,恰当的名称有益交流。对于用户来说,他们越容易理解API这个词,就越容易接受API的相关内容。
其实还有几个词:架构、模式
设计API时要区分其目标用户群
API
可以添加但不能移除
供他人调用来完成某些功能
final类
内聚,自包含
SPI
Service Provider Interface
可以移除但不可增加
供其他人扩展API功能
接口
避免两者混用
合理分解API
API
SPI
NetBeans的分类
核心API
支持API
核心SPI
支持SPI
根据用户群体的不同需求来组织你的API结构
声明式编程
基本思路:不是让API用户一步步告诉程序如何做,而只需要告诉程序他们的结果,然后交给API去完成
NetBeans Lookup实现,只需要简单XML描述,不需要用户注册、注销
自描述性