函数组合成变换
重构动机
在软件中,经常将数据传递给一组程序,让它再计算出各种派生信息。这些派生数据可能在几个不同的地方用到,因此这些计算逻辑也常会在需要用到派生数据的地方重复。
这时候,我们可以把所有计算派生数据的逻辑收拢到一处,这样始终可以在固定地方找到和更新这些逻辑,避免到处重复。
函数组合成变换接受源数据作为输入,计算出所有的派生数据,将派生数据以字段的形式填入输出数据。如果需要更改计算逻辑,只需要在这个变换函数更改。
重构前
下面代码实现的功能:计算叫外卖的总费用(包含快餐费+餐盒包装费):
<?php
namespace app\controller;
class Index
{
/**
* 计算外卖的总费用
*/
public function calculateTotalCost($order)
{
$fastFoodCosts = $this->CalculateFastFoodCosts($order);
$deliveryCharges = $this->CalculateDeliveryCharges($order);
return $fastFoodCosts + $deliveryCharges;
}
/**
* 计算快餐的费用
*
* @param $order 用户的快餐订单
* @return float|int 快餐费用
*/
public function CalculateFastFoodCosts($order)
{
$ricePrice = $order['rice'] * 2;
$meatPrice = $order['meat'] * 10;
$vegetables = $order['vegetables'] * 4;
return $ricePrice + $meatPrice + $vegetables;
}
/**
* 计算外卖配送费
*/
public function CalculateDeliveryCharges($order)
{
// 如果外卖小于3份,餐盒包装费需要加 2 元
return $order['num'] > 3 ? 0 : 2;
}
}
重构后
<?php
namespace app\controller;
class Index
{
/**
* 计算外卖的总费用
*/
public function calculateTotalCost(&$order)
{
$ricePrice = $order['rice'] * 2;
$meatPrice = $order['meat'] * 10;
$vegetables = $order['vegetables'] * 4;
// 计算快餐费用
$order['fastFoodCosts'] = $ricePrice + $meatPrice + $vegetables;
// 计算餐盒包装费用
$order['deliveryCharges'] = $order['num'] > 3 ? 0 : 2;
return $order;
}
/**
* 测试
*/
public function test()
{
$order = [
'rice' => 3,
'meat' => 6,
'vegetables' => 4,
'num' => 3
];
$costs = $this->calculateTotalCost($order);
echo $costs['fastFoodCosts'] + $costs['deliveryCharges'];
}
}