Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用于限制返回对象可用方法的Java设计模式_Java_Design Patterns_Inheritance - Fatal编程技术网

用于限制返回对象可用方法的Java设计模式

用于限制返回对象可用方法的Java设计模式,java,design-patterns,inheritance,Java,Design Patterns,Inheritance,我是一名新的Java/OO程序员。我想创建一个方法(以下称为myMethod),它根据检查输入参数和世界状态返回n种对象之一。为了简单起见,这里假设n==2:myMethod()可以返回类型为Foo或Bar的对象 Foo和Bar有不同的方法可用于调用它们,有些是独占的,有些是共同的,例如: ReturnType? myMethod(inputs) { if (/*examining state of world & inputs implies a Foo*/)

我是一名新的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()
接收对象的客户机,有没有一种方法能够安全地调用
f()
b()
在返回的对象上,而不需要使用对象内省或强制转换


或者这种设计是一种反模式,我是否缺少一个明显的重写?谢谢。

没有图案-知道类型和铸造是不行的


您必须将这些方法向上拉到公共接口或父类或强制转换。没有“模式”可以拯救你——这是一种神奇的想法。

在我看来,你正在寻找的设计模式是工厂设计模式,它在OO范式中非常常用。您可以阅读有关此模式的更多信息。我不完全确定您想要实现什么,但我认为这种设计模式至少值得一看。

在java中,您可以对接口进行隐式的向上转换,但必须使用显式的向下转换,否则java将无法编译。

您尝试的方法似乎非常接近于反模式

由于返回的对象的类型取决于“世界状态”,您是否希望调用方法检查返回对象的确切类型,并根据类型的不同表现出不同的行为


我认为您需要坐下来,试着解释一下这种设计的用例是什么,然后也许我们可以帮助您找到更好的解决方案。

Factory是正确的-它将返回公共接口或超类类型的引用。但是,如果不使用强制转换来访问接口或超类型中不存在的方法,这将无助于解决这个问题。您描述的确切场景似乎没有意义——您的客户机代码需要知道是否要调用“f”或“b”,那么使用单一创建机制的优势是什么?听起来您的客户机代码期望两个不同的对象在不同的代码路径中具有完全不同的行为。听起来你想做的是针对这三种行为(x、f和b)中的每一种。Foo和Bar都将实现x的接口,Foo也将实现“f”,因此forthIndeed@val akkapeddi当前有单独的接口“f”和“b”,它们是对“x”的扩展,而Foo和Bar只实现适当的扩展。这似乎需要从被调用方强制转换,但是,在我看来,一个公共接口,如果“f”和“b”抛出异常(除非重载),将为被调用方生成更干净的代码。故意引发异常不会生成更干净的代码-您将使用异常作为流控制,调用错误的方法,然后尝试处理后果,而不是一开始就避免陷入这种情况-对吗?在本例中,强制转换也是令人讨厌且不必要的。我这样做的方式是使用Foo:Ix,If和Bar:Ix,Ib。您必须在代码中做出调用f的决定-让代码仅通过接口If引用其对象,并隐藏对If,Ix类型的工厂方法后面的类的访问,Java中是否有一种受欢迎的方法,或者这种方法通常是特定于项目的风格?如果我使用前者,如果有人使用Foo试图调用
aFoo.b()
,我可能会抛出一个异常,但是一旦n变大,公共接口就会抛出大量异常。然而,强制转换似乎给被调用方带来了更多的知识负担。您可以编写工厂并返回接口或超类型的引用,但您不能也不应该控制用户一旦拥有了它就选择如何处理它。它确实给被调用方带来了知识负担,但给设计者带来了更大的负担。被调用方应该处理给定的接口类型,而不需要强制转换。如果他们这样做,那么您的设计就是有缺陷的。遵循预期规范的被调用方将知道是否期望从myMethod返回Foo、Bar等,但是如果被调用方犯了错误,我认为优雅地失败将导致抛出异常。在GUI自动化中,调用方法用例是,如果用户请求表单(即
Foo
),用户可以向(
f()
)提供字符输入,但如果用户请求按钮(A
),则用户不应该能够提供输入,只需单击
myMethod
是提供可自动化元素的联络点。但为什么该实现需要相同的方法来返回表单或按钮呢在我看来,现在您需要的是一种方法,让系统中的所有组件实现一个接口,该接口准确地描述了它们支持的输入类型,以及一种获得具有扩展功能的新接口的方法。这让我想起:我不知道你到底想解决什么问题,但我很确定你的方法是错误的,所以试着坐下来,描述一下你想做什么,不是你认为它应该如何实现。你自己的描述是我试图实现的事实:)-我认为Val上面的评论是我需要模仿的-我将尝试从调用方法中请求并返回特定的Foo或Bar对象,并将
myMethod()
作为单一接触点删除。