instanceof vs isAnX()

Posted

技术标签:

【中文标题】instanceof vs isAnX()【英文标题】: 【发布时间】:2011-08-28 19:42:09 【问题描述】:

在 java 中,我正在编写一些 DTO 对象,它们都继承自 AllocationDTO。 然后将这些对象的列表传递到 DAO 对象中以保存到数据库中。

根据要保存AllocationDTO 的哪个子类型,保存逻辑会发生变化(例如,要保存到数据库中的哪个表等)

我发现自己使用这样的代码:

for (AllocationDTO x : listOfAllocationDtos) 
    if (x instanceof ManagerAllocationDTO) 
         Manager m = (x(ManagerAllocationDTO)).getManager();
         // save manager etc to managerallocs
     else if (x.getId() == AllocationDTO.TYPE_SPECIAL1) 
         // save to specialAlloc1 table
     else if (x.getId() == AllocationDTO.TYPE_SPECIAL2) 
         // save to specialAlloc2 table
    

ManagerAllocationDTO 有一个额外的字段将分配与经理相关联,但对于 specialalloc1/2 的情况,我没有创建子类型,因为数据的唯一区别是它保存到的表。

我的问题是一个软设计问题 - 这是最好的方法吗?

【问题讨论】:

只是对您的代码的评论:您确实应该使用equals 方法而不是== 来比较您的字符串。尤其是在使用数据库时。 不太确定像 "(x.getId() == "specialAlloc2")" 这样的代码 - 你真的对对象相等感兴趣还是你真的应该使用 "x.getId().equals ("specialAlloc2")" ? "specialAlloc2" 是一个常数,所以我认为在这种情况下对象相等性测试是可以的。我在发布此内容后立即更改了代码以引用所述内容,并意识到你们两个刚刚评论的内容相同。我已编辑问题以反映我的更改。你同意吗? 看到这个类似的问题:***.com/questions/5579309/switch-instanceof 【参考方案1】:

在没有instanceOf 和 if-else-cascade 的情况下分隔不同实例的一种方法是使用Visitor Design pattern。

新接口:AllocationVisitor 为 AllocationDTO 的每个具体子类提供一个方法:

访问(TYPE_SPCIAL1 dto) 访问(TYPE_SPCIAL2 dto)

AllocationDTO: abstract void acceptVisitor(AllocationVisitor visitor)

AllocationDTO 的每个 concreate 子类都以这种方式实现 acceptVisitor(): void acceptVisitor(AllocationVisitor visitor)visit(this); //编译时类型选择正确的访问方式。 您的 DTO 实现了 AllocationVisitor 接口(带有一个内部类),创建它的一个实例,并将其传递给 listOfAllocationDtos 的元素。

道:

AllocationVisitor saveVisitor = new AllocationVisitor() 
  visit(TYPE_SPCIAL1 dto) //what ever you need
  visit(TYPE_SPCIAL2 dto) //what ever TYPE_SPCIAL2 needs

for (AllocationDTO x : listOfAllocationDtos) 
  x.visit(saveVisitor);

【讨论】:

这看起来我必须将保存逻辑添加到 DTO。我不喜欢这个想法,因为这个想法是 DTO 基本上是一个数据容器,不知道它是如何持久化/传输的等。DAO 应该知道 DTO,但不是相反。我是否正确理解了访问者模式? 不,如果按照模式,那么DTO只有一个类似回调的方法,逻辑属于DAO @Ben Page:我已经扩展了我的答案来解释访问者模式。这种模式是 GOF 书中最复杂的(并且从静态结构的角度很难理解)之一。但是即使你不使用它来处理这种情况,你也应该看看他的力量全模式。 -- 您可以在任何需要案例的地方使用它,具体取决于类型。那么如果你添加一个新的类型,你永远不会忘记“扩展案例”,因为编译器会检查它。 感谢您的解释。我了解它的工作原理,并且(希望)能够实现它。

以上是关于instanceof vs isAnX()的主要内容,如果未能解决你的问题,请参考以下文章

instanceof 和 构造函数

java中的instanceof

每日一博 - instanceof vs isInstance vs isAssignableFrom

每日一博 - instanceof vs isInstance vs isAssignableFrom

markdown instanceof vs typeof

JavaScript instanceof vs typeof