0

我目前正在使用 Oracle 的 ADF Faces JSF 实现表示层的遗留系统。该系统依赖于规则引擎来根据用户与它们的交互或输入的值来使某些表单元素成为必需、禁用甚至突出显示。

在当前阶段,应用程序正在“工作”,有点。当前处理规则引擎和前端更新的实现不是很优雅,并且由大量的 if 语句组成,类似于:

if(screenObj instanceof CoreInputText) {
    ((CoreInputText) screenObj).setDisabled(true);
}

为了使混合更复杂,我们还混合了我们自己的对象,因此整个集合不共享一个共同的祖先,从而消除了我们执行以下操作的选项:

((CommonAncestor) screenObj).setDisabled(true);

问题是是否值得重新编写这部分代码以使其更清晰。由于大多数屏幕元素都是 ADF Faces 元素,我们不能/不允许更改它们的祖先以添加其他方法。

代码更改的目标有两个:清理旧代码并改进代码库,以便添加新元素或控件不会导致大的代码更改(特别是存在于许多地方的 if 语句) .

那么,如果我们继续进行这种改变,那将是实现我们正在寻找的更好的选择?子类化所有元素(每次我们使用另一个预先存在的控件时都需要一个新类)或实现装饰器模式?我对装饰器的唯一担心是它仍然需要为每个附加元素更改代码。这两个选项似乎都可以减少代码更改,因为包含这些 if 块的多个方法不需要更新。

除了子类化和装饰器之外,任何有关处理此类情况的方法的输入都是受欢迎的!

4

1 回答 1

1

尽管它们没有共同的祖先,但您无需指定它们是否具有共同的方法。如果他们这样做了,那么也许只是在运行时使用只调用该方法的代理放入一个接口,这样你就有一个通用类型。当然,这是一种装饰器,由于它使用反射,它可能太慢(尽管可能不会),但它具有任何新对象只需实现正确的方法签名(或者可能让新对象实现接口,并为旧对象保留代理,并在工厂方法中有条件地创建代理,以检查对象是否需要它)。

此外,如果这是一个真正的 setter,您可以使用 apache 的 BeanUtils 并将其设置为一个名为 disabled 的属性。

编辑:鉴于它们没有相同的方法,每次添加新对象时都必须添加一些代码,除非您至少可以控制前进的新对象将具有已定义的接口。话虽如此,如果您愿意沿着反射路线走下去,您可以创建一个类到方法的映射(前提是这些方法都采用布尔值 - 如果必须的话,您甚至可以强制绕过它)并查找对象在地图中。这样,当您引入一个新对象时,您只需要在地图中添加一个条目。

但是,我倾向于避免这种情况,因为这似乎太过分了。这使得方法名称很难重构,并且 IDE 无法确定它们是在该上下文中使用的。我认为装饰器乍一看是正确的选择,因为在没有任何其他考虑的情况下,组合应该优先于继承,它将为正在发生的事情提供更清晰的代码路径,从长远来看可以改善维护。

于 2009-08-26T02:05:32.477 回答