TinyMail研究—类型系统

TinyMail采用面向对象设计,自定义类型系统支持继承与多态。该系统包括对象与类结构、类型注册、对象创建与销毁等功能。文章对比了TinyMail与glib的类型系统,探讨了TinyMail自定义系统的必要性。

TinyMail研究—类型系统

转载时请注明出处和作者联系方式:http://blog.youkuaiyun.com/absurd

作者联系方式:李先静<xianjimli at hotmail dot com>

更新时间:2007-4-11

TinyMail是一套针对移动设备设计的邮件系统框架,为了达到最大的灵活性,它采用了很多设计模式和先进的编程技术,让框架的每一部分都可以定制和配置。TinyMail流行的趋势非常明显,Nokia770/800GPE Phone Edition等项目中都使用了它。因为我们也要开发邮件系统,所以花了几天时间去研究它的实现,这里记录一些研究笔记,供有兴趣的朋友参考。本文介绍一下TinyMail的类型系统

TinyMail虽然是用C语言开发的,但完全采用了面向对象的设计方法,为此它实现了自己的类型系统。TinyMail的类型系统和glib的类型系统极为类似,让人奇怪的是,TinyMail本身已经使用了glib,为什么它不用gobject的类型系统,而要自己实现一套呢?抱着这个疑问,我花了一些时间去研究它的实现:

1. ObjectObjectClass

gobject一样,每个类都由两个基本结构组成:ObjectObjectClass

Object结构定义了对象的数据成员,每个对象实例都有自己的拷贝。该结构的第一个成员用来实现继承关系,这是C语言中实现继承的常用手法。比如(CamelService继承于CamelObject)

struct _CamelService {

CamelObject parent_object;

struct _CamelServicePrivate *priv;

CamelSession *session;

CamelProvider *provider;

CamelServiceConnectionStatus status;

CamelOperation *connect_op;

CamelURL *url;

gpointer data;

};

ObjectClass定义了对象的行为和所有实例的共享数据。对象的行为也就是一些函数指针,用来实现虚函数。该结构的第一个成员用来实现继承关系,这是C语言中实现继承的常用手法。如(CamelServiceClass继承于CamelObjectClass)

typedef struct {

CamelObjectClass parent_class;

void (*construct) (CamelService *service,

CamelSession *session,

CamelProvider *provider,

CamelURL *url,

CamelException *ex);

gboolean (*connect) (CamelService *service,

CamelException *ex);

gboolean (*disconnect) (CamelService *service,

gboolean clean,

CamelException *ex);

void (*cancel_connect) (CamelService *service);

GList * (*query_auth_types) (CamelService *service,

CamelException *ex);

char * (*get_name) (CamelService *service,

gboolean brief);

char * (*get_path) (CamelService *service);

} CamelServiceClass;

这与glib相似。

2. 类型的注册。

可以调用函数camel_type_register向类型系统注册新类型,注册时要提供下列信息:

l 父类的类型。

l 名称。

l Object的大小。

l ObjectClass的大小。

l ObjectClass的初始化函数。

l ObjectClass的释放函数。

l Object的初始化函数。

l Object的释放函数。

camel_interface_register是对camel_type_register的包装,用于注册接口。由于接口只有虚函数,没有数据成员,所以Object的大小为0,也没有Object的初始化函数和释放函数。

camel_type_register调用co_type_register完成注册。在注册时,co_type_register先建立类型的层次关系,然后插入到hash表中,最后调用ObjectClass的初始化函数。在调用ObjectClass的初始化函数时,它会从最顶层基类的ObjectClass的初始化函数一直调到当前类的ObjectClass的初始化函数。

这与glib相似。

3. 对象的创建。

可以调用camel_object_new创建对象实例,该函数要求一个指明对象类型的参数。也可以调用camel_object_new_name创建对象实例,该函数是对camel_object_new包装,它先通过类型名称获得类型,然后调用camel_object_new创建对象。

camel_object_new首先根据注册时指定的对象大小分配一块内存,然后调用Object的初始化函数初始化它,然后返回指向该内存块的指针。在调用Object的初始化函数时,它会从最顶层基类的Object的初始化函数一直调到当前类的Object的初始化函数。

这与glib相似。

4. 对象的销毁。

虽然在注册类型时,指定了Object的释放函数,但不直接调用它去销毁对象,而是由对象的引用计数来决定是否真正销毁对象。

camel_object_unref用于将对象的引用计数减一,当对象的引用计数为0时,它会:

l 触发finalize信号,让相关对象得到通知。

l 从当前类的Object的释放函数一直调到最顶层基类的Object的释放函数。

l 释放内存。

glib相比,对象的销毁不再分disposefinalize两阶段,对于互相引用的对象可能存在问题。

5. 对象的引用计数。

camel_object_ref增加引用计数。

camel_object_unref减少引用计数。

glib相比,缺少弱引用(weak ref)功能,但可以通过finalize信号来模拟实现。

6. 对象的属性。

camel_object_set/camel_object_setv可以用来设置对象的属性。

camel_object_get/camel_object_getv/camel_object_get_ptr/camel_object_get_int可以用来获取对象的属性。

glib相比,不需要安装属性的spec

7. signal(event)机制。

camel_object_hook_event用于注册。

camel_object_remove_event/camel_object_unhook_event用于注销。

camel_object_trigger_event用于触发。

glib相比,不需要那套复杂的marshal机制,所有参数都是gpointer格式,但使用简单的同时也失去类型检查的好处。

8. 持久化。

camel_object_state_write负责保存对象状态。

camel_object_state_read负责恢复对象状态。

glib相比,这是一个特有的功能。

综上所述,我觉得TinyMail的类型系统虽然实现很精巧,但完全可以建立在glib的类型系统之上,没有必要自己重搞一套。

~~end~~

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值