给出以下类和服务层签名:
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()
不是一种选择。
由于
玛蒂
答案 0 :(得分:4)
如果executeAction
是PersonVO
,EmployeeVO
,ManagerVO
和UnicornWranglerVO
共有的基类或接口中的方法,则可以调用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获得正确的方法,还可以让您更轻松地阅读并确保您了解正在发生的事情。