2016-06-21 64 views
0

我有一個工廠類CipherBuilder,其靜態方法build返回StringCipher對象到客戶端。 我想隱藏StringCipher類,所以客戶端只能通過CipherBuilder工廠得到這種類型的對象,並且不能直接調用類構造函數(但它仍然可以使用它的公有方法)。以工廠模式隱藏客戶端的產品

我當前的實現是創建另一個包從客戶端代碼分開,並把其中的三個班,CipherBuilder工廠(這是公開的),在StringCipher(包私人)和公共的接口吧(IStringCipher)。這樣客戶端不能直接調用構造函數,但它仍然可以通過接口使用公共方法。

但是因爲我不得不創建一個新的包來隱藏一個類,這就像一個黑客。有沒有更好的方式來執行此操作(使用Java),同時將StringCipher保留在與客戶端代碼相同的包中,並將StringCipherCipherBuilder保存在單獨的文件中?

+0

讓CipherBuilder創建一個IStringCipher。並且StringCipher以某種方式被隱藏。它確實意味着一個包私人類和構造函數。子包也是慣例。人們可以使該類成爲工廠類的靜態內部類。 –

+0

因此,在將StringCipher與客戶端代碼保持在同一個包中時,沒有辦法做到這一點?我可以在單獨的文件中執行靜態內部類嗎? – devil0150

+1

另一種方法:** Java SPI,服務提供程序接口**。這是一種機制,通過該機制可以發現並加載XML解析器。至於原始問題:我不完全確定你想要指定的東西是多麼「好」。 (順便說一下,至少有一個'package'是常態。)有一個帶有私有構造函數的類(例如工廠),可以將工廠傳遞給構造函數並檢查一個非null對象。醜陋! (更好地等待Java 9與模塊。)對不起,混亂。 –

回答

2

爲了保持CipherBuilderStringCipher在同一個包,你可以做的StringCipher構造的保護,這樣,客戶端無法建立StringCipherCipherBuilder仍然可以訪問,因爲這兩個類都在同一個包。

我希望這有助於

+0

關鍵在於隱藏課程而不爲其創建單獨的包。我將編輯帖子來解釋這一點。 – devil0150

+0

似乎沒有更好的解決方案。你能否在答案中包括「如果客戶類在同一個包中」的句子,我會接受它。 – devil0150

0

有幾件事情,你如何能實現它。

您可以將StringCipher類定義爲CipherBuilder類中的私人類。如果StringCipher將被編碼爲接口,則工廠方法CipherBuilder可能會返回給您一個接口;

其他的解決辦法,如果你不想接口,將在同一個包中定義CipherBuilderStringCipher,並設置訪問級別StringCipher的構造函數包(沒有訪問修飾符級)。然後StringCipher只能在包內創建。

+0

第二種解決方案是我目前正在做的。第一個解決方案可以在保持StringCipher與CipherBuilder不同的文件的情況下完成嗎? – devil0150

+0

@ devil0150也許我誤解了你,但如果兩個類都在單獨的包中,並且在問題描述中建議你有單獨的包,那麼第二種解決方案將無法工作。和第一個解決方案不會工作,如果你有私人的構造函數。除非你使用反射,但這將是不好的做法,對於這種情況 – user902383

+0

@ devil0150,當然你可以分開它們,並改變訪問級別,但是再次,這將與第二個解決方案相同 – user902383

0

我認爲最簡單的方法是:

1)創建你的包

2)在裏面你的包中創建:

public class CipherBuilder{...} 
    public class IStringCipher{...} 
    class StringCipher {...} 

你的包外,沒有人會看到CipherBuilder。

+0

我假設第三行應該是StringCipher。但是,這仍然是我目前正在做的。 – devil0150

+0

是的,只是改變了它。我明白,你需要客戶端在同一個包中。也許你可以在一個單獨的文件中定義一個asbtract StringCipher類,並將一個Inner類定義到實現它的CipherBuilder中。它有意義嗎? –