系统可跟踪性(Tracibility)设计与异常处理

来源:互联网 发布:ims注册成功率优化 编辑:程序博客网 时间:2024/05/16 08:52

烽驿2009开源实时通信平台 源码获取:svn checkout http://fy2009.googlecode.com/svn/trunk/ fy2009-read-only  

可跟踪性(Tracibility)设计是软件架构设计的重要内容之一。在面向对象系统中,对象的可跟踪是实现系

统可跟踪的基本前提。在本项目中为此定义了一个接口如下:

class object_id_it : public lookup_it
{
public:
        //return an unique object id and ensure it's readable for tracibility
        virtual const int8 *get_object_id() throw()=0;
};

自定义Class通过实现该接口实现其基本的可跟踪性要求。get_object_id被要求返回运行期唯一标识该对象

的字符串(如果你采用一种持久性唯一标识当然可以接受)。 本项目还提供了object_id_it接口的缺省实现object_id_impl_t。用户自定义的Class只需继承自该类,并重写void _lazy_init_object_id() throw()虚函数即可实现可跟踪。为尽可能降低这类非功能性服务的开销,该函数只在第一次访问get_object_id时才被调用。通常,对象标识可采用类名加对象指针的格式:<class name>_<object pointer>。

用户Class只需在实现_lazy_init_object_id函数时用OID_DEF_IMP(class_name)宏即可生成常规

格式的对象标识符。另外,上述接口之所以继承自lookup_it,请参阅笔者另一篇有关“窄接口”设计与动态类型发现的博文。
异常处理是架构设计的另一项重要任务。任何复杂系统都会发生异常,软件系统当然不会幸免。发生异常

时,准确详尽的上下文描述对问题诊断至关重要。在C语言中,通常只能通过检查每次函数调用的返回码来

判断是否发生了异常,若对每次函数调用都作这种判断和处理,无疑将使程序丑陋而冗长,不免让人想起《大话西游》中那个喋喋不休的唐僧。C++及当前的主流语言基本上都采用try...catch机制来处理异常,笔者同样赞赏该方式。但C++给了我们太大的灵活性,你可以throw出任意类型(系统类型或用户自定义类型)的异常对象,这反而使我们在捕获异常时不知道究竟需要捕获哪些类型。无规矩不成方圆,本项目统一定义异常对象exception_t,本项目中一律抛出该异常对象。

异常总是发生在特定的函数调用上下文,我们通常只重视异常的原始发生地,而轻视异常发生时特定的函数调用链。如

有个函数完成两个数相除,在零用作除数时会抛出异常“被零除”,但调用该函数的函数通常要么直接把这个

异常继续抛出,要么终结该异常(通常是输出异常描述“被零除”)。显然,该异常描述对技术人员帮助有限

,因为,它没有指明调用上下文,即异常发生时的整个函数调用链。笔者坚持认为异常发生时跟踪整个函

数调用链是至关重要的,因此,上述exception_t被实现成可追加行的方式,以便函数调用链的任一环都可

方便地通过调用 void push_back(const int8 *src_file, int32 line_num, const int8 *object_id,

       const int8 *function_name, const int8 *spot, const int8 *desc)成员函数往该异常对象增加该环节的特定描述行。这样,在最后终结该异常对象时,你将得到有关整个调用链的详细信息。每条被追加的异常记录都包含源文件名,源码行号,上述对象标识,函数名,异常发生点(spot),异常描述。 其中异常发生点应该尽可能用一个对象范围内唯一的短字符串表示,尽管这种唯一性样并不被强制。其目的是供工程维护中对常见异常以spot组合(整个调用链上的spot,相互间以“."分隔)为Key建立档案库。
为方便实际使用上述异常机制,本项目定义了如下宏:
对于实现了上述object_id_it接口的对象成员函数的实现,可以在第一句调用如下宏:
FY_DECL_EXCEPTION_CTX_EX(function_name) 该宏会自动调用object_id_it接口取得当前对象的标识

符,用于后面的异常处理。
然后调用FY_TRY宏开始try...catch语句体。
在发生异常时,调用FY_THROW_EX(spot, desc)抛出exception_t异常对象
在函数实现的尾部调用FY_CATCH_N_THROW_AGAIN_EX(spot, desc, final_code)或终结异常的宏来结束try...catch语句体。FY_CATCH_N_THROW_AGAIN_EX宏并不终结异常,只是在异常对象上追加本环结的描述行然后再抛出;终结异常的宏,则因涉及Trace服务,将在以后有关的专题中提及。


有关上述异常机制的使用,在本项目的测试代码中都能找到Sample.

 

原创粉丝点击