您的第一个方法的一个缺陷是它为每次调用创建一个新的 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 中的一个重要目标:如果您必须更改某些内容,则不必在所有地方都进行更改,而只需要更改一次即可。