设计决策:向方法V / S添加新参数,创建实例变量

时间:2011-08-01 10:15:45

标签: java oop

假设我们有一个 Shape 类,它有一个方法 rotate(int velocity)。此方法使形状以速度(传递给旋转的参数)旋转。这个方法已在一个项目中调用,比如在100个地方。

但是现在出现了新的要求,旋转功能也将取决于形状的颜色,即如果颜色是蓝色则速度应该减少1,否则不应该改变做成。

  • 此问题的一个解决方案是将旋转(int velocity)方法更改为旋转(int velocity,Color color),然后添加if语句内部旋转方法检查颜色,更改100次调用旋转。 例如。

    shape.rotate(50, blue) ;

在旋转方法中,

void rotate(int velocity, Color color) {
  if(color == blue)
      --velocity ;
}
  • 另一个解决方案是将颜色作为形状对象的实例变量,然后不向旋转方法添加新参数,只需在调用之前设置颜色,然后在旋转内部挤压if检查方法。 例如。

     shape.setColor(blue) ;
     shape.rotate(50) ;
    

    在旋转方法中,

    void rotate(int velocity) {
      if(this.color == blue)
        --velocity ;
    }
    
  • 另一个解决方案是重载旋转方法并创建一个名为 rotate(int velocity,Color color)的新方法,并在新的方法中使用它调用。这将使现有代码使用 rotate(int velocity)不变。

哪一个是最好的解决方案? 或者,是否存在更好的解决方案?如果是,那么它会是什么?

此致

4 个答案:

答案 0 :(得分:2)

我想说你需要问几个问题。

  1. 您是否关心rotate方法之外的颜色?如果是,请将其设为实例变量;如果不是,请将其传递给rotate方法。

  2. 您是否可能会关注rotate方法之外的颜色?如果是,请将其设为实例变量;如果不是,请将其传递给rotate方法。

  3. 调用rotate方法时,您是否总是关心颜色?如果是,请将其设为参数(强制它们在旋转形状时设置颜色)。

答案 1 :(得分:0)

  1. 我认为第一个选择是实施起来很乏味。如果你错过了一个地方怎么办,如果你以后意识到你需要再次旋转(单个参数)怎么办。
  2. 第二种选择与许多人已经指出的无关。
  3. 3rd我觉得这是最好的解决方案,因为它不会破坏你的代码。您可以同时拥有重载方法,可以根据需要使用其中任何一个。

答案 2 :(得分:0)

至于我,我在这里看到了继承用法的经典例子。

class Shape {
  public void rotate(int v) {}
}

class GreenShape extends Shape {
  public void rotate(int v){
    super.rotate(v + 10);
  }
}

答案 3 :(得分:0)

OO的一个好原则是共同定位相关的行为和状态。在这种情况下,形状的旋转行为取决于形状的颜色状态,因此在Shape类c.q中共同定位两者是有意义的。创建一个字段'color'并在rotate方法中使用它来自定义旋转行为。

除了这个设计决定之外,您还在询问重构决策:如何处理依赖于形状的应用程序代码?在这种情况下,我的方法是提前考虑:我们可以期待对Shape类进行多少次更改?如果这是一个罕见的更改,那么您可以继续更改初始化形状类的所有代码位置,以便设置颜色。如果形状经常变化,那么你应该更严格,并使你的代码不那么紧密耦合。在这种情况下,一种方法是创建一个抽象工厂(或使用像Spring这样的D.I.框架提供的工厂),这样应用程序代码就不需要知道形状的创建细节。

BTW你的第三个选项对我来说似乎不是最优的:部分代码没有意识到颜色状态的加入,并且不断调用旧的'不赞成'的旋转方法。这意味着将形状的颜色设置为蓝色不会普遍影响旋转行为,但仅限于“特殊情况”。这会削弱设计,并使您在理解之后更难为开发人员。