MFC程序轻量级模块化的实现

这里介绍一个办法来实现基于MFC应用程序的模块化,至于为什么要模块化,模块化有哪些优点哪些缺点这里不做讨论。

假设有这样一个工程,有主程序Main.exe和两个DLL模块Module1.dll以及Module2.dll组成,所有的模块都动态链接到MFC动态库(静态链接到MFC动态库的情况会有些区别)。


一、首先要建立先定义好一组接口,用来实现主程序和DLL模块双向交换。

 

1、主程序Main.exe要提供一个接口IApp给DLL模块,使得DLL模块可以使用主程序的一些功能,比如写日志等。

class IApp

{

public:

    virtual ILog* GetLog()= 0; //返回日志接口指针

    //这里可以扩展其他的虚函数,但是新的虚函数定义一定要放在原有接口的最后面,这和虚函数表有关。

    //这样就达到了可扩展性。

};

 

2、模块Module1.dll以及Module2.dll也要分别提供一个或多个接口给主程序Main.exe调用。

分别为:

class IModule1

{

public:

    virtual void SetApp(IApp* lpApp) =0; //把主程序的接口传给DLL

    virtual void DoSomething()= 0;//做一些处理

    //这里一样支持可扩展

};

 

class IModule2

{
public:

    virtual void SetApp(IApp* lpApp) =0; //把主程序的接口传给DLL

    virtual void ShowDlg()= 0;//显示对话框

//这里一样支持可扩展

};

 

二、建立各自的MFC工程并实现相应的接口

 

1、建立主程序MFC工程Main.exe,动态链接到MFC动态库,然后实现IApp,ILog等接口。

 

2、建立MFC工程Module1.dll,可以是规则DLL,也可以是非规则DLL,但是要求动态链接到MFC动态库。

   规则DLL与非规则DLL在资源使用,窗口管理等方面有些区别,一般建议使用非规则DLL。

   Module1.dll不直接导出类,而是导出一些函数来创建对应的接口,比如导出函数CreateModule1Instance()用来创建IModule1实例,以此类推。这是为了把创建实例的代码放在DLL中,也是为了支持将来升级扩展。因为后续版本的Module1.dll所实例化的对象占用的内存大小可能不一样的,如果把实例化代码放在Exe中,则需要重新编译Exe。

 

3、Module2.dll实现同上。

 

三、扩展升级

 

1、不修改接口的扩展

比如要修改IModule1中DoSomething函数所实现的功能,那就只需要修改并升级Module1.dll即可。

 

2、需要修改接口的扩展

 

修改IModule2接口(有可能也需要修改IApp接口):

class IModule2

{

public:

    virtual void SetApp(IApp* lpApp) =0;

    virtual void ShowDlg()= 0;

    virtual void DoSomething()= 0;//增加的函数

};

       这样需要修改Module2.dll和主程序Main.exe的代码来实现新功能。但是修改后Module2.dll一样支持老版本的Main.exe,因此也就只需要维护一个版本的Module2.dll即可。

 

四、一些应用场合

 

1、 不用的客户使用不同的模块,从而实现业务逻辑的不同。(比如使用不同的数据库。)

 

2、 主程序需求相对稳定,但是某个模块功能经常需要升级。(需求特别紧急的情况下,其好处更是明显,目前笔者的产品就是这样的。)

你可能感兴趣的:(VC/MFC,mfc,module,dll,扩展,exe,数据库)