1

我的应用程序是用于连接“模块”(通过模块端口)的编辑器。端口有端口类型。每个端口类型都有其关联的比较器。如果它们的属性满足比较器中实现的规则,则两种类型是兼容的。

我希望用户通过实现新的端口类型和如何连接它们的规则来扩展应用程序(通过 eclipse 扩展点基础设施)。

这意味着在运行时我只能与端口类型接口进行交互。没有具体的类是已知的。所有具体的实现都由工厂返回。

我实现了这两个接口:

public interface IPortType {
    [many attributes]
}
public interface IComparator {
    public boolean isCompatible(IPortType source, IPortType target);

    // more interaction methods!
}

我目前的解决方案有点难看,因为通用 isCompatible(IPortType source, IPortType target) 方法是一种委托,必须在所有子类中重写。简单地重载 isCompatible() 方法在这里不起作用。

但更大的缺点是违反了开闭原则:当应该支持一种新类型时,必须扩展所有具体的 Comparator 类。但是,当类型之间有更多的交互(如转换等)时,如何保持规则类的数量较少?我的意图是在一类中保留一种类型的所有规则。

一个具体的比较器示例:

public class ATypeComparator implements IComparator {

    public boolean isCompatible(IPortType source, IPortType target) {
        if (!(source instanceof AType))
            return false;
        if (target instanceof BType)
            return isCompatible(source, (BType) target);
        if (target instanceof CType)
            return isCompatible(source, (CType) target);
    }

    public boolean isCompatible(AType source, BType target) {...}
    public boolean isCompatible(AType source, CType target) {...}
}

你将如何解决这个问题?

感谢您的任何建议!

4

2 回答 2

1

我认为 IPortType 实现决定它是否与其他 IPortType 实现兼容是不正确的。这不是其责任的一部分。

一个简单的解决方案是创建一个单独的公共静态方法,例如在 PortTypeManager 类中,它知道两个 IPortType 实现是否兼容。这样,您始终可以添加新类型,并且只需在一个地方更改逻辑以适应该新类型。

然而,最终,这也不够,因为该方法应该覆盖的案例数量会像 n^2 一样增长。您需要为每个 IPortType 实现提供 getVersion() 或 getSignature() 之类的方法,该方法返回一段数据,您可以将其与类似的数据进行比较,以确定两个实现是否兼容。

于 2010-01-09T16:42:33.013 回答
0

如果您允许多态性来处理复杂性,您的实现似乎可以被清理。

.compatibleTo()有一个方法会不会更简单IPortType?如果你能做到这一点,每个实现都可以从本质上知道它支持的端点它可以支持什么?

类似于以下内容:

IPortType port1 = ...
IPortType port2 = ...

if (port.compatibleTo(port2)) {
    // do whatever
}
于 2010-01-09T16:44:51.373 回答