0

我可能使用了错误的词,所以当我说业务对象(BO)时,我的意思是一个类,它引用了一个类,该类通过 Hibernate 以及业务逻辑映射到一个数据库表。

我面临的问题是在不使用反射或 instanceof 的情况下为子类实例化正确的 BO。

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

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 的 get 方法中像这样实例化它们:

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

然后我使用这样的类:

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

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

我“可以”使用 instanceof 检查当前 Pen 中的实际 Animal,但这显然不漂亮。我正在考虑的另一种选择是使用反射来获取类名并在之后添加“BO”并获取它的实例,但是它也很丑陋。

我尝试在 getAnimalBO 周围包装另一个访问者模式,但它无法选择正确的访问方法而不进行强制转换,我不想将接受方法添加到非 BO 类。

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

4

1 回答 1

1

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

就目前情况而言,您的部分代码将不得不负责知道CatBO对应于Catetc,并且知道如果Pen对象的Animal属性实际上是 a Cat,那么包含PenBO对象的AnimalBO属性实际上将是 a CatBO。鉴于此,它必须能够确定Animal返回的实例的类型,所以我看不出如何避免使用其中之一instanceof或反射。你反对instanceof什么?我同意,反射获取类名并附加“BO”是非常讨厌和丑陋的,尽管它显然可以工作。但是一个单一的方法,其职责是通过使用和选择正确的方法来获取Animal和返回合适的AnimalBOinstanceofBO在恕我直言的情况下,上课并不是一件坏事。

我要问的问题是,为什么你要从一个类层次结构映射到另一个这样的层次结构。您已经说过您不想accept方法添加到映射的类中,并且它“不好”,但是您没有解释为什么会有这种感觉。它是否比您已经提供给自己的选项更糟糕?通过将访问者模式添加到映射的类层次结构中,您实际上并没有在其中嵌入任何业务逻辑,您只是使用访问者模式启用跨层次结构的业务逻辑应用程序。因此,您的业务逻辑层包含简单的通用访问者实现,您的映射类或域层是 POJO 加上基本访问者实现,

于 2012-08-14T15:27:48.080 回答