我有n个可以堆叠或不堆叠的类。所有这些类都扩展了相同的类(CellObject)。我知道会有更多的类添加到此列表中,并且我想创建一种易于在一个地方操纵“可堆叠性”的方式。

我正在考虑创建一个矩阵,其中行索引是堆栈底部的类,而列索引是堆栈顶部的类。如果可以上下堆叠,则该值为true(或1),否则为false(0)。

但是,我的同事建议创建n + 1个名为canStack的方法。一个通用的canStack方法将打开一个instanceof语句,该语句将其定向到n个子方法之一中。每个子方法仅会回答顶部对象是否可以自己堆叠在底部对象上的问题。

我认为我的解决方案更优雅/更干净。这是真的?如果是这样,我将如何实施?

我将对象更改为类

最佳答案

您的解决方案会更短。但是它的缺点是,如果添加CellObject的子类,则可能会忘记更改阵列。即使您知道会发生这种情况,其他人也有一天可能会在代码上工作。再说一次,他的解决方案也有同样的问题。

现在,这是一个有点荒谬的想法,但是由于您实际上是在讲有关类的一些,因此感觉像是在使用元数据工具。您可以做的是定义一个注释,该注释指出可以将哪些类堆叠到带注释的类上和/或可以将哪些类堆叠在其上。

像这样:

@interface Stackable {
    Class<? extends CellObject>[] stackables(); //Classes that may stack on the annotated one
    Class<? extends Cellobject>[] pillars(); //Classes this one can stack on
}

然后,您可以创建使用此元数据的注释处理器。它可以创建一个在编译时读取的配置文件,或者为您生成一些样板代码。您可以像JPA为其类型安全的查询API生成元类那样,生成有关类的内容。或者,您甚至可以在运行时保留注释,以使用反射来找出可以堆叠在什么上的内容,从而建立所需的临时数组,而不必编写代码。

如果您使用注释处理器,则将String数组与规范的类名一起使用可能会更安全,因为Class对象在编译时可能尚不可用。其可行性还取决于所有CellObject类是否始终在同一编译运行中。

在这里使用反射(确保注释具有RetentionType RUNTIME时可能)似乎是一个可行的选择。检查阵列;如果相应的元素为null(可以通过使用Boolean而不是boolean来完成),请进行反射并填充该元素。下次您可以避免反射开销,根据需要延迟填充数组。

编辑:忘了提及,我的解决方案也不强制您保持元数据为最新。而且,如果可堆叠性是可传递的,则可以降低复杂度。也就是说,A可以堆叠在B上,B可以堆叠在C上,这意味着A可以堆叠在C上。

09-06 07:04