c++ - 如何在不重复代码的情况下统一实现双向转换?

标签 c++ design-patterns data-structures

我在 C 遗留代码中使用了两个大型 C 结构,我需要从一个转换为另一个,然后反过来。像这样:

#include <iostream>

struct A {
    int a;
    float b;
};
struct B {
    char a;
    int b;
};

struct C {
    A a;
    B b;
};

struct D {
    int a;
    char b;
    float c;
};

void CtoD( const C& c, D &d ) {
    d.a = c.a.a;
    d.b = c.b.a;
    d.c = c.a.b;
}
void DtoC( const D &d, C& c ) {
    c.a.a = d.a;
    c.b.a = d.b;
    c.a.b = d.c;
}

int main()
{
    C c = { { 1, 3.3f }, { 'a', 4 } };
    D d = { 1, 'b', 5.5f };

#if 0
    CtoD( c, d );
#else
    DtoC( d, c );
#endif

    std::cout<<"C="<<c.a.a<<" "<<c.a.b<<" "<<c.b.a<<" "<<c.b.b<<std::endl;
    std::cout<<"D="<<d.a<<" "<<d.b<<" "<<d.c<<std::endl;
}

函数 CtoDDtoC 做同样的事情,但方向相反。更改一种结构需要同时更改它们。

为了尽量减少出错的可能性并避免重复,我想实现某种映射,我只定义一次连接,然后将一个值复制到另一个值。这样,如果结构发生变化,则只需要进行一次更改。

那么,问题是:怎么做?是否有我可以使用的设计模式?


我的真实结构有数百个字段。以上只是简化的例子。

最佳答案

在您的文字示例中,我认为不值得麻烦。只需编写测试即可确保您的转换工作顺利。

在你的真实代码中,如果你的结构有“数百个字段”,你的结构可能设计得很糟糕。也许它们应该由更小的物体组成。我从来没有设计过任何需要完全相同的结构对象中的数百个字段的东西 - 相反,这些字段允许某种分类,以便它们可以在更小的串中进行处理。

由于您的代码是遗留并且您不想重写它,只需为您的转换函数编写测试,正如我在上面的示例中所说的那样。

经过良好测试的代码不再是遗留代码。遗留代码基本上是您没有对其进行自动化测试的代码。

如果重写它不是一个选项,那么测试它是必须的。

关于“双向”测试的成本,Idan Arye 的 comment below说明一切:

Since the conversion is symmetric, testing it both ways is not that much more work than testing it one way. All you need to do is init two structs - C c and D d - and set them to be the converted versions of each other. Then you just have to check that CtoD(c)==d and DtoC(d)==c (or use comparison functions if you happen to have them defined). The big work here is initializing c and d - but you would have to do that anyways if you wanted to test one way conversion, so adding the test for the other way is very cheap.

关于c++ - 如何在不重复代码的情况下统一实现双向转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19377612/

相关文章:

c++ - 查找轮廓上凸点的索引

ruby-on-rails - Rails - 用一个链接更新多个资源条目

design-patterns - 函数式语言和像 MVC 这样的编程模型是否只是下一个流行趋势?

c# - 关于数据结构设计的问题

c++ - 为什么从 Windows 启动时程序会运行而不是命令提示符?

c++ - 是否所有虚函数都需要在派生类中实现?

javascript - 避免 namespace 污染的模式

java - 为什么我的 get 方法没有将分配的值返回给我的键?

java - 使用什么数据结构来存储 <String, String> 类型的键值对?一键多值

c++ - 关于对内存泄漏的第 3 方 DLL 进行沙盒处理