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

注意,我一直在这两种方法的地方,但委托一个到另一个。另一件事情,在这种变化之后仍然没有解决,就是你将无法交换城市对象,即在单元测试中进行模拟。依赖关系是硬连线的。

谈到设计模式,对于松耦合设计,实例化对象的唯一类应该是工厂

如果我们在这里应用,它可能看起来像:

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一些实例。这可以很容易地交换,以产生不同的对象。

当我必须决定在哪里写创建方法时,我应该问自己什么?

两件事情:

  • 我介绍一个新的硬连线的依赖?
  • 我可以将对象创建提取到自己的类吗?

有人可能会认为像CityState有两个域对象不是去耦练习最好的例子,因为他们显然会永远在一起使用的,对不对?

但是,如果你仔细想一想,这不是太牵强:也许在某些时候,你会划分或装饰你的城市来区分行为的某些差异。有了城市工厂,如果您想要更改城市,您只需要在一个点上更改城市的创建。这是OOD的一个重要目标:如果你必须改变某些东西,就不必在整个地方改变它,但只能在一个地方改变它。

+0

优秀的答案!我会与你的建议 – skyline26 2013-03-22 17:31:35

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; 
    } 
} 
相关问题