复合模式的正确使用
Correct usage of composite pattern
我目前正在学习软件工程课程(我必须学习)。
我们有一大堆任务需要我们使用 Java 中的设计模式。通常我只是一个 PHP 开发人员,所以我在 Java 方面的技能并不多,这可能是个问题。
具体问题是:我们必须使用复合模式来解决以下问题:创建一个数学框架来求解项。术语可以是数字(双精度)或连接两个术语的“/”、“-”,或者使用一个术语的 "sin"。
我必须创建一个 UML Class 图。
这是哪个
我不确定这是否正确。关于我的 class 图,我遇到的两个主要问题是:
- 使用 value 和 first/second 是否正确,因为它们只有 1 或 2 个术语,或者我应该用
add
方法列出并确保有正好是列表中的 1/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
.
没有任何优势
我提到的另一个选项(我不推荐)是有 UnaryOperation
和 BinaryOperation
类,然后为操作定义和 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() 方法。
我目前正在学习软件工程课程(我必须学习)。 我们有一大堆任务需要我们使用 Java 中的设计模式。通常我只是一个 PHP 开发人员,所以我在 Java 方面的技能并不多,这可能是个问题。
具体问题是:我们必须使用复合模式来解决以下问题:创建一个数学框架来求解项。术语可以是数字(双精度)或连接两个术语的“/”、“-”,或者使用一个术语的 "sin"。
我必须创建一个 UML Class 图。 这是哪个
我不确定这是否正确。关于我的 class 图,我遇到的两个主要问题是:
- 使用 value 和 first/second 是否正确,因为它们只有 1 或 2 个术语,或者我应该用
add
方法列出并确保有正好是列表中的 1/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
.
我提到的另一个选项(我不推荐)是有 UnaryOperation
和 BinaryOperation
类,然后为操作定义和 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() 方法。