2012-08-14 55 views
0

我可能会使用错误的词,所以当我说业务对象(BO)我的意思是一个类的引用与Hibernate映射到数据库表的类,以及作为商业逻辑。休眠,子分类和访问者模式

我面临的问题是实例化没有使用反射或instanceof子类的权利BO。

例如,假设我有一个Pen-table,其中有一个动物表的引用,它又有两个子表Cat和Dog(所有的一对一引用)。这些类看起来有点像这样:

Pen p = ... // Get or load from database 
PenBO pbo = new PenBO(); 
pbo.setPen(p); 

然后,我使用的类是这样的::

public class Pen { 
    private Animal a; 
    // Getters and setters 
} 
public class Animal { 
    // Getters and setters 
} 
public class Dog extends Animal { 
    // Getters and setters 
} 
public class Cat extends Animal { 
    // Getters and setters 
} 
public class PenBO { 
    private Pen p; 
    public AnimalBO getAnimalBO() { ... } 
} 
public interface Action { 
    void visit(DogBO dbo); 
    void visit(CatBO cbo); 
} 
public class Sound implements Action { 
    void visit(DogBO dbo) { ... } 
    void visit(CatBO cbo) { ... } 
} 
public interface AnimalBO { 
    void accept(Sound s); 
} 
public class DogBO implements AnimalBO { 
    Dog d; 
    void accept(Sound s) { 
     s.visit(this); 
    } 
} 
public class CatBO implements AnimalBO { 
    Cat c; 
    void accept(Sound s) { 
     s.visit(this); 
    } 
} 

然后,我刚刚与BO的实例他们像这样的BO的获得的方法里面工作

pbo.getAnimalBO().accept(new Sound()); 

这是我正在研究的getAnimalBO-方法。我希望它根据Pen的Animal实例返回BO的正确实例。

我“可以”使用instanceof检查当前笔的实际动物,但这显然不是很漂亮。我想到的另一种选择是使用反射来获取类名并在之后添加“BO”并获得该类的实例,但它也非常难看。

我试过围绕getAnimalBO包装另一个访客模式,但它不能选择正确的访问方法而不投射,我不想将接受方法添加到非BO类。

如果没有聪明的方法来让该方法有效地工作,那么核心的问题就是错误的?我还没有真正找到Hibernate的最佳实践。 Hibernate和访问者模式的一些例子只是将accept方法添加到映射类中,这不能很好...

回答

1

您的问题实际上只是一个OO问题,具有继承性,并且从一个类层次结构转换为平行的。你已经解决了这个和Hibernate映射的数据库建模问题,显然你的访问者实现没有任何问题。只是您不想将访问者模式应用于映射的类层次结构,因此您在创建两个层次结构之间的转换时遇到了问题。

就目前情况来看,青梅一块你的代码将不得不承担责任,知道CatBO对应Cat等,并知道如果Pen对象的Animal属性实际上是一个Cat,则包含PenBO对象的AnimalBO财产将实际上是一个CatBO。鉴于此,它必须能够确定返回的Animal实例的类型,所以我看不到如何避免使用instanceof或反射之一。你有什么反对instanceof?反思获得班级名称并附加“BO”非常讨厌和丑陋,我同意,尽管显然可以开展工作。但一种方法的责任是采取Animal并返回一个合适的AnimalBO使用instanceof和选择正确的BO类在这种情况下恕我直言,这不是一件坏事。

我想问的问题是为什么你从一个类层次结构映射到另一个这样的所有。你说过你不要想要accept方法添加到映射的类,并且它“不能很好”,但你没有理由为什么你有这种感觉。它比你已经提出的选项更糟吗?通过将访问者模式添加到映射的类层次结构中,您并不真正在其中嵌入任何业务逻辑,而只是使用访问者模式在整个层次结构中启用业务逻辑应用程序。因此,您的业务逻辑层包含简单的通用访问者实现,映射的类或域图层是POJO以及基本的访问者实现,而且您确实拥有我认为您想要的完美分离。

+0

感谢您的回答!对不起,我没有给出不想用instanceof或relfection去解决的原因。这是正常的,它需要一个额外的地方更新时,添加新的类或不得不留下一个新的类最后需要“BO”的说明。我认为你对映射类中的accept方法进行了很好的说明,我可能会用它。它并不觉得它在映射类中只有getter和setter,除了创建额外的BO类以外,还为每个新的Animal子类添加一个instanceof。 – user1540134 2012-08-14 22:06:04