2014-08-28 43 views
0

這更像是一個架構問題。我想在我的項目中有一個全局對象,每個類都可以訪問它,但需要它,但不會每次創建一個實例。對象本身是不同服務的組合。我的第一個方法是定義一個接口,在接口中實例化對象,然後可以通過implements注入到每個類中。我想知道的是,如果這種方法是乾淨的或有點hacky或真的很粗糙。 這裏是我的執行至今:從界面創建全局唯一對象

public final class SystemServices 
{ 
    private final SecurityService securityService; 
    private final PersistencyService persistencyService; 
    private final RecordService recordService; 
    private final DispatcherService dispatcherService; 

    private SystemServices(Builder builder) 
    { 
     this.securityService = builder.securityService; 
     this.persistencyService = builder.persistencyService; 
     this.recordService = builder.recordService; 
     this.dispatcherService = builder.dispatcherService; 
    } 

    public SecurityService getSecurityService() 
    { 
     return securityService; 
    } 

    public PersistencyService getPersistencyService() 
    { 
     return persistencyService; 
    } 

    public RecordService getRecordService() 
    { 
     return recordService; 
    } 

    public DispatcherService getDispatcherService() 
    { 
     return dispatcherService; 
    } 

    public static class Builder 
    { 
     private SecurityService securityService; 
     private PersistencyService persistencyService; 
     private RecordService recordService; 
     private DispatcherService dispatcherService; 

     public Builder setSecurityService(SecurityService securityService) 
     { 
      this.securityService = securityService; 
      return this; 
     } 

     public Builder setPersistencyService(PersistencyService persistencyService) 
     { 
      this.persistencyService = persistencyService; 
      return this; 
     } 

     public Builder setRecordService(RecordService recordService) 
     { 
      this.recordService = recordService; 
      return this; 
     } 

     public Builder setDispatcherService(DispatcherService dispatcherService) 
     { 
      this.dispatcherService = dispatcherService; 
      return this; 
     } 

     public SystemServices build() 
     { 
      return new SystemServices(this); 
     } 
    } 
} 

而且這是在SystemServices的實例創建的接口:

public interface ServiceProvider 
{ 
    public static SystemServices systemServices = new SystemServices.Builder() 
      .setSecurityService(new SecurityService()) 
      .setPersistencyService(new PersistencyService(new BlackBoxDb(BlackboxApplication.getAppContext()))) 
      .setRecordService(new RecordService()).setDispatcherService(new DispatcherService()).build(); 
} 

現在我可以只使用systemServices.getSecurityService.doSomethingSecurityRelated()

訪問對象中的每個類

代碼的工作原理對初學者來說似乎太好了,但我確信這種方法有一些醜陋之處。所以任何批評都是讚賞:) 也是有趣的JVM如何處理接口。它真的只是一個單一的對象嗎?還是它爲每個類創建一個對象?

回答

1

JVM將按照您的需要處理接口,只會創建一個SystemServices。 但是你描述的方法確實被認爲是「醜陋的」。我認爲最好的方法是使用像Spring這樣的依賴注入框架。它非常擅長你需要的東西 - 擁有其他類可以訪問的全局對象。它還使得測試更容易,並且使您能夠快速更改應該使用的全局對象。

0

我不會說這是醜陋或哈克。這更加不尋常和單一。

它實際上看起來像一個非常好的,輕量級的方式來獲得注入所有類的依賴關係。您必須重新編譯接口來更改實現,這在理論上是不好的,但實際上,根據您的要求,可能並不重要。例如,它將使單元測試變得困難,因爲您的ServiceProvider接口將不得不被重寫以提供模擬SecurityService。

我注意到,你似乎已經取決於春天,如在BlackboxApplication.getAppContext()。爲什麼不在春季環境中提供所有服務?是否因爲你想讓它們可用於不受Spring管理的類?通過基於註解的春季環境加載,我沒有看到任何大的開銷,並且Spring爲您購買了許多漂亮的基礎架構代碼。

我可能是錯誤的,你已經使用彈簧。如果你不是這樣,我認爲你的方法沒有錯。它起初讓我感到驚訝!但是那很酷。

+0

首先:謝謝!獲得積極的反饋,儘管它是單一的,但感覺很好。那麼,因爲這是一個Android應用程序,所以在這裏Spring會很無用。所有提到的類都是自我實現的(也許我應該添加import語句來澄清這一點)。我認爲可能更多的「慣用」方法是經典的Singleton模式,但我不確定它是否會與已經實現的Builder模式相沖突。 – JohnPlata 2014-08-28 19:01:14

+0

誠然,您導入並在所有需要該服務的類中「實例化」的單例可以完成同樣的任務。有似乎有一些依賴注入框架的android:http://square.github.io/dagger/ – 2014-08-28 19:06:59

+0

是的,一些谷歌搜索後,我剛剛發現,也有一個Android的春季版本,但仍然爲我漂亮的「小」應用程序,它不是必需的。我明天會發布單例方法,希望得到一些反饋,因爲我沒有單身經驗,特別是將它與建設者模式結合起來。 – JohnPlata 2014-08-28 19:11:46