如何更好的架构一个界面库,欢迎大家一起讨论

leeihcy 2013-03-11 11:49:07
到目前为止,自己做界面库时为了简单,直接将所有内容封装在一个DLL里面,然后将所有的类统统导出,便于外部进行继承扩展。例如外部可以直接继承一个导出的ListViewBase基类,在这个基础上再实现相应需求的列表控件。

最近有时间重新整理架构了,发现全部将类导出这种方式有很多缺陷:
a. dll导出数据过多,导出列表不清晰。 导出过多的数据对DLL大小有多少影响目前尚未验证
b. 如果一个导出类中包含了stl类,(如string),在跨模块继承时,很容易造成崩溃现象
c. 对外暴露的信息太多,不利于升级
d. 导出太多的头文件,一修改导出类的一些成员时,就得全部编译
e. 其它

目前我的想法是将界面库先分成两块,UISDK.dll负责界面核心部分,UICtrls.dll负责各种控件的实现,其中各DLL仅导出接口文件和一些CreateInstance Api。

这里碰到的一个头疼的问题就是没法使用继承了。 例如UICtrls.dll中的Button类,需要在UISDK.dll中的Control、Object、Message的基础上进行扩展,但它只能拿到一系列的接口IControl,IObject,IMessage...

要想让Button得到Control/Object/Message这些能力,我现在能想到的就是在Button中去Create Control类实例,例如:


/* UISDK.dll 内部实现 */
class Message : public IMessage {};
class Object : public Message, public IObject {};
class Control : public Object, public IControl
{
public:
virtual void Func() {};
}

/* UISDK.dll 暴露出来的接口头文件 */
interface IMessage{};
interface IObject{};
interface IControl { virtual void Func() = 0; }

class IMessageImpl : public IMessage {...};
class IObjectImpl : public IMessageImpl, public IObject {...};
class IControlImpl : public IObjectImpl , public IControl
{
public:
IControlImpl()
{
CreateControlInstance(&m_pInnerControlInstance);
}
virtual void Func() { m_pInnerControlInstance->Func(); }

private:
IControl* m_pInnerControlInstance;
};

/* UICtrls.dll控件实现代码 */
class Button : class IControlImpl
{

}

这样Button类就能间接调用到内部的Control方法。


但最恶心的是实现多态非常麻烦,还得由内部类反调外部类的实现,各种细节问题,搞的我头都大了。最后让自己都觉得这种方案太过于复杂了,想看看有没有别的办法,既能只导出接口,又能实现继承和多态的效果。

像Windows系统控件那样完全靠SendMessage进行交互不知道行不行..
...全文
563 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
OriesMap 2013-11-05
  • 打赏
  • 举报
回复
干什么一定要分开呀? 象楼上说的pImpl方法,那不是要写n多的接口类? 而且在基类里面大量限定子类的行为似乎对于扩展性也不太好。
雪人silent 2013-05-02
  • 打赏
  • 举报
回复
hyperminer 2013-05-02
  • 打赏
  • 举报
回复
还没用使用过dll界面库方面的知识,大神能不能整理一些从入门到高级的知识呢,对这个很感兴趣。
leeihcy 2013-03-25
  • 打赏
  • 举报
回复
上网查了一些方法,发现Pimpl方法能较好的解决一部分问题:


每个对象分为两部分: Ixxx 和 xxx 。Ixxx 模拟接口类,但需要导出给外部使用(纯虚接口类则不需要导出),内部创建 xxx 实例并转发函数调用。

另外在Pimpl基础上做了一些修改,例如:
1. 添加了Ixxx之间的继承关系,
2. 为IMessage基类固定添加了两个虚函数:~IMessage和 ProcessMessage,用这种方式来实现多态,同时避免增加新的虚函数,便于升级扩展(ProcessMessage虚函数可以采用 NVI 方法做成私有虚函数,让外部调用一个public_ProcessMessage方法进行转发)。
Yun__ 2013-03-12
  • 打赏
  • 举报
回复
我的那个DirectUI 就是框架是框架 与控件完全分离 。 但是dll多了也是个麻烦。
hurryboylqs 2013-03-12
  • 打赏
  • 举报
回复
简单就是美
特雷西_KID 2013-03-12
  • 打赏
  • 举报
回复
mark
  • 打赏
  • 举报
回复
呵呵,什么都有好的一面和不好的一面,对于这个东西,没有绝对的不好,也没有绝对的好。呵呵。

15,981

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧