当只能更改一侧时重构紧密耦合的类
Refactoring tightly coupled classes when only one side can be changed
请提前接受我对这个有点冗长的问题的道歉。这是我能想到的最小的自包含示例......我很确定这个问题一定有一些明显/漂亮/整洁的解决方案,但我目前看不到它。
好的,问题来了:想象一下以下情况(注意,代码的可编译版本可在 http://goo.gl/dhRNex 获得(。假设
struct Thing1 {
public:
void bar(class Implementation1 &i) {
i.baz();
}
// ...various other methods like bar()
};
struct Thing2 {
public:
void bar(class Implementation2 &i) {
i.qux();
}
// ...various other methods like bar()
};
被给予。不幸的是,这些类是固定的,即不能更改/重构。
但是,Implementation1
和Implementation2
是可变的。这两个类共享许多相似的代码,因此将共享代码放在公共基类中似乎是很自然的。但是,代码依赖于所使用的Thing
类型,但是Thing1
和Thing2
没有通用的基类,因此使用模板似乎也很自然。因此,我为基类提出了以下解决方案
template<class T, class S>
struct ImplementationBase {
public:
S *self;
void foo() {
T thing;
thing.bar(*self);
}
// ...lots more shared code like foo()
};
和具体实施
struct Implementation1 : public ImplementationBase<class Thing1, class Implementation1> {
public:
Implementation1() {
self = this;
}
void baz() {
std::cout << "Qux!" << std::endl;
}
};
struct Implementation2 : public ImplementationBase<class Thing2, class Implementation2> {
public:
Implementation2() {
self = this;
}
void qux() {
std::cout << "Qux!" << std::endl;
}
};
理想情况下,人们会在foo
中使用this
而不是self
,但问题是this
是ImplementationBase<class Thing1, class Implementation1>
类型,但Implementation1
是必需的。显然,整个事情相当混乱,Implementation
和Thing
类耦合得太紧密,但是如果不能够重构Thing
类,我就看不到一个简单的出路。所以,最后,我的问题是:
- 除了使用上面的
self
技巧之外,有没有更好的选择? - 有没有一种设计可以更好地解决这个问题?(我有一种感觉,有,但我错过了一些明显的东西(
如果您已经做到了这一点,非常感谢您抽出宝贵时间阅读整个故事,并为这个冗长的问题再次道歉。
你已经在使用 CRTP,所以你根本不需要自我:
template<class T, class S>
struct ImplementationBase {
public:
S* getThis() { return static_cast<S*>(this); }
void foo() {
T thing;
thing.bar(*getThis());
}
// ...lots more shared code like foo()
};
相关文章:
- 如何重构类层次结构以避免菱形问题
- Visual studio代码重构似乎不起作用(例如,重命名符号-f2)
- C++-将具有引用的长参数列表重构为结构
- 重构使用动态强制转换的 std::set 的比较运算符
- C++中的命名空间重构
- 将具有相反操作数的两个函数重构为一个
- 将耦合类拆分为单独的标头
- 重构模板类,该类将其嵌套类用作另一个类的模板参数
- 我当前实现的双向链表类是否需要重构迭代器 end() 功能?
- C++重构,扩展方法typedef
- 重构类:无法将派生类中成员函数的公共代码移回基类
- 重构MFC消息映射以包括完全限定的成员函数指针
- 重构建议?
- 在Visual Studio本机单元测试中,是否可以将单元测试耦合到项目?
- 包装器函数可以重构吗?
- 重构此代码以进行优化
- 将 Arduino 草图重构为 C++ 类
- C++紧密耦合的模板定义,无限重复的模板参数
- 重构为模板类
- 当只能更改一侧时重构紧密耦合的类