【发布时间】:2012-02-01 02:27:32
【问题描述】:
我是一名新的 Java/OO 程序员。我想创建一个方法(以下称为myMethod),它根据检查输入参数和世界状态返回n 类型的对象之一。在这里说 n == 2 为简单起见:myMethod() 可以返回类型为 Foo 或 Bar 的对象。
Foo 和 Bar 有不同的方法可以调用它们,有些是专有的,有些是共同的,例如:
ReturnType? myMethod(inputs) {
if (/*examining state of world & inputs implies a Foo*/)
return new Foo();
return new Bar();
}
...
public class Foo {
public Foo() {}
public void x() {...} //common to Bar
public void f() {...}
}
public class Bar {
public Bar() {}
public void x() {...} //common to Foo
public void b() {...}
}
对于myMethod() 以及类Foo 和Bar,我应该使用什么设计模式?如果我的方法的返回类型是 Foo 和 Bar 的超类(或聚合?),或者 Foo 和 Bar 实现了一些通用接口,那么有没有办法让从 myMethod() 接收对象的客户端能够安全地调用 @987654329 @ 或 b() 在返回的对象上而不需要使用对象自省或强制转换?
或者这种设计是一种反模式,我是否缺少明显的重写?谢谢。
【问题讨论】:
-
您描述的确切场景似乎没有意义-您的客户端代码无论如何都需要知道是调用“f”还是“b”,那么单次创建的优势是什么机制?听起来您的客户端代码会期望两个不同的对象在不同的代码路径中具有完全不同的行为。对于这三种行为(x、f 和 b)中的每一种,听起来您想要做的是 segregate interfaces。 Foo & Bar 都会实现 x 的接口,Foo 也会实现 'f' 等等
-
确实@val-akkapeddi 我目前有单独的接口“f”和“b”,它们是“x”的扩展,而 Foo 和 Bar 只实现了适当的扩展。然而,这似乎需要从被调用者进行强制转换,在我看来这是一个通用接口,除非重载,否则“f”和“b”会抛出异常,这将为被调用者带来更清晰的代码。
-
故意引发异常永远不会产生更简洁的代码 - 您将使用异常作为流程控制,调用错误的方法,然后尝试处理后果,而不是首先避免陷入这种情况 -对?在这种情况下,铸造也是令人讨厌和不必要的。我这样做的方法是拥有 Foo:Ix,If 和 Bar:Ix,Ib。您必须在代码中决定调用 f - 让该代码仅通过接口 If 引用其对象,并隐藏对 If、Ix、Ib 恕我直言的工厂方法后面的类的访问。
标签: java design-patterns inheritance