【发布时间】:2016-10-04 15:40:46
【问题描述】:
我经常读到关于向下转换是一件坏事,现在我需要它,我问自己在我的示例中我有哪些替代方案:
我有一个Interface A
实现接口 A 的三个类:X1, X2, X3
这些类描述了相同的内容,但以不同的“格式”和流程(简单地说),这就是为什么我必须对它们进行划分。
现在我有一个类如下:
class Test {
A obj;
}
根据“格式”,我选择obj = new X1(), obj = new X2() or obj = new X2()。
从现在开始,在使用对象时(除了 A 中的方法),我必须在此类中使用大量向下转换来访问类方法。我看到的唯一选择是为每个可能的类创建一个字段,其中只有一个被使用过。这似乎也很糟糕。
对更好的设计有何建议?
感谢您的帮助。
编辑:这是我的场景(简单地说):
我的主类是某些数据的容器。其中之一是内容属性(有点像 HTTP 请求的主体)。内容可以是:
- 纯文本(两个单独的字符串)
- 文件(只是文件路径、md5 等)-> 稍后将加载到输入流中。
- unknown (bytes) -> 我不能,实际上我也不必知道。稍后的上下文将为我提供有关它的信息。
对于每种类型,我都创建了一个类(TextContent、FileContent、UnknownContent)。他们实现了具有 getBytes() 方法的接口内容,它将内容作为字节数组返回。
内容的使用:
- 创造
ContainerClass.setContent(plainText) -> BaseInterface content = new TextContent(plainText)
ContainerClass.setFile(file) -> BaseInterface content = new FileContent(file)
ContainerClass.setContent(someBytes) -> BaseInterface content = new UnknownContent(someBytes)
我的 Container 对象可以保存为 json。内容对象只会被保存,如果它是文本或文件(因此我无法在界面中实现 toJsonObject())。
当内容是文本时,我想检查它的某些模式。我使用 Matcher 类在容器类之外执行此操作(例如
((TextContent)container.content).getText()-> 遗憾的是,FileContent 没有它可以返回的单个文本,所以我也无法实现那个)。我可以向我的容器类添加一个 getContentAs..() 方法,该方法将适当地转换它,但我觉得我只是解决了根本问题:(
【问题讨论】:
-
Test不应该关心obj是X1还是X2- 它应该只知道 或关心obj是一个A!即使Test知道存在X1或X2这一事实也是一个设计错误。您需要调查为什么Test需要知道这一点才能找出设计的问题;但是向下转换是抽象在错误层的标志。例如。如果Test不断根据obj的运行时类型决定行为,那么访客模式可能会更好。 -
如果流程相似但实现不同,为什么不在接口中声明一个抽象方法,让每个类覆盖方法?
-
你能发布一些示例代码吗?也许是一个(非常)简化的情况,您正在垂头丧气?
-
@BoristheSpider 谢谢你的回答。我知道我在某个地方犯了设计错误,但我很难弄清楚如何解决这个问题。我更新了我的帖子以展示我的场景。也许你对此有一些想法。谢谢!
-
@jmw5598 每种类型都有一些他们不与其他人共享的“独特”方法。要访问它们,我需要向下转换。