您的第一个方法的一个缺陷是,它会为每个调用创建一个新的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
一些实例。这可以很容易地交换,以产生不同的对象。
当我必须决定在哪里写创建方法时,我应该问自己什么?
两件事情:
- 我介绍一个新的硬连线的依赖?
- 我可以将对象创建提取到自己的类吗?
有人可能会认为像City
和State
有两个域对象不是去耦练习最好的例子,因为他们显然会永远在一起使用的,对不对?
但是,如果你仔细想一想,这不是太牵强:也许在某些时候,你会划分或装饰你的城市来区分行为的某些差异。有了城市工厂,如果您想要更改城市,您只需要在一个点上更改城市的创建。这是OOD的一个重要目标:如果你必须改变某些东西,就不必在整个地方改变它,但只能在一个地方改变它。
优秀的答案!我会与你的建议 – skyline26 2013-03-22 17:31:35