如何为旧版API /框架(C宏与C模板与代码生成器)实现大量复杂的包装?

前端之家收集整理的这篇文章主要介绍了如何为旧版API /框架(C宏与C模板与代码生成器)实现大量复杂的包装?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我们与使用VC6编译器的C实现的旧旧系统一起工作.现在我们正在重构代码.我们也切换到VC9编译器.

我们使用外部专有框架,这也是遗留代码,而不是单元测试.为了使我们的代码单元可以测试,我们为框架类引入了接口和包装(提示:参见Martin Fowler的“使用遗留代码”):

现在我们依赖于接口.包装器调用框架方法,我们可以在单元测试中快乐地使用模拟.

在这里我们来看我们的问题

框架类包含许多需要包装和嘲笑的方法.为了实现这一目标,我们的供应商团队编写了一个使用C宏生成接口,封装和模拟实现的API.

包装头文件示例:

class PlanWrapper : public IPlan
{
  // ... 
  WRP_DECLARE_DEFAULTS(FrameworkPlan); // macro
  WRP_DECLARE_CSTR_ATTR(FrameworkPlanLabel); // macro
  // ...
};

宏WRP_DECLARE_CSTR_ATTR定义如下:

#define WRP_DECLARE_CSTR_ATTR(AttrName) \
    virtual bool set##AttrName (LPCTSTR Value_in); \
    virtual bool get##AttrName (CString& Value_out); \
    virtual bool unset##AttrName (); \
    virtual bool isSet##AttrName ()

包装器cpp文件示例:

#include "StdAfx.h"

using namespace SomeNamespace;

WRP_IMPLEMENT_MODDICOM_DEFAULTS(FrameworkPlan)
WRP_IMPLEMENT_W_CSTR_ATTR (FrameworkPlan,FrameworkType1,FrameworkPlanLabel)
// ...

宏WRP_IMPLEMENT_W_CSTR_ATTR的定义如下:

#define WRP_IMPLEMENT_W_CSTR_ATTR(ClassName,AtrTypeObj,AttrName) \
    bool ClassName##Wrapper::set##AttrName (LPCTSTR Value_in) { \
            AtrTypeObj aValue = Value_in; \
        FrameworkLink<ClassName> convertedObj = NULL_LINK; \
        framework_cast(convertedObj,m_Object); \
        return convertedObj != NULL_LINK ? \
                       convertedObj->set##AttrName (aValue) : false; \
    }
    // ...

我们有一堆更复杂的东西,但我想你得到的想法.

API的问题是它非常复杂,不可读,不可调试,不可测试.

我们想提出一个更好的机制来实现同样的目标.这个想法是我们使用新的编译器(如高级模板,类型列表,特征等)附带的一些高级功能.

使用模板我们几乎可以实现我们的目标,但我们坚持使用方法名称.我们可以推广类型,但是我们如何处理属性名称

我们还考虑创建一个自动生成包装器接口mocks代码的工具.然而,我们的外部框架的API非常复杂,并且编写这样的工具将是非常昂贵的.

你认为解决这个问题的最好办法是什么?也许你已经处理过这样的事情,可以提供好的提示?我们期待您的回答!

解决方法

我想我会用代码生成工具.我可能会做一些简单的实用程序:一个用于生成一个对应于你的旧框架类的接口,一个用于生成包装器,一个用于生成模拟对象(或至少一个框架).

这意味着有一些方法来解析遗留框架的代码.我会看看Clang,或者可以简单地在源文件上运行ctags,并处理结果标签.

猜你在找的C&C++相关文章