太多计算怎么整,关于php:从对象中删除太多的IF"/>
php太多计算怎么整,关于php:从对象中删除太多的IF
编辑:
我应该提到我希望它更面向对象。我不认为这里的代码在OO附近,也不使用开关,是吗?
OP:
首先,在下面的示例中,我使用的是荷兰语单位,因此计算看起来可能不正确,但您会明白这一点。
基本上,我有一份杂货店的产品清单。例如,在我的数据库中,我将价格存储在"按件价格"或"按磅价格"中。因此,为了计算每种产品的总价格,根据所选的数量,我正在处理下面的类。
例子:
在我的杂货店列表中,我有一些产品,在这个产品后面是一个文本字段和一个下拉列表。在文本字段中,我可以输入我想要的数量,并在下拉列表中选择是否需要盎司、磅等。根据这些值和我的数据库中的初始价格(每件价格等),我可以计算出每个产品的总价格。
class Calculation
{
protected $price;
protected $amount;
protected $unit;
public function __construct($price, $amount, $unit)
{
$this->price = $price;
$this->amount = $amount;
$this->unit = $unit;
}
public function calculate()
{
if($this->unit === 'ounce')
{
return $this->formatOunce();
}
if($this->unit === 'pound')
{
return $this->formatPound();
}
return $this->formatOne();
}
public function formatOne()
{
return $this->price * $this->amount / 100;
}
public function formatOunce()
{
return $this->price / 1000 * $this->amount / 100;
}
public function formatPound()
{
return $this->price / 1000 * 500 * $this->amount / 100;
}
}
我的问题是:
public function calculate()
{
if($this->unit === 'ounce')
{
return $this->formatOunce();
}
if($this->unit === 'pound')
{
return $this->formatPound();
}
return $this->formatOne();
}
如何更改上述代码以使其成为良好的OO?我是使用存储库还是使用接口?或者我可以在这个特定的类中这样做来保持简单吗?我觉得有太多如果有的话。
切换可能是一种更清洁的方式来进行IFS。
你也可以做大括号:返回$this->$key()
记住,OO不是良好代码的黄金标准。如果你问更多的OO,你应该去掉你关于删除if的部分问题。(PS:我会去掉我的答案,尽管它处理的是分离问题,但它不是特别的OO)
我用一种简单的OO方法更新了我的答案。这应该给你一个想法。其他答案中似乎没有一个涵盖了OO。
我建议立即进行两次修改:
使用类常量而不是硬编码的字符串标识符。其优点是双重的:IDES能够更好地支持自动完成,并且不再出现打字错误。
使用switch()语句,使事情更清楚:
class Calculation
{
const UNIT_WEIGHT_OUNCE = 'ounce';
const UNIT_WEIGHT_POUND = 'pound';
// ...
protected $price;
protected $amount;
protected $unit;
// ...
public function calculate()
{
switch ($this->unit) {
case self::UNIT_WEIGHT_OUNCE:
return $this->formatOunce();
case self::UNIT_WEIGHT_POUND:
return $this->formatPound();
// ...
default:
return $this->formatOne();
}
}
// ...
}
这也将允许有一个"计算目录"和一个方法,而不是几个独立的方法来进行实际的计算,因为您可以将公式存储在一个数组甚至静态类中…
最后一件更基本的事情:我想在这里讨论架构方法:
为什么选择实现类Calculation?这对我来说是非常不直观的…实施像"定位购物车"这样的东西不是更自然吗?这样,这类对象就可以保存产品标识符、基价、数量/金额等?这将导致一个"购物车"类的自然方式…该类型的对象将保存第一个类型的对象列表。
面向OO的方法(编辑问题后按要求):
您将生成一个处理输出total()的基类。它调用执行计算的受保护方法。calculate():
class Item
{
protected $price;
protected $amount;
public function __construct($price, $amount)
{
$this->price = $price;
$this->amount = $amount;
}
protected function calculate()
{
return $this->price * $this->amount;
}
public function total($format = true)
{
if ($format) {
return number_format($this->calculate(), 2);
}
return $this->calculate();
}
}
现在,您可以使用该项的磅版本扩展基本项。pound版本将覆盖calculate()方法,因为计算方式不同。
class PoundItem extends Item
{
protected function calculate($format = true)
{
return $this->price / 1000 * 500 * $this->amount / 100;
}
}
要生成对象,您需要一个构造函数方法或所谓的工厂来生成它们。这是工厂班。它也可以在您的basket类上实现。
class ItemFactory
{
static public function create($price, $amount, $type)
{
// this could be implemented in numerous ways
// it could even just be method on your basket
$class = $type ."Item";
return new $class($price, $amount);
}
}
创建磅类型的新项目:
$a = ItemFactory::create(49.99, 25,"Pound");
由于PoundItem也是一个Item方法,您可以使用total()方法。但由于我们改变了calculate()的实现方式,现在它计算的是磅。
echo $a->total();
我留下了我以前的答案,因为仍然有一些部分,如const,以及我认为你利用的关切的分离。
是的,这东西很有道理,我可以用它,谢谢:)
你不想换成开关吗?
首先,在概念上和逻辑上,切换是正确的方式。您正在使用一个变量$this->unit切换值。我觉得这很干净。[何时使用if else if else转换开关柜,反之亦然]
其次,它更快[如果"else"比"switch()case"快吗?]虽然在你的情况下,可能没有那么重要。
$res = NULL;
switch($this->unit)
{
case 'ounce': $res = $this->formatOunce(); break;
case 'pound': $res = $this->formatPound(); break;
default: $res = $this->formatOne();
}
return $res;
引入附加变量$res,只会使事情变得更复杂……为什么?
@我认为阿卡沙不是很复杂。给$res赋值并到达代码末尾更是一种标准实践。他们说,如果你在代码中间发出一个返回语句,这是一个坏习惯,也是一个麻烦制造者,但是如果它对你有效,并且不会真正导致维护问题,那么应该这样做。这是一个秘密,我喜欢使用Go-to,即使人们认为它是一个麻烦。:)我不会有问题的。这真的取决于你如何使用它或者什么对你方便。
我同意这是个人品味和习惯的问题。对我来说,这要复杂得多,因为很明显,很难遵循流程。还有更高的风险,例如,您可能在以后不小心修改了$res,可能是由于缺少break或类似的…
是的,我编辑了我的问题,因为它确实是作为个人品味和习惯问题制定的,现在随着编辑,它应该更清楚我在追求什么,真的。
你的问题是用多态性替换条件,这样你就从每个条件中分离出代码,并把它们放到自己的类中:盎司类知道如何计算盎司,磅类知道如何计算磅。
如前所述,你仍然需要某种工厂来决定是时候使用磅还是盎司。那家工厂看起来…嗯,就像你现在的样子(但很可能是从别处抽象出来的)。
由于目前的代码有多简单,我认为这些更改中的任何一个都将被重构得太早。你现在所拥有的并不复杂——理解代码的作用不会让这里的人放慢脚步。一旦你开始有更复杂的方法来计算某个东西,那么观察多态性将是更好的选择。
同样,我认为switch语句vs if条件建议也不是很有用的建议。在这种情况下,它们不会为可读性添加任何内容。
我想这就是我所需要知道的。)
更多推荐
php太多计算怎么整,关于php:从对象中删除太多的IF
发布评论