2013-03-22 2 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) 
    } 
} 

Обратите внимание, что я сохранил оба метода на месте, но делегированы друг к другу. Еще одна вещь, которая до сих пор не решена после этого изменения, заключается в том, что вы не сможете обменять объект City, т. Е. На макет в модульном тестировании. Зависимость жестко связана.

Говоря о шаблонах проектирования, для слабосвязанной конструкции единственными классами, которые создают объекты, должны быть заводы.

Если мы применим, что здесь, это может выглядеть так:

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. И это легко можно было бы обменять на разные объекты.

что я должен просить у себя, когда я должен решить, где написать метод создания?

две вещи:

  • мне ввести новый зашитым зависимость?
  • Могу ли я создать объект для собственного класса?

Можно подумать, что два объекта домена, как City и State не лучший пример для расцепления упражнения, потому что они, очевидно, всегда будут вместе, не так ли?

Но если вы думаете об этом, это не слишком надуманно: возможно, в какой-то момент вы подклассифицируете или украсите свои города, чтобы отличить определенные различия в поведении. С городской фабрикой вам нужно будет только изменить создание городов в какой-то момент, если вы когда-либо захотите его изменить.И это важная цель в OOD: если вам нужно что-то изменить, не обязательно менять ее повсюду, но только в какой-то момент.

+0

отличный ответ! Я поеду с твоими предложениями – skyline26

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; 
    } 
} 
Смежные вопросы