有魔法变量是不是很糟糕?

时间:2011-10-02 22:15:12

标签: java oop

假设我有一个变量或对象,我希望通过测试类从一个类传递到另一个类。假设我有一个测试班,一个厨师班和一个服务员班。

在测试类中执行此操作是否不好:

chef.makeFood();
waiter.deliverFood(chef.getFood())

在同样的说明中,我应该这样做:

chef.makeFood();
Food f = chef.getFood();
waiter.deliverFood(f);

3 个答案:

答案 0 :(得分:6)

  

拥有魔法变量是不是很糟糕?

这取决于你所说的“魔法”。如果“魔术”对你意味着“做一些难以理解或解释的事情”,那就太糟糕了。

  

在测试类中执行此操作是否不好:

  chef.makeFood();
  waiter.deliverFood(chef.getFood())

我认为代码本身没有任何问题,即使这不是在普通(非测试)代码中使用类的方式。 (但是你没有向我们展示设计/代码存在问题......)

  

在同样的说明中,我应该这样做:

  chef.makeFood();
  Food f = chef.getFood();
  waiter.deliverFood(f);

这样做是可以的,或者不这样做。这取决于是否认为这使代码更具可读性。 (就个人而言,我不会在那里打扰一个局部变量,但这只是我的意见。)


另一方面,我同意@ DaveNewton对于“makeFood”中持有食物的“厨师”对象的评论。这当然是反直觉的,有点“神奇”......如果它是一个刻意的设计选择。

更简单,更好的设计是:

Food f = chef.makeFood();
waiter.deliverFood(f);

并从getFood()类中完全删除Chef方法和关联的状态变量。

有很多原因导致设计糟糕/建模不良:

  • 从直觉上来说,这意味着厨师对象必须“站在那里拿着盘子”直到服务员拿走它。

  • 从类建模的角度来看,你有一个状态变量,它不是实现Chef行为所必需的。

  • 从实际编程的角度来看,这意味着:

    • 当您在12个月内查看代码时,代码将很难理解

    • Chef API将难以在多线程厨房模拟中使用。

(如果这个就是你所说的“魔术变量”,那就糟糕了......见上文。)

答案 1 :(得分:1)

很难概括这个例子。

在这个简单的例子中,厨师可能没有理由保留对`makeFood()'的引用,因此应该直接返回它。 (然后可以删除getFood())

但是还有很多其他场景可以保持内部状态,例如StringBuilder - 或者更复杂的“构建器”,然后在罚款时返回结果。

局部变量通常在调试时结束....这并不重要。

答案 2 :(得分:1)

这不是一个神奇的变量或任何类型的东西,而是在这里:

chef.makeFood();
waiter.deliverFood(chef.getFood())

第一个需要更少的行,如果你不需要对新创建的Food对象的引用可能会更好。但是很多人可能会争辩说,即使你不需要引用,下面的代码也更具可读性并清楚:

chef.makeFood();
Food f = chef.getFood();
waiter.deliverFood(f);

一般情况下,您应该总是尝试使用更易读的代码,因为您永远不会知道将在何时维护该代码。