复合模式的正确使用

Correct usage of composite pattern

我目前正在学习软件工程课程(我必须学习)。 我们有一大堆任务需要我们使用 Java 中的设计模式。通常我只是一个 PHP 开发人员,所以我在 Java 方面的技能并不多,这可能是个问题。

具体问题是:我们必须使用复合模式来解决以下问题:创建一个数学框架来求解项。术语可以是数字(双精度)或连接两个术语的“/”、“-”,或者使用一个术语的 "sin"。

我必须创建一个 UML Class 图。 这是哪个

我不确定这是否正确。关于我的 class 图,我遇到的两个主要问题是:

  1. 使用 value 和 first/second 是否正确,因为它们只有 1 或 2 个术语,或者我应该用 add 方法列出并确保有正好是列表中的 1/2 项?
  2. 我是否应该为复合结构(Sin、Divide、Subtract)创建另一个接口

我做得对吗,还是遵循了 bad/wrong 方法?

谢谢

伯恩德

复合模式确实对如何表示复合节点的子节点没有任何限制。在您的情况下,您可以让 类 代表一元和二元运算,或者为每个运算单独设置 类。

第二个选项看起来像:

interface Term {
    double getValue();
}

class Constant implements Term {
    private double value;
    public double getValue() {
        return value;
    }
}

class Divide implements Term {
    private Term numerator;
    private Term denominator;
    public double getValue() {
        return numerator.getValue() / denominator.getValue();
    }
}

这可能是您的 UML 的最接近表示。在这种情况下,将子术语建模为 List.

没有任何优势

我提到的另一个选项(我不推荐)是有 UnaryOperationBinaryOperation 类,然后为操作定义和 enum。在这种情况下,操作枚举将包含实际的计算逻辑。我认为这对您的需求来说过于复杂,除非您有大量操作。

抱歉,这不是复合模式的正确实现。如果您查看它,您会发现您没有 Composite(具有 add、remove 和 getChild 方法的对象)class,并且您正在聚合 Leaf 对象,而您不应该这样做。

如果您要将复合模式应用于此问题,您需要想出一个 class 包含要执行的不同操作。

因此,首先创建一个名为 FrameworkItem 的抽象 class。这对应于 Composite 模式图上的 Component。由此推导出另一个class,叫做Term。这是您的组合,并且是 FrameworkItem 的集合。 (确保它包括您的添加、删除和 getChild 方法。)最后,从 FrameworkItem 中单独派生您的 Leaf classes(Number、Sin、Subtract、Divide 等)同样,使用简单的关联而不是聚合。

请记住,您的 Composite 的 solve() 方法需要将一个 Leaf 对象作为参数,该对象告诉它需要调用其子对象的哪一个 solve() 方法。