gpt4 book ai didi

c++ - 如果复合模式中的每个复合项目都有许多自己独特的属性,可以吗?

转载 作者:行者123 更新时间:2023-11-28 05:50:14 27 4
gpt4 key购买 nike

典型的复合模式书籍显示了更精简的示例(显然),其中所有复合项目都有些相关,并且经常使用一个通用方法名称进行说明,例如文件夹和文件示例中的 name()

我在项目中部署了复合模式,它在树状结构中的“整体-部分关系”中很有意义。然而,它们实际上只有两个共同的属性(=方法),它们的其余属性或每个节点的属性虽然相关但完全不同。

因此,我最终为基础 CompositeItem 类中的每个派生类型提供了很多特定函数,我的意思是我用以下示例说明的 10 到 15 个方法。

class CompositeItem
{
CompositeItem();

// common methods, applies to all derived classes
virtual void hello();
virtual void foo();

// these apply only to derived1 class
virtual void method1();
virtual void method2();
virtual void method3();
virtual void method4();
virtual void method5();
virtual void method6();
virtual void method7();
virtual void method8();
virtual void method9();
virtual void method10();

// these applies to only derived2 class
virtual void method11();
virtual void method12();
virtual void method13();
virtual void method14();
virtual void method15();
virtual void method17();
virtual void method17();
virtual void method18();
virtual void method19();
virtual void method20();

// these applies to only derived3 class
virtual void method21();
virtual void method22();
virtual void method23();
virtual void method24();
virtual void method25();
virtual void method26();
virtual void method27();
virtual void method28();
virtual void method29();
virtual void method30(;)

// these applies to only derived4 class
virtual void method31();
virtual void method32();
virtual void method33();
virtual void method34();
virtual void method35();
virtual void method36();
virtual void method37()
virtual void method38();
virtual void method39();
virtual void method40();
}

由于我还没有真正看到复合 Material 在这种规模上的运作,所以我正在寻找验证,这听起来正常还是有任何危险信号?

我知道我没有包含关于项目的太具体的信息,但考虑到所有项目仅共享 2 种方法,但每个项目都有 10 到 15 种不同的方法,仅针对该派生项目,这听起来不错并且总体上符合模式吗?

更新 1

我拥有这些 amy 函数的原因之一是因为我需要这些函数来检索每个派生类类型的不同属性或特性。我注意到的一件事是,将事物填充到复合 Material 中很容易,但当您需要每次检索特定信息并将其显示在 View 中时就没那么容易了 - 这就是我正在做的事情。

我的应用程序在树中留下了所有这些东西的 View 。我确实需要在 View 的右 Pane 中显示有关每个节点(=子类)的特定/唯一信息。如果 composite 不适合,是否有其他适合的模式?

更新 2

我可以通过以下方式总结我对合成的困境(请注意即时编写的代码,请原谅错别字):

class CompositeItem 
{
virtual void add(CompositeItem *item);
};

class Species : public CompositeItem
{
QList< CompositeItem *> species;
}

class Mammals: public CompositeItem
{
QList<CompositeItem *> mammals;
// assume I have 10 methods here for various attributes about mammals

}

class Tiger: public CompositeItem
{
// assume I have 10 methods to various specific attributes about tigers

}

CompositeItem * species = new Species;

CompositeItem * mammals = new Mammals( lives_on_land, has_4_legs, etc);

CompositeItem * tiger = new Tiger(eats_meat, hunts_alone, etc);

mammals->add(tiger);
species.add(mammals);

现在您可以看到,当我创建一个物种或组时,我可以直接访问它并且可以设置它的所有属性。

问题是一旦我将该项目添加到 Composite 容器并关闭,现在当我需要稍后处理该项目时,我必须将其作为 CompositeItem * 指针处理。这意味着我要么必须键入 cast(我假设不好),要么使用特定于该项目的虚拟方法到基类来访问它。这是我的问题!虚函数太多了!

我想添加上面的内容以提供更好的图片并显示我的问题的确切性质,以及是否可以为这种情况提供更好的解决方案。谢谢!

最佳答案

复合模式是用来统一处理对象和对象集合的,当你想显示对象的层次结构而不关心具体的集合(树,列表,图,...)而不关心内容(您的 CompositeItem 接口(interface)后面的具体类)。

在这里,您的 CompositeItem 接口(interface)似乎只是许多具有一些共同点的派生类的基类,集合的概念并不真正存在。从这个意义上说,复合模式不太适合;但是,此时无法确定您的派生类中的一个是否是集合。

现在你问的是获取多个虚方法的接口(interface),其中一些涉及每个类,很多只涉及一个派生类是否正常?

不,这是一种代码味道。您应该从您的界面中删除“特定方法”,因为它们没有意义并且会污染您的界面。

但您的目的仍然是通过 compositeItem 接口(interface)操作其中的许多对象,但要借助许多特定方法?对吧?

问题是您的所有特定内容无法在新的接口(interface)方法下重新组合,并且您不想依赖 dynamic_cast 和其他 RTTI 方法来实现您的目标。

那么怎么做呢?

您必须解耦您要应用的算法的对象层次结构。 Composite/Visitor 对完全满足这个目的。

访问者模式将统一地抓取您的 TreeView,从一个项目到另一个项目,允许您使用 CompositeItem 接口(interface)方法,或者这些项目的特定内容。

唯一的缺点是您必须将一些派生类逻辑分发给访问者类

编辑: https://sourcemaking.com/design_patterns/visitor

关于c++ - 如果复合模式中的每个复合项目都有许多自己独特的属性,可以吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35416353/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com