我有一个类 item
。此类的每个实例都是 3D 空间中的对象,可以是基本形状,如圆柱体、球体 和圆锥体。 类 Item
为几何(半径、顶部半径、底部半径、长度)和转换(旋转、平移、缩放)提供了方便的 API .
enum ItemType {
Sphere = 1,
Cone
}
class Item
{
// ...
public:
ItemType type();
void setType(const ItemType &t);
float radius();
float length();
float topRadius();
float botRadious();
QMatrix4x4 transformations();
void setRadius(const float &r);
void setLength(const float &l);
void setTopRadius(const float &tr);
void setBotRadius(const float &br);
void setTransformations(const QMatrix4x4 &matrix);
// ...
}
我经常想将多个对象粘在一起形成一个统一的形状。例如,下面连接了两个球体和一个圆锥体。统一对象的几何形状和变换取决于两个球体和一个圆锥体。
问题是:
- 统一对象的方便处理是不可能的
- 我所说的处理是指,例如,转换。如需要改变统一物体的长度,相应地改变中间锥体的长度和两个球体的位置。
class Item
有方便处理每个单独对象的 API,但不是统一对象- 为了处理统一的对象,我不得不处理三个不同的对象,这很折磨人
问题是:
哪些设计模式最适合方便地处理统一的对象?
最佳答案
注:本题是关于面向对象的软件设计和软件模式的,与C++无关。唯一特定于 C++ 的部分是 virtual
关键字的使用,但即便如此,也只是为您提供多态性的特定于 C++ 的关键字,这又是一个面向对象的原则,而不是什么C++ 独有。
因此,您首先需要做的是为您所谓的“API”提取一个真正的接口(interface)。我将其称为 Primitive3D
,它将是一个 类
,只包含纯虚拟方法。 (在 C++ 中,这将是 virtual function(parameters) = 0
。)
然后,您的每个原语都将通过为每个纯虚拟方法提供一个实现来实现该接口(interface)。如果您有一些所有实现都将共享的基本功能,那么除了实现此接口(interface)之外,您还可以保留一个公共(public)基类。但是,界面的引入将使您的选择更加开放。
然后,引入一个新的原语,可能叫做Conglomerate
。同样,这将是另一个实现 Primitive3D
的类。该类将提供自己的实现来设置各种属性,如长度和转换,这些实现将通过设置包含的基元的一些属性来工作。
Conglomerate
类还将提供一些特定于它的函数,并且在 Primitive3D
接口(interface)中找不到。您将使用这些函数来配置企业集团,至少用其内容填充企业集团。
将新成员原语添加到集团的函数可以接受额外的参数来精确指示新成员应该出现在集团的哪个位置,缩放原语时要执行什么样的转换,要执行什么样的转换翻译原语等时
在内部,集团可能会使用包含某些内部成员
结构实例的vector
,它会包含对Primitive3D
的引用> 以及了解如何处理该原语所需的任何其他信息。不要错误地将此信息添加到 Primitive3D
本身,它不属于那里,因为图元不知道,也不应该知道它是集团的成员。我什至会说原始的位置不是原始本身的特征;它是包含原始空间的一个特征,无论这个空间是宇宙,还是一个团 block 。
关于c++ - 处理对象组的设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58429409/