Недостаток вашего первого метода заключается в том, что он создает новый объект 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: если вам нужно что-то изменить, не обязательно менять ее повсюду, но только в какой-то момент.
отличный ответ! Я поеду с твоими предложениями – skyline26