【问题标题】:Java - Collection of abstract class, children contain disparate objects - Any "good" way to handle these wrapped objects?Java - 抽象类的集合,子类包含不同的对象 - 处理这些包装对象的任何“好”方法?
【发布时间】:2013-08-29 12:12:14
【问题描述】:

假设我们有这样的东西:

public abstract class MyClass {
    //Stuff in here
}

public class MyClassA extends MyClass {

    private String thingie; //Along with getter/setters, of course
    //Other stuff
}

public class MyClassB extends MyClass {

    private List<Integer> thingies; //Again, getters and setters to go with
    //Other stuff
}

假设我们有任意数量的扩展 MyClass 的类,每个类都有自己的不同类型的实例变量,尽管有些可能具有相同的类型。这是一个不幸的必要性。现在,假设我们有一个 MyClass 的集合。我们有一个包含任意数量子类的集合,每个子类都包含一个对象。假设我需要遍历此 Collection,从任意数量的元素中检索所述对象,并​​对它执行操作、存储、操作、发送到其他地方等。这些对象除了扩展 Object 之外没有任何共同点。

我可能能够简单地将这些操作委托给 MyClass 子项本身、使用访问者等,但这可能不可行,因为这些操作可能依赖于集合中的其他 MyClass 子项。单个 MyClass 子项可能不会单独决定要采取的操作,甚至不会决定任何单个 MyClass 集合。其中一些行动可能是累积的,并且取决于许多其他潜在的累积因素。

有什么“好”的方法来处理这个问题,还是我会被诅咒到丑陋的类型检查条件或类似的地狱?我考虑在 MyClass 中使用泛型并在所有孩子身上使用具体类型。这可以简化对象的检索,但仍然需要一个大的条件块。

【问题讨论】:

  • 不是泛型或类似的问题。问题是找到一个好的模式来达到结果
  • 您真正的问题是,您一开始就将这些都放在了Collection&lt;MyClass&gt; 中,而没有保留其他信息。
  • 贝拉巴克斯也是这样。 :) 问题已简化,但还有其他信息。该集合来自提交给线程池的一系列链式任务。每个任务都将执行,将响应对象放入集合中,然后根据结果确定下一个任务应该是什么。这一直持续到结束,此时返回集合并且主线程评估结果。采取的行动取决于许多因素,其中一些可能超出仅存在于该集合中的数据,即池中的其他作业是否具有类似的结果。

标签: java generics collections types erasure


【解决方案1】:

您在问题中放弃了“好”的做法。在这种情况下,泛型将无济于事。是的,你会因为丑陋地使用类型检查而被诅咒到一个令人讨厌的地方。您可以使用称为category 的公共实例成员及其在MyClass 中定义的相应访问器getCategory 来伪装类型检查。如果可以的话,他们会在getCategory() 上执行switch(而不是多个ifs)。但是,谴责你的人可能不喜欢ifs 和switches,无论他们是否检查类型。他们也可能很聪明,并且了解您要做什么。除了

for(MyClass e: collection )
    e.doYourAction();

是“坏的”。

现在,对于似乎根本没有规范的软件,你可以原谅。

【讨论】:

  • 条件类型检查?我不知道我是否会称其为“好”而不是“最不坏”。 ;) 这只是一段丑陋的代码,不是很动态,每次添加、删除甚至更改 MyClass 的子级时都必须更改。我意识到这可能是“最好的”选择,但我希望有一些更干净、更有活力的东西。我在那里添加了泛型的想法作为一种折腾想法的方式。当然,这可以让我将对象推入抽象类,但我仍然需要对危险的东西进行类型检查。
  • @user1017413 如果您以更一般的方式解释问题会怎样?我可能会遗漏一些东西。特别是,如果每个新类都与其他类有很大不同,那么每次添加、删除甚至更改 MyClass 的子类时,您都需要更改“丑陋的代码块”。还是其中有什么让你认为你做不到?你确定他们没有任何共同点吗?
  • 这些 MyClass 子项中的每一个都继承自 MyClass 并包含一个对象以及一些其他更统一的信息,但其中的对象可以是多种类型。这些中的每一个都构建为匹配任务对象的响应对象,其中大多数都与外部服务通信。一个新的/改变的类将需要它自己的块来处理封闭的对象(不同的类型意味着不同的处理)以及根据多种因素确定如何处理它的逻辑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-19
相关资源
最近更新 更多