从Tomcat工程源码中学到的软件开发小技巧
摘要
本文主要总结我阅读Apache Tomcat 7.0.65源码的过程中学到的一些软件开发小技巧。今后如果我们新建工程项目,团队遵循这些小技巧能够给工程代码管理与组织带来极大的方便性。
如果把Tomcat源码工程看成一部书,那么这部书就有好几册。每个大的功能模块可以看成一册书。比如Tomcat日志模块juli,连接器模块coyote,请求响应处理模块catalina。每一个*.java文件就是书里一个个章节。有的章节可能会和另外的章节有依赖关系。但是册与册之间基本能够独立开来。就像一部书,我们可以只买其中某一册或者几册。同样内容的一册书可能有好几个出版社出版,虽然封面或规格不太一样,但是内容基本一致。Tomcat有些模块也可以使用其他类似功能模块替代,比如日志模块可以使用Log4j,或使用其他的连接器。每个章节也大纲非常清晰,层次非常分明。总的来说,阅读Tomcat源码,就像在阅读一本逻辑严谨,层次清晰,情节跌宕起伏的小说。
软件模块化
任何事物只要整齐化,结构化,规范统一化就能给人产生美感。如果一个房间混乱不堪,我们要从中找一个东西恐怕要靠运气。软件设计也一样。模块化,命名规范统一化,层次清晰化的设计无论是维护还是后续迭代增量开发都能让人轻松上手并且真正享受编程的乐趣。
从物理层面来说,Tomcat的源码分为两大类,分别是Java EE拓展代码和Tomcat容器代码。两个包名分别是javax.和org.apache.,这是工程的两大类代码。每个类里又是由一个个模块组成,比如请求响应处理模块的代码位于org.apache.catalina,日志模块位于org.apache.juli,连接器模块位于org.apache.coyote等。模块里可能又划分了小模块,类与类之间可能还有继承,组合关系。这些关系的组织都非常清晰。模块与模块之间基本能实现独立化。我们可以用其他模块代替Tomcat自由的模块,只需要在配置文件中修改配置即可,比如替换连接器或替换日志组件就只需要修改Tomcat的server.xml文件。这就是模块化带来的好处。高内聚,低耦合,这是软件工程里的一条非常重要的原则。
常量字段模块化,统一化
在Tomcat里,很多模块都能看到一个Constants.java这个类文件。这个文件基本全是public static final字段。这些就是Tomcat用到的常量字段。这样做可以实现常量字段统一化,集中化管理,还能消除代码中的魔数。如果要修改某个地方,只要来修改这个文件即可。
package org.apache.catalina.core;
public class Constants {
public static final String Package = "org.apache.catalina.core";
public static final int MAJOR_VERSION = 3;
public static final int MINOR_VERSION = 0;
public static final String JSP_SERVLET_CLASS =
"org.apache.jasper.servlet.JspServlet";
}
国际化资源管理统一化
Tomcat有一个StringManager.java的类,专门处理国际化资源文件。Tomcat里很多日志信息需要国际化。因此Tomcat专门针对这些properties文件用一个StringManager.java来统一管理。使的那些国际化字符串集中化。
模仿StringManager.java写的一个工具类:https://github.com/34benma/MyTools/blob/master/src/com/util/StringManager.java
类文件结构清晰,注释完善,命名完整
比如Tomcat的启动文件就叫BootStrap.java(非内嵌版),很多方法名字以及字段名字看到名字就知道其作用。类中私有方法,公用方法,辅助方法按照功能类型统一集中布局。
// ----------------------------------------------------- Instance Variables
/**
* Use await.
*/
protected boolean await = false;
/**
* Pathname to the server configuration file.
*/
protected String configFile = "conf/server.xml";
=分=割================
// ----------------------------------------------------------- Constructors
public Catalina() {
setSecurityProtection();
}
=分割===================
// ------------------------------------------------------ Protected Methods
/**
* Process the specified command line arguments, and return
* <code>true</code> if we should continue processing; otherwise
* return <code>false</code>.
*
* @param args Command line arguments to process
*/
protected boolean arguments(String args[]) {
总结
Tomcat的源码读起来让人产生舒适感。从来不会感到混乱的代码以及让人迷惑的命名或方法功能。整个Tomcat的逻辑架构也非常清晰合理,仿佛一座大厦。这可能也是Tomcat目前一直发展这么好的一个原因吧。它的首席架构师Craig R. McClanahan同时也是Struts2的架构师。我们也能从中看到很多相似点,比如拦截器的概念,在Tomcat里叫阀。功能类似。
在软件架构以及代码规范上,如果能做到整齐统一,简洁清晰真的是一件非常让人愉快的事情。
好的软件架构以及代码规范学习,从阅读好的代码开始。