通过组合添加类功能
假设我们有一个抽象类 Element
,Triangle
和 Quadriside
类是从该抽象类派生出来的。
假设这些类与依赖于元素形状的插值方法结合使用。因此,基本上我们创建了一个抽象类 InterpolationElement
,从中派生出 InterpolationTriangle
和 InterpolationQuadriterior
。
然后,为了在 Triangle
和 Quadriside
类中包含插值功能,我们在 Element
类型的类 Element
中添加一个常量引用数据成员>InterpolationElement,即:
class Element
{
public:
Element(const InterpolationElement& interp);
const InterpolationElement& getInterpolation() const;
private:
const InterpolationElement& interpolation;
};
然后我们创建一个方法(如 Scott Meyers,Effective C++ 中所述),将 InterpolationTriangle
类的本地静态对象实例化为
const InterpolationTriangle& getInterpolationTriangle()
{
static InterpolationTriangle interpolationTriangle;
return interpolationTriangle;
}
该类 Triangle< /code> 可以这样构造:
class Triangle : public Element
{
public:
Triangle() : Element( getInterpolationTriangle() ) {}
};
这是我的问题:为了在我的类 Element
上合并插值方法,这种方法是否正确?这是在专业场景中使用的吗?
我可以直接在 Element
类(作为纯虚拟)上实现所有插值方法,并在派生类 Triangle
和 Quadriside
中覆盖它们。然而,在我看来,这种方法很麻烦,因为每次我需要改进或实现新的插值功能时,我都必须在这些类上执行此操作。此外,使用这种方法,类会变得越来越大(有很多方法)。
我想听听您的一些提示和意见,
提前致谢。
其他详细信息:
class InterpolationElement
{
public:
InterpolationElement();
virtual double interpolationMethod1(...) = 0;
:
virtual double interpolationMethodN(...) = 0;
}
class InterpolationTriangle : public InterpolationElement
{
public:
InterpolationTriangle () {}
virtual double interpolationMethod1(...) { // interpolation for triangle }
:
virtual double interpolationMethodN(...) { // interpolation for triangle }
}
class InterpolationQuadrilateral : public InterpolationElement
{
public:
InterpolationTriangle () {}
virtual double interpolationMethod1(...) { // interpolation for quadrilateral}
:
virtual double interpolationMethod1(...) { // interpolation for quadrilateral}
}
Suppose we have an abstract class Element
from which classes Triangle
and Quadrilateral
are derived from.
Suppose yet that these classes are used in conjunction with interpolation methods that depend on the shape of the element. So, basically we create an abstract class InterpolationElement
from which we derive InterpolationTriangle
and InterpolationQuadrilateral
.
Then, to include the interpolation functionality in the Triangle
and Quadrilateral
classes, we add a const-reference data member in class Element
of type InterpolationElement
, that is:
class Element
{
public:
Element(const InterpolationElement& interp);
const InterpolationElement& getInterpolation() const;
private:
const InterpolationElement& interpolation;
};
We then create a method (as described by Scott Meyers, Effective C++) that instanciate a local static object of class InterpolationTriangle
as
const InterpolationTriangle& getInterpolationTriangle()
{
static InterpolationTriangle interpolationTriangle;
return interpolationTriangle;
}
So that class Triangle
can be constructed like:
class Triangle : public Element
{
public:
Triangle() : Element( getInterpolationTriangle() ) {}
};
Here is my question: is this approach correct in order to incorporate interpolation methods on my class Element
? Is this used in professional scenarios?
I could implement directly all the interpolation methods on class Element
(as pure virtual) and the override them in the derived classes Triangle
and Quadrilateral
. However, this approach seems to me to be cumbersome, since every time I need to improve or implement new interpolation functionalities I would have to do that on these classes. Moreover, the classes get bigger and bigger (many methods) using this approach.
I would like to hear from you some tips and comments
Thanks in advance.
Additional details:
class InterpolationElement
{
public:
InterpolationElement();
virtual double interpolationMethod1(...) = 0;
:
virtual double interpolationMethodN(...) = 0;
}
class InterpolationTriangle : public InterpolationElement
{
public:
InterpolationTriangle () {}
virtual double interpolationMethod1(...) { // interpolation for triangle }
:
virtual double interpolationMethodN(...) { // interpolation for triangle }
}
class InterpolationQuadrilateral : public InterpolationElement
{
public:
InterpolationTriangle () {}
virtual double interpolationMethod1(...) { // interpolation for quadrilateral}
:
virtual double interpolationMethod1(...) { // interpolation for quadrilateral}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这些类与插值方法结合使用。为什么这些方法需要位于单例对象中?这里的单例看起来很有问题。
另外,欢迎来到SO!
The classes are used in conjunction with interpolation methods. Why do those methods need to be in a singleton object? The singleton here looks very problematic.
Also, welcome to SO!
这让人想起我回答过的一个问题 在这里。关于数据容器和策略分离的想法相同。
This is reminiscent of a question that I had answered here. The same idea about the separation of data containers and the strategies.
您的提案有一个小问题:您在基类中添加了一个与插值相关的方法,并且更改了构造函数...
所以首先,如果您希望这样做,那么您应该这样做it:
这里有 2 个优点:
但是,这仍然需要更改
Element
类及其每个派生类。这不打扰你吗;)?好吧,是时候(这一次)调用设计模式了:
Visitor
。和策略思路有点不一样,依靠双重调度才能正常工作。但是,它允许您一次性调整
Element
的层次结构(使用accept
方法),然后添加任意数量的操作。那太好了。There is one little issue with your proposal: you have added an interpolation related method to your base class and you've changed the constructor...
So first of all, if you wish to do it this way, here is how you should do it:
There are 2 advantages here:
const
, which allows it to maintain state during the computation... like a reference to the current object being interpolated.However, this still requires to change the
Element
class, and each of its derived classes. Doesn't it bother you ;) ?Well, it's time (for once) to call upon a Design Pattern:
Visitor
.It's a little different from the strategy idea, relying on double dispatch to work properly. However it allows you to tweak the hierarchy of
Element
s ONCE (with anaccept
method) and then to add as many operations as you wish. And that is great.您总是可能会弄乱模板。
首先我们有一个顶级班级。
...但是我们在层次结构的中间还有一个类,它实际上是一个模板。模板不能是顶级类,因为具有不同参数的模板是不同的类。我们的想法是,我们将插值类作为元素的类型参数。
和插值类。请注意,他们不是兄弟姐妹,因为他们不需要。
最后是真正的元素和小主要程序。
摘要:
方法是使用静态方法,并在 Element_Impl 中定义包装器 - 仍然只在一个地方。
You can always mess a little bit with templates.
First we have a top class.
... but then we also have a class in the middle of the hierarchy which is actually a template. Template can't be the top level class, as templates with different parameters are different classes. The idea is that we give an interpolation class as a type parameter to the element.
And interpolation classes. Notice, they aren't siblings, because they don't need to.
And finally the real elements and the small main procedure.
Summary:
One way is to use static methods, and defining a wrapper in Element_Impl - still only in one place.
我首先想到的是 GoF 设计模式访问者
根据我对你的问题的理解,这种模式正是为了解决这个问题而设计的。
每个访问者对象都定义了一种插值技术或应用于您的对象的算法。
因此,Element 类根本不会随着每个新功能而增长。一旦到位,访问者模式就可以丰富功能,而无需触及基类定义。
What first comes to my mind is the GoF Design Pattern Visitor
From what I understand of your problem, this pattern is conceived to exactly solve this issue.
Each Visitor object defines an interpolation technique, or an algorithm to apply to your object.
Thus the Element class doesn't grow at all with each new functionnality. Once in place, the Visitor pattern enables to enrich functionnality without touching to the Base class definition.