所以我读过如果我们看到一个switch语句,它就表明它需要多态性。
我看到了这样的多态性示例:
include 'vendor/autoload.php';
$calc = new Calculator();
$calc->setOperands(5, 6);
$calc->setOperation(new Addition);
echo $result = $calc->calculate();
当然可以有各种类,如Subtract,Multiply,Root等。
现在假设我想在Laravel框架中使用此代码,但我认为这应该适用于任何php框架。
添加类的示例(同样可以使用任何其他计算器函数)
Class Addition implements Operation {
public function run($num, $current){
return $current + $num;
}
}
计算器:
Class Calculator {
protected $result = 0;
protected $operands = array();
protected $operation;
public function getResult()
{
return $this->result;
}
public function setOperands()
{
$this->operands = func_get_args();
}
public function setOperation(Operation $operation)
{
$this->operation = $operation;
}
public function calculate()
{
foreach ($this->operands as $num) {
echo $num;
if ( ! is_numeric($num)) {
throw new InvalidArgumentException;
}
$this->result = $this->operation->run($num, $this->result);
}
return $this->result;
}
}
我写了一个这样的课:
class CalcUser
{
private $calc;
public function __construct(Calculator $calc)
{
$this->calc = $calc;
}
public function index()
{
$this->calc->setOperands(5, 6);
$this->calc->setOperation(new Addition);
$result = $calc->calculate();
// imagine we have long formula to calculate so we add here many functions
// (5+6) * 12 + 21 / 6 + sqrt(4) ...
$this->calc->setOperands($result, 6);
$this->calc->setOperation(new AnyOtherFunction);
echo $result = $calc->calculate();
}
}
这应该有效,没有测试我的CalcUser类,只是直接写在这里。
但我发现一个问题 - 使用了关键字 new
我所读到的也是:
不可测试代码的迹象:
- 新运营商
醇>唯一可以在其中实例化类的时间 另一个类就是那个对象就是我们所说的那个 value-object,或带有getter和setter的简单容器 不做任何实际的工作。
好的,现在我可以添加Addition类,并将其他类添加到构造函数作为参数,就像我使用计算器类和 new 运算符一样。
但是还有另外一件事:
依赖性太多
如果您发现特定课程需要四个或更多 依赖性,这通常是一个告诉你的标志 上课要求太多了
因此,仅使用计算器就可以轻松获得3个以上的依赖关系,具有许多不同的功能。
那么我应该如何重新格式化代码以避免依赖太多?
答案 0 :(得分:0)
在这个问题上有很多不同的观点(类何时依赖于某些东西),但类依赖性通常被视为传递给构造函数的内容,即将类实例化为对象所需的内容。因此,当您拥有计算器的实例时,调用方法并将另一个对象(在本例中为Operation
的实现 - )传递给方法并不是直接依赖。
所以基本上你的Calculator
类没有依赖关系,你的CalcUser
有一个依赖关系(Calculator
)。
另外,我认为关于new
- keyword / construct的事情是,类不应该自己调用某些东西,通过那里传递方法依赖。这可能表明,如果新实例化的对象仅用于该类的生态系统中,则它是多余的。假设你从不在依赖它的类中的其他地方使用Operation
,即在这种情况下:
class Calculator
{
...
public function newSumOperation()
{
$this->setOperands(func_get_args());
$this->setOperation(new Addition);
}
...
}
class CalcUser
{
...
public function index()
{
$this->calc->newSumOperation(1,2,3);
$result = $this->calc->calculate();
// imagine we have long formula to calculate so we add here many functions
// (5+6) * 12 + 21 / 6 + sqrt(4) ...
$this->newXXXXXOperation(4,3,2);
echo $result = $calc->calculate();
}
}
因此,正如您所见,在上面的示例中,您永远不会在Addition
- 类之外使用Calculator
。如果你想到一个真正的计算器,你可以输入数字并得到结果;在这之间,计算器并没有将数字加在一起的逻辑推进到别的地方,因为计算器 job 做了一个补充。