2011-06-29 187 views
1

我堅持一個規劃問題:AbstractFactory與扭曲

我有兩個的Java項目,在我的Eclipse IDE:項目A和項目B。 項目B引用項目A

我已經宣佈在項目A類:ClassA的,一個在項目B:ClassB的,使得:

public class ClassA{ 
    public static Object foo(){ 
    //blah 
    } 
} 

public class ClassB extends ClassA{ 
    public static Object foo(){ 
    //blah 
    } 
} 

我也有一個名爲ClientClass,在項目A類。此ClientClass早期用於創建ClassA的實例並使用它。但現在,基於環境設置,ClientClass應該提供使用ClassA或ClassB的選項。

這似乎是AbstractFactory模式的一個問題,或者我想。 我需要創建一個工廠,提供對ClassA或ClassB的訪問。 ClientClass不應該知道它是ClassA或ClassB。這要求我爲ClassA和ClassB創建一個接口。

問題我跑進

  • ClientClass不能引用ClassB的直接(不導入語句/或新的調用),因爲ClassB的是在不同的項目。這可能是Eclipse IDE的限制,但在將這兩個項目作爲jar文件查看時,對我來說也是有意義的。循環關係是可以避免的。
  • 我無法爲ClassA Class A & ClassB創建Factory接口和通用接口,然後通過AbstractFactory模式提供ClassAFactory或ClassBFactory。這是因爲要在ClassA和ClassB上調用的方法是靜態方法。這些類上的方法需要存在於接口上。但是,在Java中,不能有「抽象靜態」修飾符

任何人都可以爲這個問題提出一個優雅的解決方案嗎?

回答

2

那麼,這裏有很多問題。對於初學者來說,這是最大的一個,因爲你不能重寫Java中的靜態方法,所以這不起作用。我認爲,您所說的目標是能夠在運行時將ClassA替換爲ClassB或B或A或其他,這取決於某些參數。爲了做到這一點,您需要能夠利用動態分派(或者簡單地說,虛擬方法),這將允許運行時系統選擇要在運行時執行的方法的內存地址。這對於靜態方法是不可能的。你需要使這個方法非靜態的工作。您不必專門設計Java Interface,但是當您使用ClassB擴展ClassA時,您可以將對象視爲僅僅是ClassA對象。所有這一切都說,如果你從方法中刪除了靜態修飾符,並使它們變爲非靜態的,那麼你可以在項目A中使用ClassB而不必在你正在談論的客戶端類中使用任何導入語句。但是,在項目A的某個地方,有人需要了解ClassB才能實例化它。當然,除非你想做一些運行時綁定的東西,並使用字符串動態加載類。那有意義嗎?

+0

Chris,感謝您的詳細回覆。是的,擁有非靜態方法定義將有助於動態調度,但是我必須保持靜態方法 - 這是我無法改變的設計決策。 我需要可能設計一個完全不同的機制,我可以將呼叫路由到ClassA或ClassB。 –

+0

我終於決定清理亂七八糟的靜態修飾符,並採用動態類加載的動態調度標準解決方案。將此答案標記爲正確答案。謝謝:) –

+0

@Kiran快樂的幫助!對不起,這不是你想要的答案... –

0

冷杉問題:您的B類和A類的foo方法是靜態的。因此沒有什麼被覆蓋。如果您打算在ClassB中重寫foo,則不應將它們設置爲靜態。

這裏的第二個問題是上游需要知道下游。這是錯的不是嗎?

這是否是一個抽象因素模式的問題是除了這一點。設計模式只是使代碼遵循已知的結構。它本身並不是目的。

現在,爲什麼您的項目A中的ClientClass需要了解ClientB?

至於工廠,你的工廠需要在項目B,它可以是這樣的:

類廠{

公共靜態ClassA的createTheRightOne(EnvironmentSettings設置){//做正確的事}

}

一旦你解決static修飾符

  • Pavan
+0

Pavan,謝謝你的評論。從建築純度的角度來看,上游 - 下游代碼點是一個有用的代碼點,並且我喜歡堅持。 在這種特殊情況下,所有智能材料都發生在ProjectA中,而ProjectB中的類提供了一些特定於環境/上下文的信息。因此,在這種特殊情況下,我需要ProjectA從ProjectB動態地選取正確的一組類,以便事情正確。 如上所述,我有一個設計需要保持類和它們的方法的靜態性質。 –