2012-08-14 42 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