http://www.raychase.net/2380
http://programmers.stackexchange.com/questions/196151/what-guidelines-should-i-follow-while-designing-a-library
http://programmers.stackexchange.com/questions/196151/what-guidelines-should-i-follow-while-designing-a-library
- Pin Map,明确你期望库主要用来做什么,但不要把它定得太死,用户要可以比较方便地做出改变。
- Working Library,一个工作的库,如果它连这点都达不到,一定要注明。没有人希望浪费时间在一个无法工作的程序库上面。
- Basic Readme,清晰地描述库是用来做什么的,测试的情况等等。
- Interfaces,接口必须清晰地定义,这可以帮助库的使用者。
- Special Functions,特殊的功能,一定要注明,包括在readme文档中注明,以及在注释中注明。
- Busy Waits,如果有一些场景需要使用busy wait(我不知道怎么翻译),其过程中可能会出现异常,使用interrupt或者其它妥善的方法来处理。
- Comments,你做的任何的改变都要注释清楚,明确描述接口和其每个参数,方法是做什么的,又返回什么;如果有某个中间方法被调用到,就要注明。
- Consistency,一致性,所有东西,包括注释。相关的方法要放在一个简单的代码文件里面,小但是逻辑一致。
其中的高级部分又包括Detailed Readme,Directory Structure,Licensing和Version Control。
考虑库的目标用户。这听起来扯得有点泛,但实际上这是确切的问题,这是开源库还是你只是在小组内部使用的库,或者是公司内部使用的?用户的能力和需求是不一样的,要求当然不同。
要解决的核心问题。这是上文中Pin Map的一部分,不要重复发明轮子,那么每一个新库都有其存在的价值,这个问题既要通用又要具体,“通用”指的是库总有一个普适性,解决的实际问题对于不同的用户来说是不一样的;而“具体”是指库解决的问题对于程序员来说是非常清晰和直接的。例如设计一个库,根据某种规则把不同的数据类型(XML,BSON或者某种基于行的文本等等)都转换成JSON。
统一的编程风格。很多库都有自己精心设计的一套DSL,比如链式调用等等几种方式,当然,这也和使用的语言有关系。定义一种用起来舒服的编程风格对于程序库的推广是很有好处的。这也是一致性的一个体现。
内聚的调用入口。这和面向对象的“最少知识原则”有类似的地方,把那些不该暴露出去的库内部实现信息隐藏起来,在很多情况下,程序库不得不暴露和要求用户了解一些知识的时候,比如:
1
2
3
4
5
6
7
| MappingConfig config = new MappingConfig(); config.put(MappingConfigConstants.ENCODE, "UTF-8" ); FileBuilder fileBuilder = new StandardFileBuilder(mapping); InputStream stream = fileBuilder.build().getInputStream(); DataTransformer<XMLNode> transformer = new XMLDataTransformer(...); ... transformer.transform(stream); |
这里引入了太多的概念,MappingConfig、FileBuilder、DataTransformer等等,整个过程大致是构造了一个数据源,还有一个数据转换器,然后这个数据转换器接受这个数据源来转换出最后结果的过程。那么:
这些象征着概念的接口和类最好以某种易于理解的形式组织起来,比如放在同一层比较浅的包里面,便于寻找;
也可以建立一个facade类,提供几种常用的组合,避免这些繁琐的对象构建和概念理解,例如:
1
| XXFacade.buildCommonXMLTransformer(); |
向后兼容。当然,这一点也可以归纳到前文提到的一致性里面去。我曾经拿JDKHashTable举了一个例子,它的containsValue和contains方法其实是一样的,造成这种情况的一个原因就是为了保持向后兼容。
依赖管理。依赖管理很多情况下是一个脏活累活,但是却不得不考虑到。通常来说,任何一个库考虑自己的依赖库时都必须慎重,尤其是面对依赖的库需要升级的时候。如果依赖的库出了问题,自己设计的程序库也可能因此连累。
完善的测试用例。通常来说,程序库都配套有单元测试保证,无论是什么语言写的。
健全的文档组织。通常包括教程(tutorial)、开发者文档(developer guide)和接口API文档(API doc)。前者是帮助上手和建议使用的,中间的这个具备详尽的特性介绍,后者则是传统的API参考使用文档。