异常捕获在实际的开发过程乃司空见惯.下面就我在开发过程中遇到的两种常见捕获异常的方法进行一个简单的比较.
方法一:
- void func1(param1, ...) throw Exception1;
- void func2(param1, ...) throw Exception2;
- int demo_func1(return_info)
- {
- // CODE LINES ...
- try
- {
- func1(param1, ...);
- func2(param1, ...);
- }
- catch(Exception1& e1)
- {
- // return_info assignment
- ...
- return FAIL;
- }
- catch(Exception2& e2)
- {
- // return_info assignment
- ...
- return FAIL;
- }
- return SUCC;
- } // end func demo_func1
方法二:
- int func3(param1, ..., return_info);
- int func4(param1, ..., return_info);
- int demo_func2(return_info)
- {
- // CODE LINES ...
- if (FAIL == func3(param1, ..., return_info))
- return FAIL;
- if (FAIL == func4(param1, ..., return_info))
- return FAIL;
- return SUCC;
- } // end func demo_func2
方法一使用的是显示的异常捕获,可以看到有异常捕获的关键字,try、catch、throw;方法二初一看,似乎仅是普通的函数调用,但实际上他是隐式的异常处理方法,为什么这么说呢,方法一是在外层函数捕获异常,并在捕获到异常后设置返回信息return_info,而方法二则在低层函数直接捕获了异常(不向上层抛出),并通过参数return_info来返回异常处理的信息.
这两种方法各有优劣,首先来看看方法二的缺点,需要有大量的if判断,使得代码不够直观明了.而方法一在这点上较有优势,从上面可以看出,方法一的代码结构比较清晰,不会有较多的if判断语句,所有的程序逻辑都放在了try语句中.
设计模式里面有个Law of Demeter,我也把这个法则叫做最少朋友法则,即不要跟陌生人说话,只与你最直接的朋友通信.显然符合Law of Demeter的代码有较高的复用性,利于重构.其实方法二是比较符合这个法则的.
下面假设,如应需求的变化,需要另外添加方法func5,该方法抛出异常Exception3,如果按照方法一的修改,那么需要在demo_func1中添加另外的catch块来捕获新的异常,同样,如果下次又需要删除func1方法时,也要删除对应的catch块,每次的修改,他所牵涉的代码不仅是所添加或删除代码的所在行,还包括了后面的一些代码行,影响范围较大.如果后期这部分的代码转给另外的人员维护的话,相信他还要另外花时间去熟悉代码结构,这是一个容易引起BUG的地方.同样地,如果我们采用的是方法二的结构,那么所需要的修改仅是在demo_func2中添加或注释掉几行,且涉及的代码仅仅就是添加或删除的代码行,与demo_func2内的其他代码没有关系,与func5的联系完全依赖于参数,则func5的复用性自然也得到了提高.因此方法二的内聚性高,耦合度低,具有较好的模块性,对后期代码的维护也比较简单.但是,如果需求是稳定不变的(基本上很难),那么采用方法一则会有较清晰的结构.