如何为旧版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,并处理结果标签. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |