代码整洁之道-读书笔记之边界

1. 使用第三方代码

在接口提供者和使用者之间,存在与生俱来的张力。第三方程序包和框架提供者追求普适性,这样就能在多个环境中工作,吸引广泛的用户。二使用者则想要集中满足特定需求的接口。这种张力会导致系统边界上出现问题。

不建议服务和服务之间、接口和接口之间通过Map传递

2.浏览和学习边界

第三方代码帮助我们在更少时间内发布更丰富的功能。在利用第三方程序包时,该从何处入手呢?我们没有测试第三方代码的职责,但为要使用的第三方代码编写测试,可能最符合我们的利益。

设想我们对第三方代码库的使用方法并不清楚。我们可能会花上一两天(或者更多)的时间阅读文章,决定如何使用。然后,我们编写使用第三方代码的代码,看看是否如我们所愿的公工作。我们会陷入长时间的调试,找出在我们或他们代码种的缺陷。这可不是什么稀罕事。

学习第三方代码很难,整合第三方代码也很难,同时做着两件事难上加难。如果我们采用不同的做法呢?不要在成产代码种试验新东西,而是编写测试来便览和理解第三方代码。Jim Newkirk把这叫做学习性测试

在学习性测试中,我们就像在应用中那样调用我们第三方代码,我们基本上时在通过核对试验来检测自己对那个API的理解程度。测试聚焦于我们想从API得到的东西。

3.学习log4j

3.1日志等级

1、TRACE 在线调试

默认情况下,即不打印到终端也不输出到文件。对程序的运行效率几乎不产生影响。

2、DEBUG 终端查看、在线调试

默认情况下,打印到终端输出,但是不会归档到日志文件。因此,一般用于开发者在程序当前启动窗口上,查看日志的流水信息。

3、INFO 报告程序进度和状态信息

一般这种情况都是一次性的,不会大量反复输出。

4、WARNING 警告信息

程序处理中遇到非法数据或者某种可能的错误。该错误是一过性的、可恢复的,不会影响程序的继续运行,程序仍处在正常状态。

5、ERROR 状态错误

该错误发生后程序仍然可以运行,但是极有可能运行在某种非正常的状态下,导致无法完成全部既定的功能。

6、FATAL 致命错误

表明程序遇到了致命的错误,必须马上终止运行。

Log4j建议只使用四个级别,优先级从高到低分别是

ERROR > WARN > INFO > DEBUG

3.2书本内容

比如,我们想使用Apache log4j包来代替自定义的日志代码。我们下载了log4j,打开介绍文档页,无需看太久,就编写了第一个测试用例,希望他能在控制台打印输出“hello”字样。

@Test
public void testLogCreate(){
	log.info("info");
}

运行上述代码, logger发生了一个错误,告诉我们需要用Appender。在多读一点文档,我们发现有个ConsoleAppender。于是我们创建了一个ConsoleAppender,再看是否能解开控制台输出日志的秘诀。

@Test
public void testLogAddAppender(){
	Logger logger = Logger.getLogger("MyLogger");
	logger.removeAllAppenders();
	logger.addAppender(new ConsoleAppender(
		new PatternLayout("%p %t %m%n"),
		ConsoleApender.SYSTEM_OUT)
	);
	Logger.info("hello");
}

这回行了,”hello”字样的日志信息出现在控制台上!必须告知ConsoleAppender,让它往控制台写字,看起来有点奇怪。

很有趣,当我们移除ConsoleAppender.SystemOut参数时,那个“hello”字样仍然输出到屏幕上。但如果取走PatternLayout,就会出现关于没有输出流的错误信息,这实在太古怪了。

再仔细看看文档,我们看到默认的ConsoleAppender构造器时”未配置”的,这看起来并不明显或没什么用,反而像是log4j的一个缺陷,或者至少时前后不太一致。

在搜索、阅读、测试,最终我们的带代码如下。

public class LogTest {
	Private Logger logger;

	@Before
	pubolic void initialize() {
		logger = Logger.getLogger("logger");
		logger.removeAllAppenders();
		logger.getRootLogger().removeAllAppenders();
	}

	@Test
	public void basicLogger() {
		BasicConfigurator.configure();
		logger.info("basicLogger");
	}

	@Test
	public void addAppenderWithStream() {
		logger.appAppender(new ConsoleAppender(
			new PatternLayout("%p %t %m%n"),
			ConsoleApender.SYSTEM_OUT
		));
		logger.info("addAppenderWithStream");
	}

	@Test
	public void addAppenderWithoutStream() {
		logger.addAppender(new ConsoleAppender(
			new PatternLayout("%p %t %m%n")
		));
		logger.info("addAppenderWithoutStream");
	}
}

现在我们知道如何初始化一个简单的控制台日志器,也能把之这些知识封装到自己的日志类中,好将应用程序的其他部分与log4j的边界接口隔离开来。

4. 学习性测试的好处不只是免费

学习性测试:用以表述在对第三方接口或资源包学习的过程中,通过本地编写测试来遍历我们需要用到的功能,并以此作为后续自身项目质量保证一环的软件编程行为

好处:当第三方资源进行版本升级的时候,可以通过测试代码很好的展示出,版本升级带来的问题,并且及时修复

5. 使用尚不存在的代码

在开发过程中,需要与第三方交互,但是接口还没有实现,这个时候我们可以mock接口的入参和出参还有接口请求方式,从而不影响自己以及其他人的开发进度,当接口开发完成,再修改成真实的接口

我们和第三方交互,mock第三方接口

前端和我们交互,给前端提供mock接口

6. 整洁的边界

有良好的软件设计,无需巨大投入和重写即可进行修改。在使用我们控制不了的代码时,必须加倍小心保护投资,确保未来的修改不至于代价太大。

控制你能控制的,好过依赖你控制不了的,避免日后受它控制

相关文章

学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习...
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面...
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生...
Can’t connect to local MySQL server through socket \'/v...
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 ...
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服...