2013-03-22 75 views
2

是否存在關於對象創建可響應性的一般規則,常見缺陷? 我應該如何決定對象創建的責任人?有時很明顯,有時候不是,我試圖避免多餘的代碼並且僅限於必要的最小值。 當我必須決定在哪裏寫創建方法時,我應該問自己什麼?我應該如何決定哪個類負責對象創建?

class State 
{ 
    ... 
    public [City] getCapitalCity() 
    { 
     return new City(this.capitalCityID); 
    } 
} 

class City 
{ 
    ... 
    public static [City] getCapitalOf(State s) 
    { 
     return new City(s.capitalCityID) 
    } 
} 

預先感謝您

回答

1

您的第一個方法的一個缺陷是,它會爲每個調用創建一個新的City對象。類似的東西會更自然的對我說:

class State 
{ 
    protected [City] capitalCity; 
    ... 
    public [City] getCapitalCity() 
    { 
     if (this.capitalCity == null) { 
      this.capitalCity = City::getCapitalOf(this); 
     } 
     return this.capitalCity; 
    } 
} 

class City 
{ 
    ... 
    public static [City] getCapitalOf(State s) 
    { 
     return new City(s.capitalCityID) 
    } 
} 

注意,我一直在這兩種方法的地方,但委託一個到另一個。另一件事情,在這種變化之後仍然沒有解決,就是你將無法交換城市對象,即在單元測試中進行模擬。依賴關係是硬連線的。

談到設計模式,對於鬆耦合設計,實例化對象的唯一類應該是工廠

如果我們在這裏應用,它可能看起來像:

class CityFactory 
{ 
    ... 
    public static [City] createCapitalFromState(State s) 
    { 
     return new City(s.capitalCityID); 
    } 
} 

class State 
{ 
    protected [City] capitalCity; 
    ... 
    public [City] getCapitalCity() 
    { 
     if (this.capitalCity == null) { 
      this.capitalCity = CityFactory::getCapitalOf(this); 
     } 
     return this.capitalCity; 
    } 
} 

class City 
{ 
    .... 
} 

爲了簡單起見,我不停的工廠方法靜態的,在現實中,你將有機會獲得的CityFactory一些實例。這可以很容易地交換,以產生不同的對象。

當我必須決定在哪裏寫創建方法時,我應該問自己什麼?

兩件事情:

  • 我介紹一個新的硬連線的依賴?
  • 我可以將對象創建提取到自己的類嗎?

有人可能會認爲像CityState有兩個域對象不是去耦練習最好的例子,因爲他們顯然會永遠在一起使用的,對不對?

但是,如果你仔細想一想,這不是太牽強:也許在某些時候,你會劃分或裝飾你的城市來區分行爲的某些差異。有了城市工廠,如果您想要更改城市,您只需要在一個點上更改城市的創建。這是OOD的一個重要目標:如果你必須改變某些東西,就不必在整個地方改變它,但只能在一個地方改變它。

+0

優秀的答案!我會與你的建議 – skyline26 2013-03-22 17:31:35

1

我可能會說,這完全取決於你的課程將如何使用。在這種情況下,我會選擇State.getCapitalCity(),因爲開發人員的工作流程更可能是查詢首都城市是否屬於他們已有的州級對象。

我的課堂設計可能看起來類似於以下內容。這樣,如果需要的話,我可以在兩個實體之間來回切換。

class State 
{ 
    ... 
    public City CapitalCity() 
    { 
     return new City(this.capitalCityId); 
    } 
} 

class City 
{ 
    ... 
    public State State() 
    { 
     return new State(this.stateId); 
    } 

    public bool IsCapitalCity() 
    { 
     return this.isCapitalCity; 
    } 
} 
相關問題