4

特别是在 C++ 中,但也通常作为一种 OO 设计原则,这样做有什么问题吗?是在实践中完成的吗?如果它显示出明显的设计缺陷,有什么好的替代方案?有什么优势吗?

class Property {};
class CompositeProperty : public Property 
{
    ...
    private:
        std::vector<Property> m_properties;
};

那么具体来说,派生类可以包含基类对象吗?

由于我有一些背景知识,我已经看到这用于建模/镜像 XML 结构,但感觉该设计有点面对通常努力的 is-a-is-inheritance 和 has-a-is-composition 关系。

4

5 回答 5

6

设计上没有瑕疵——事实上,这种设计距离广为人知且非常有用的复合图案仅一步之遥。但是,在执行过程中存在重大缺陷。

CompositeProperty聚合 的实例Property,而不是聚合指针。这会扼杀使用多态元素的能力CompositeProperty。为了解决这个问题,您需要用指针向量(最好是智能指针)替换实例向量。

复合模式的一个经典地方是表达式树的表示:您从一个抽象基开始,然后添加常量、变量、函数调用、一元表达式、二元表达式、条件等的表示。常量和变量等表达式不引用其他表达式,而一元表达式、二元表达式和函数调用等表达式则可以。这使得对象图具有递归性,让您可以表示任意复杂度的表达式。

于 2012-08-10T11:08:54.530 回答
2

那么具体来说,子类可以包含父类对象吗?

简而言之YES

于 2012-08-10T11:06:11.850 回答
2

请看一下复合模式

当客户应该忽略对象组合和单个对象之间的差异时,可以使用组合。如果程序员发现他们以相同的方式使用多个对象,并且通常有几乎相同的代码来处理每个对象,那么复合是一个不错的选择;在这种情况下,将基元和复合体视为同质的并不那么复杂。

于 2012-08-10T11:06:32.257 回答
2

没有什么问题。

以这个例子(它是 C#,但应该足够简单)为例,您定义了两个子类,每个子类都包含一个继承的实例:

public class Person
{
    public string Name;
}

public class MalePerson : Person
{
    public Person BestFriend;
}

public class FemalePerson : Person
{
    public Person BestFriend;
}

根据我的经验,在子类中包含超类的实例最常用于对异构对象之间的层次结构进行建模,或者使用尽可能少的假设来引用对象。

于 2012-08-10T11:10:51.097 回答
2

完全没有问题,但您可能需要考虑使用指向基类/父类的指针。这允许对象的多态行为。如果您将派生类的实例原样添加到您的向量中,您将遭受对象切片的影响。

于 2012-08-10T11:11:04.647 回答