Java 中就是接口)。封装的层次越高,抽象的层次就越高,使得设计、代码有越高的弹性,
越容易适应变化。
考虑对上一节中的代码,如果在系统的开发过程中发现需要对一种新的错误进行处理,
比如:用户认证错误,我们该如何做使得我们的系统能够增加对于此项功能的需求呢?一
种比较简单、直接的做法就是在增加一条用来处理此项错误的 case 语句。是的,这种方
法的确能够工作,但是这样做是要付出代价的。
首先,随着系统的进一步开发,可能会出现更多的错误类型,那么就会导致对于错误
的处理部分代码冗长,不利于维护。其次,也是最根本的一点,修改已经能够工作的代码,
很容易引入错误,并且在很多的情况下,错误都是在不经意下引入的,对于这种类型的错
误很难定位。有调查表明,我们在开发过程中,用于修正错误的时间并不多,大部分的时
间是在调试、发现错误。在面向对象领域,有一个很著名的原则:OCP(Open-Closed
Principle),它的核心含意是:一个好的设计应该能够容纳新的功能需求的增加,但是增
加的方式不是通过修改又有的模块(类),而是通过增加新的模块(类)来完成的。如果
一个设计能够遵循 OCP,那么就能够有效的避免上述的问题。
要是一个设计能够符合 OCP 原则,就要求我们在进行设计时不能简单的以功能为核心。
要实现 OCP 的关键是抽象,抽象表征了一个固定的行为,但是对于这个行为可以有很多个
不同的具体实现方法。通过抽象,我们就可以用一个固定的抽象的概念来代替哪些容易变
化的数量众多的具体的概念,并且使得原来依赖于哪些容易变化的概念的模块,依赖于这
个固定的抽象的概念,这样的结果就是:系统新的需求的增加,仅仅会引起具体的概念的
增加,而不会影响依赖于具体概念的抽象体的其他模块。在实现的层面上,抽象体是通过
抽象类来描述的,在 Java 中是接口(interface)。
既然知道了问题的本质以及相应的解决方法,下面就来改善我们的代码结构。
4、初步方案
让我们重新审视代码,看看该如何进行抽象。在错误处理中,需要处理不同类型的错误,
每个具体的错误具有特定于自己本身的一些信息,但是它们在概念层面上又是一致的,比
如:都可以通过特定的方法接口获取自已内部的错误信息,每一个错误都有自己的处理方
法。由此可以得到一个初步的方案:可以定义一个抽象的错误基类,在这个基类里面定义
一些在概念上适用于所有不同的具体错误的方法,每个具体的错误可以有自己的不同的对
于这些方法的实现。代码示例如下:
interface ErrorBase
{
public void handle()
public String getInfo();
}
class DBAccessError implements ErrorBase
{
public void handle() {
/* 进行关于数据库访问错误的处理 */
}