Java多态性 - 选择基于子类型的正确方法

时间:2010-05-20 18:00:12

标签: java design-patterns polymorphism

给出以下类和服务层签名:

public class PersonActionRequest {
    PersonVO person
    // ... other fields
}
public class MyServiceLayerClass {

   public void requestAction(PersonActionRequest request)
   {
       PersonVO abstractPerson = request.getPerson();
       // call appropriate executeAction method based on subclass of PersonVO
   }
   private void executeAction(PersonVO person) {}
   private void executeAction(EmployeeVO employee) {}
   private void executeAction(ManagerVO manager) {}
   private void executeAction(UnicornWranglerVO unicornWrangler) {}
}

正如所讨论的here,java将在编译时根据类型信息选择最佳方法。 (即,它将始终选择executeAction(PersonVO person))。

选择正确方法最合适的方法是什么?

The internet告诉我使用instanceof让我受到打击。但是,我没有看到选择方法的合适方式,而没有明确地将abstractPerson转换为其他具体类型之一。

编辑:要澄清 - 传入的VO是一个简单的ValueObject公开,供Web客户端实例化和传入。按照惯例,它没有方法,它只是一个数据结构领域。

因此,调用personVO.executeAction()不是一种选择。

由于

玛蒂

5 个答案:

答案 0 :(得分:4)

如果executeActionPersonVOEmployeeVOManagerVOUnicornWranglerVO共有的基类或接口中的方法,则可以调用abstractPerson.executeAction()而不是多个重写方法。

答案 1 :(得分:3)

这里对多态性的主要障碍似乎是'dumb-struct'数据对象+'manager class'服务非模式。 “更多态”的方法是将execute()作为各种人实现覆盖的方法。

假设无法改变,那么在Java中进行多次调度的方式就是具有访客外观的回调。

public interface PersonVisitor {
   void executeAction(EmployeeVO employee);
   void executeAction(ManagerVO manager);
   void executeAction(UnicornWranglerVO unicornWrangler);
}
public abstract class PersonVO {
public abstract void accept(PersonVisitor visitor);
}
public class EmployeeVO extends PersonVO {
@Override
public void accept(PersonVisitor visitor) {
  visitor.executeAction(this);
}
}

public class MyServiceLayerClass implements PersonVisitor {

   public void requestAction(PersonActionRequest request)
   {
       PersonVO abstractPerson = request.getPerson();
       abstractPerson.accept(this);
   }

   public void executeAction(EmployeeVO employee) {}
   public void executeAction(ManagerVO manager) {}
   public void executeAction(UnicornWranglerVO unicornWrangler) {}
}

答案 2 :(得分:2)

您可以更改接近设计的方式并使用Visitor,将执行程序传递到Person并让人员类型确定要调用哪个。

答案 3 :(得分:2)

访问者模式通常用于克服缺乏双重调度的Java。

答案 4 :(得分:0)

我会明确地施放abstractPerson。它不仅可以确保JVM获得正确的方法,还可以让您更轻松地阅读并确保您了解正在发生的事情。