我有两个类似的类.你会使用什么设计来分解代码
I have these two similar classes. What design would you use to factorize code?
我有一个相当复杂的类似图形的数据结构。为了清楚起见,让我们将其简化为:
class Node;
class AbstractEdge { void foo() {} };
class Edge1: public AbstractEdge { void bar1() {} };
class Edge2: public AbstractEdge { void bar2() {} };
如您所见,我们的图与任何其他图不同:存在两种边缘,它们都继承自 AbstractEdge。此设计无法更改。现在,假设我必须按照以下方式设计两个类:
class OrientedEdge1
{
Edge1 * edge;
bool orientation;
void foo() { edge->foo(); }
void bar1() { edge->bar1(); }
}
class OrientedEdge2
{
Edge2 * edge;
bool orientation;
void foo() { edge->foo(); }
void bar2() { edge->bar2(); }
}
实际上,OrientedEdge1::foo(( 和 OrientedEdge2::foo(( 比调用单个方法要长得多,但想法是它们是相同的,只调用从 AbstractEdge 继承的方法。
你会使用什么设计来分解代码?我正在考虑三种方法:
1. 使用自由函数
foo_impl(AbstractEdge * edge) { edge->foo(); }
class OrientedEdge1
{
Edge1 * edge;
bool orientation;
void foo() { foo_impl(edge); }
void bar1() { edge->bar1(); }
}
class OrientedEdge2
{
Edge2 * edge;
bool orientation;
void foo() { foo_impl(edge); }
void bar2() { edge->bar2(); }
}
优点:
- 非常简单的解决方案,总比完全不分解要好得多。
缺点:
并非所有方法都可以作为自由函数实现。
声明代码仍然重复。
2. 使用继承
class AbstractOrientedEdge
{
AbstractEdge * edge;
bool orientation;
void foo() { edge->foo(); }
}
class OrientedEdge1: public AbstractOrientedEdge
{
Egde1 * edge1() { return static_cast<Egde1*>(edge); }
void bar1() { edge1()->bar1(); }
}
class OrientedEdge2: public AbstractOrientedEdge
{
Egde2 * edge2() { return static_cast<Egde2*>(edge); }
void bar2() { edge2()->bar2(); }
}
优点:
更多因子分解。
我不打算多态地使用这两个类,但谁知道呢,也许它们通过继承相关的事实将来可能会变得有用。
缺点:
在构造函数/setter中需要小心,以强制执行Oriented Edge1::edge始终指向Egde1*。
不知何故,static_cast感觉不对劲。
3. 使用模板
template <class EdgeT>
class OrientedEdge
{
EdgeT * edge;
bool orientation;
void foo() { edge->foo(); }
}
class OrientedEdge1: public OrientedEdge<Edge1>
{
void bar1() { edge->bar1(); }
}
class OrientedEdge2: public OrientedEdge<Edge2>
{
void bar2() { edge->bar2(); }
}
优点:
大多数因子分解。
存储在两个类中的指针具有正确的类型,无需强制转换。
缺点:
- 需要在标头中保留共享代码的实现,这强制包含 AbstractEdge.h(可以通过使用以前的方法进行前向声明来避免(。
问题:您倾向于使用哪种方法?您还有其他解决方案或建议吗?
1 和 3。
3 删除重复的样板,1 将实现移动到我想要的任何地方。
相关文章:
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 0-1背包代码中的错误.我的代码中有什么错误
- 我是C++编程的新手,这些代码之间有什么区别,我应该使用哪一个
- 不确定要在我的main中放入什么才能使我的代码正常工作
- 这行代码在C++类中意味着什么
- 使用不同的CRT将新的C++代码与旧的(二进制)组件隔离开来的最佳方法是什么
- 当无法使用模板和宏时,生成类型变体C++代码的最简单方法是什么?
- 我可以做些什么来消除或最小化这种将提供相同功能和行为的代码重复
- 以下 C++ 代码用于 -> "#define idiv(a, b) (((a) + (b) / 2) / (b))" 是什么?
- 这个带有模板<类 Vector 的C++代码片段有什么问题>
- 此代码中的操作流程是什么?C/C++.
- 当我从下面的代码中删除关键字 virtual 时,它可以正常工作,否则会出现错误。在这里"virtual"字的意义是什么?
- 此代码验证公式是什么意思?
- 这是什么代码?为什么它有效?C++
- 当您希望在Arduino Uno编程中同时执行不同函数时,使用什么代码/语句
- 这是什么代码?C或C
- 在 c++ 中应该使用什么代码而不是 getche
- 什么代码更适合用于运算符重载
- 什么代码可以使这个循环工作