复合设计模式能否避免Collection(列表,哈希表)数据结构?

时间:2019-05-13 17:35:26

标签: java design-patterns uml composite

在查看代码时,我想全面理解“复合设计模式”的所有可能类型。在这段代码中,我有一个复合对象PeanutButterAndJellySandwich,其中包含BreadPeanutButterJelly

PeanutButterAndJellySand的字段变量都是食物类型的原因是为了计算卡路里

interface Food{
    int calories = 9000;
}


class Bread implements Food{
    private String flour;
    private String salt;

}

class Jelly implements Food{
    private String fruit;
    private String sugar;
}

class PeanutButter implements Food{
    private boolean crunchy;
}

class PeanutButterAndJellySandwich implements Food{
    private Food bread;
    private Food jelly;
    private Food peanutButter;

    public void setBread(Bread bread){this.bread=bread;}
    public void setJelly(Jelly jelly){this.jelly=jelly;}
    public void setPeanutButter(PeanutButter butter){this.peanutButter=butter;}
}

这是遵循“复合设计模式”还是PeanutButterAndJellySandwhich需要类似foodItems:ArrayList<Food>的内容。 UML图看起来非常相似。

UML Diagram

我之所以这样问,是因为经过大约5个小时的搜索后,我在任何地方都没有找到明确指出的内容,在类似嵌入式系统的应用中,由于内存/存储空间有限,我们可能不需要收集数据结构。但是,所有在线示例都利用多种形式的列表。

3 个答案:

答案 0 :(得分:3)

根据我的理解,复合模式旨在允许您使用运行时多态性来忽略组件(在您的情况下为BreadJellyPeanutButterAndJellySandwich等)和它们的层次结构之间的差异。最有可能的。这意味着让以统一的方式(最有可能通过循环)处理它们,并让运行时执行休息

因此,由于您的示例并未显示此意图并手动处理了此意图,所以我想说这不是复合模式,而是运行时多态的简单使用(计划)。

但是,您的代码确实抓住了PeanutButterAndJellySandwichFood的地步,从而使将来可能的使用(例如,具有成分PeanutButterAndJellySandwich的{​​{1}})成为复合模式的目标。 (但是您没有在代码中显示此意图。)


p.s。

  1. 但是设计模式并不是神圣的。它们只是作为指导,而不是限制。

  2. 我会说这个问题本身没有多大意义,因为设计模式并不是要节省内存,而是要促进良好的系统设计。因此,它们以通用方式进行描述,以便于描述和理解。

答案 1 :(得分:3)

复合模式用于创建树结构。如果是三明治,那没有什么意义。您只有Ingredients的一个简单层(列表)。除了要将三明治作为三明治的一部分。对我来说,您的设计就是坏了。在适用的地方使用模式。不要使用模式,因为它们存在。

答案 2 :(得分:0)

严格来讲,按照 Gamma,Helm等人的方法合成图案。等人。确实谈到了通过接口(在您的情况下为Food)来操纵子项,这往往会导致您实现一种实现,在该实现中,可以将任意数量的子项添加到(从中删除)任何节点。复合树。典型的实现可能包括一个抽象的超类,该超类将实现子级管理(添加,删除等),然后具体的子类型将派生出来。像这样的东西:

enter image description here

我正在这里进行设计选择,但要旨是正确的。

更广泛地讲,组成并不一定要实现复合模式。没有成分就可以使用合成,实际上,有一个原理也由Gamma,Helm等人讨论过。 。讨论的是偏重于继承而不是继承,这与复合模式本身无关。

使用继承作为在程序中重用代码的便捷方法很诱人,但这实际上并不是继承的意义,这就是为什么偏爱使用组合来防止滥用继承和创建难以管理的代码的原因。我担心在使用Food接口获取Calories成员变量时可能会出现这种情况。如果您不打算泛化设计,即想在设计时(在代码的结构中)具体说明 PeanutButterAndJellySandwich 所包含的内容,那么您可能应该做的是在 PeanutButterAndJellySandwich 使用其具体类型。毫无疑问,它们是 Food ,但是考虑一下 PeanutButterAndJellySandwich 与所有声明为 Food 的成员变量有什么关系?为什么不使用一系列食物呢?