最近,我在其中一个项目中发现了非常强的代码气味,我正在为之工作。
特别是它的成本计算特性。要计算某些操作的总成本,我们必须将许多信息传递给“解析器类”。
例如:
在重构之前,所有这些参数都是通过构造函数传递给计数器类的(8个参数,您可以想象..)。
为了提高可读性,我引入了一个数据类,名为CostCountingData,带有可读的getter和setter,用于所有这些属性。
但我不认为,在这种重构之后,该代码变得可读性很强:
$cost_data = new CostCountingData();
$cost_data->setNumbers($numbers);
$cost_data->setContacts($contacts);
$cost_data->setGroups($groups);
$cost_data->setCampaigns($campaigns);
$cost_data->setUser($user);
$cost_data->setText($text);
$cost_data->setTotalQuantity($total_quantity);
$CostCounter = new TemplateReccurentSendingCostCounter($cost_data);
$total_cost = $CostCounter->count();你能告诉我这个代码片段的可读性是否有问题吗?也许你能看到任何密码的气味,并能指给我看。
我唯一的想法是如何重构这段代码,就是将这个大数据对象分割成多个,包括相关的数据类型。但我不确定我该不该这么做。
你怎么想的?
发布于 2009-03-21 13:53:21
这里有几种可能性:
不管你如何打扮一种方法的调用,其中包含8个参数,计算某物时需要8条被认为无关的信息,这一事实总是有异味的。
后退一步:
发布于 2009-03-21 10:40:35
如果您想要的是命名参数(在我看来,这就是您想要实现的),您会考虑只传递一个关联数组,其中的名称作为键吗?还有一个名为不过,我只能为C++找到一个很好的参考资料的参数成语,也许它被PHP程序员称为其他的东西。
为此,您将更改CostCountingData上的方法,以便它们都返回原始对象。这样,您就可以将顶级代码重写如下:
$cost_data = new CostCountingData();
$cost_data
->setNumbers($numbers)
->setContacts($contacts)
->setGroups($groups)
->setCampaigns($campaigns)
->setUser($user)
->setText($text)
->setTotalQuantity($total_quantity);所以有两种选择。我可能会自己使用命名参数成语,因为它是自我记录的,但我不认为差别太大。
发布于 2009-03-21 11:13:48
如果我需要数据对象(称为“数据”的类本身就是一个气味),我将在它的构造函数中设置它的值。但有趣的问题是,这些价值观从何而来?值的来源本身应该是某种类型的对象,而且它可能是您真正感兴趣的对象。
编辑:,如果数据来自POST,那么我将使类成为POST数据的包装器。我不会提供任何setter函数,并且会使读访问器看起来像这样(我的PHP有点生疏):
class CostStuff {
constructor CostStuff( $postdata ) {
$mypost = $postdata;
}
function User() {
return $mypost[ "user_name" ];
}
...
}https://stackoverflow.com/questions/669081
复制相似问题