是否存在关于对象创建责任的一般规则,常见陷阱? 我该如何决定谁负责创建对象? 有时它很明显,有时候不是,我试图避免冗余代码,并仅限制到最低限度。 当我必须决定在何处编写创作方法时,我应该问自己什么?
class State
{
...
public [City] getCapitalCity()
{
return new City(this.capitalCityID);
}
}
class City
{
...
public static [City] getCapitalOf(State s)
{
return new City(s.capitalCityID)
}
}
提前谢谢
答案 0 :(得分: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;
}
}
答案 1 :(得分: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的一个重要目标:如果你必须改变一些东西,就没有必要在整个地方改变它,但只是在一点上。