Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 从对象中删除过多的IF_Php_Oop_Object - Fatal编程技术网

Php 从对象中删除过多的IF

Php 从对象中删除过多的IF,php,oop,object,Php,Oop,Object,编辑: 我应该提到我希望它更面向对象。我不认为我的代码接近OO,也不使用开关,是吗 作品: 首先,在我下面的例子中,我使用的是荷兰单位,所以计算可能看起来不正确,但你会明白的 基本上,我有一份商品清单。例如,在我的数据库中,我将价格按件或按磅存储。因此,为了计算每种产品的总价格,根据选择的数量,我正在与下面的班级合作 例如: 在我的杂货店列表中,我有一些产品,产品后面是一个文本字段和一个下拉列表。在文本字段中,我可以输入我想要的数量,并在下拉列表中选择是否需要盎司、磅等。基于这些值,以及数据库中

编辑:

我应该提到我希望它更面向对象。我不认为我的代码接近OO,也不使用开关,是吗

作品:

首先,在我下面的例子中,我使用的是荷兰单位,所以计算可能看起来不正确,但你会明白的

基本上,我有一份商品清单。例如,在我的数据库中,我将价格按件或按磅存储。因此,为了计算每种产品的总价格,根据选择的数量,我正在与下面的班级合作

例如:

在我的杂货店列表中,我有一些产品,产品后面是一个文本字段和一个下拉列表。在文本字段中,我可以输入我想要的数量,并在下拉列表中选择是否需要盎司、磅等。基于这些值,以及数据库中的初始价格(每件的价格等),我可以计算每个产品的总价格

我的问题是:

public function calculate()
{
    if($this->unit === 'ounce')
    {
        return $this->formatOunce();
    }
    if($this->unit === 'pound')
    {
        return $this->formatPound();
    }
        return $this->formatOne();
}

我将如何更改上述代码以使其成为良好的OO?我是使用存储库还是使用接口?或者我可以在这个特定的类中这样做以保持简单?我觉得“如果”太多了。

我建议立即进行两项更改:

使用类常量而不是硬编码的字符串标识符。优点有两个:IDE提供更好的自动完成支持,并且没有更多的打字错误

使用switch语句,可以让事情更清楚:

这也将允许有一个计算目录和一个方法,而不是几个独立的方法来进行实际的计算,因为您可以将公式存储在数组甚至静态类中

最后还有一件更基本的事情:我想在这里讨论架构方法:


为什么选择实现类计算?这让我觉得很不直观。。。实现类似PositionInShoppingCart的东西不是更自然吗?这样,此类对象就可以保存产品标识符、基本价格、数量/金额等?这将以自然的方式导致ShoppingCart类。。。该类型的对象将包含第一种类型的对象列表

我建议立即进行两项更改:

使用类常量而不是硬编码的字符串标识符。优点有两个:IDE提供更好的自动完成支持,并且没有更多的打字错误

使用switch语句,可以让事情更清楚:

这也将允许有一个计算目录和一个方法,而不是几个独立的方法来进行实际的计算,因为您可以将公式存储在数组甚至静态类中

最后还有一件更基本的事情:我想在这里讨论架构方法:


为什么选择实现类计算?这让我觉得很不直观。。。实现类似PositionInShoppingCart的东西不是更自然吗?这样,此类对象就可以保存产品标识符、基本价格、数量/金额等?这将以自然的方式导致ShoppingCart类。。。该类型的对象将包含第一种类型的对象列表

您不想切换到交换机吗

首先,从概念上和逻辑上来说,转换是正确的选择。您正在使用一个变量$this->unit切换值。我觉得它看起来真的很干净。[]

第二,它更快。虽然在你的情况下,可能没那么重要

$res = NULL;
switch($this->unit)
{
    case 'ounce': $res = $this->formatOunce(); break;
    case 'pound': $res = $this->formatPound(); break;
    default: $res = $this->formatOne();
}
return $res;

你不想换到另一台吗

首先,从概念上和逻辑上来说,转换是正确的选择。您正在使用一个变量$this->unit切换值。我觉得它看起来真的很干净。[]

第二,它更快。虽然在你的情况下,可能没那么重要

$res = NULL;
switch($this->unit)
{
    case 'ounce': $res = $this->formatOunce(); break;
    case 'pound': $res = $this->formatPound(); break;
    default: $res = $this->formatOne();
}
return $res;

编辑问题后要求采用面向对象的方法:

创建一个基类来处理输出总数。它调用执行计算的受保护方法。计算:

现在,您可以使用物品的磅版本扩展基本物品。英镑版本将覆盖计算方法,因为计算方式不同

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);
    }
}
创建英镑类型的新项目:

因为PoundItem也是一个项目,所以可以使用total方法。但是由于我们改变了calculate的实现,它现在可以计算磅

echo $a->total();

编辑问题后要求采用面向对象的方法:

创建一个基类来处理输出总数。它调用执行计算的受保护方法。计算:

现在,您可以使用英镑版本的 这个项目。英镑版本将覆盖计算方法,因为计算方式不同

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);
    }
}
创建英镑类型的新项目:

因为PoundItem也是一个项目,所以可以使用total方法。但是由于我们改变了calculate的实现,它现在可以计算磅

echo $a->total();

你的问题是,你把代码从每个条件中分离出来,放到它们自己的类中:盎司类知道如何计算盎司,磅类知道如何计算磅

正如有人之前所说,你仍然需要某种决定是使用英镑还是盎司的货币。那家工厂看起来。。。嗯,和你现在的情况一模一样,但很可能是从别的地方抽象出来的

由于目前代码非常简单,我认为任何这些更改都会过早地进行重构。你现在所拥有的并不复杂——理解代码的作用不会让这里的人慢下来。一旦你开始用更复杂的方法来计算某件事,那么研究多态性就更合适了


类似地,我认为switch语句与IF条件建议也不是很有用的建议。在这种情况下,它们不会增加任何可读性。

您的问题是,将代码从每个条件中分离出来,并将它们放在自己的类中:Ounce类知道如何计算ounces,Pound类知道如何计算pounds

正如有人之前所说,你仍然需要某种决定是使用英镑还是盎司的货币。那家工厂看起来。。。嗯,和你现在的情况一模一样,但很可能是从别的地方抽象出来的

由于目前代码非常简单,我认为任何这些更改都会过早地进行重构。你现在所拥有的并不复杂——理解代码的作用不会让这里的人慢下来。一旦你开始用更复杂的方法来计算某件事,那么研究多态性就更合适了


类似地,我认为switch语句与IF条件建议也不是很有用的建议。在这种情况下,它们不会增加可读性。

切换可能是执行ifs的更干净的方法。此外,您可以只使用大括号:返回$this->{$key}请记住,OO不是好代码的黄金标准。如果你问的是更多的OO,你应该删除问题中关于删除ifs的部分。ps:我将删除我的答案,尽管它涉及分离的关注点,但它不是特别的OO。我用一种简单的OO方法更新了我的答案。这应该给你一个好主意。其他答案中似乎没有一个涵盖OO。切换可能是执行ifs的一种更干净的方法。此外,您可以只使用大括号:返回$this->{$key}请记住OO不是好代码的黄金标准。如果你问的是更多的OO,你应该删除问题中关于删除ifs的部分。ps:我将删除我的答案,尽管它涉及分离的关注点,但它不是特别的OO。我用一种简单的OO方法更新了我的答案。这应该给你一个好主意。其他答案中似乎没有一个涉及OO。引入额外变量$res只会让事情变得更复杂。。。。为什么?@arkascha我觉得并不复杂。将值赋给$res并到达代码末尾更像是一种标准做法。他们说,如果在代码中间发出return语句,这是一个坏习惯,也是一个麻烦制造者,但是如果它对您有效,并且没有真正引起维护问题,那么应该这样做。这里有一个秘密,我喜欢使用GO TO,即使人们认为这是一个麻烦我没有遇到麻烦。这真的取决于你如何使用它或什么对你方便。我同意这是个人品味和习惯的问题。对我来说,这要复杂得多,因为很明显,很难跟上潮流。还有更高的风险,例如,您可能会在稍后意外修改$res,可能是因为缺少休息或类似的原因…是的,我编辑了我的问题,因为它确实是作为个人品味和习惯问题制定的,现在通过编辑,应该可以更清楚地了解我想要什么,真的。引入额外的变量$res只会让事情变得更复杂。。。。为什么?@arkascha我觉得并不复杂。将值赋给$res并到达代码末尾更像是一种标准做法。他们说,如果在代码中间发出return语句,这是一个坏习惯,也是一个麻烦制造者,但是如果它对您有效,并且没有真正引起维护问题,那么应该这样做。这里有一个秘密,我喜欢使用GO TO,即使人们认为这是一个麻烦
. : 我没有遇到麻烦。这真的取决于你如何使用它或什么对你方便。我同意这是个人品味和习惯的问题。对我来说,这要复杂得多,因为很明显,很难跟上潮流。还有更高的风险,例如,您可能会在稍后意外修改$res,可能是因为缺少休息或类似的原因…是的,我编辑了我的问题,因为它确实是作为个人品味和习惯问题制定的,现在通过编辑,应该可以更清楚地了解我想要什么,真的。我想这就是我需要知道的全部:我想这就是我需要知道的全部:我留下了我的旧答案,因为还有一些部分,比如常数和关注点的分离,我认为你可以利用。是的,这些东西非常有意义,我可以用它,谢谢:我留下了我以前的答案,因为还有一些部分,比如const和关注点的分离,我认为你可以利用。是的,这些东西非常有意义,我可以处理这些,谢谢: