簡體   English   中英

隱藏服務實現的最佳實踐

[英]Best practice to hide a service implementation

我想隱藏API用戶的服務(接口)的實現(具體類)。 該實現由使用Java API ServiceLoader機制的工廠提供給用戶。 此Loader要求實現類具有公共可見性。 只要實現隱藏在用戶不直接依賴的不同JAR(除了API JAR之外),就可以了。

但是,為了便於分發,使用默認實現的JAR內容將打包到API JAR中。 因此,用戶有效地依賴於此預先打包的JAR,其中默認實現類可用於公共可見性。 沒有什么能阻止人們直接實例化實現。 我不希望那是可能的。

我的壞主意:

  • 實現自己的ServiceLoader版本,允許加載包私有實現(順便說一下,為什么Java API ServiceLoader不允許這樣做?)
  • 發布單獨的API和實現JAR

您認為正確的方法是什么? 妥協嗎?

使用OSGi或其他重型機械是不可能的。

令人失望的是,但是:

  • 制作一個單獨的罐子,並將其與其他第三方罐子放在一起。
  • 讓安裝程序/部署過程處理所有的包裝。
  • 在編譯期間不要使這個jar可用; maven: <scope>runtime</scope>

唯一的另一種方法是在javadoc中使用@Deprecated ,並使用java服務API作為注釋如何使用相應的類。

在C#中,您可以創建僅對相關好友程序集可見的內部接口,然后顯式實現該接口。 我不確定你將如何在Java中實現這一點,但從概念上講,這就是我在.NET世界中解決這個問題的方法。

編輯我只是查了一下,從我可以看出Java沒有明確的接口實現。 作為FYI,接口的顯式實現要求您通過接口成員進行函數調用,不能將其稱為實現類的成員。 這就是為什么我的技術適合我,至少在.NET世界中。

或者,我建議將接口放在另一個JAR中,而不是使用API​​分發它

您無法輕易阻止人們實例化/訪問任何已發布的類。

因此,我可能只是簡單地包裝您正在使用的ServiceLoader機制,並提供通過Java接口引用的實例化類(而不是作為具體的實現引用)。

我更喜歡你的第一種方法,使實現類包私有,並使用ServiceLoctor來檢索特定服務。 在我的項目中,包結構如下:

-package
   |-ServiceInterface(public)
   |-ServiceImplementation(default,package private)
   |-ServiceLocator(public)

serviceLocator是這樣的:

public class ServiceLocator{
    private static final Map<String,Service> services;

    static {
         services=new HashMap<String,Service>();
         services.put("default",new ServiceImplementation());//hide implementation
    }
    public Service getService(String name){
         return services.get(name);
    } 

    public registerService(Service service, String name){
         services.put(name,service)
    }
}

最終用戶無權訪問實現類,在以后的時間內,您可以輕松地更改為使用不同的實現類。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM