So I have read that if we see a switch statement, its a sign that it needs polymorphism.
I saw such polymorphism example:
include 'vendor/autoload.php';
$calc = new Calculator();
$calc->setOperands(5, 6);
$calc->setOperation(new Addition);
echo $result = $calc->calculate();
And of course there can be various classes as Subtract, Multiply, Root, etc.
Now lets say I want to use this code in a Laravel framework, but this I think should apply to any php framework.
Example of addition class ( same way could work any other calculator function)
Class Addition implements Operation {
public function run($num, $current){
return $current + $num;
}
}
Calculator:
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;
}
}
I write a class like this:
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();
}
}
And this should work, did not test my CalcUser class, just wrote directly here.
But I see one problem - there is used keyword new
And also what I have read is this:
Signs of Untestable Code:
- New Operators
The only time when it’s acceptable to instantiate a class inside of another class is when that object is what we refer to as a value-object, or a simple container with getters and setters that doesn’t do any real work.
Ok, now I could add the Addition class, and other classes to constructor as parameter like I did with calculator class and new operator will be avoided.
But then there is another thing:
Too Many Dependencies
If you find that a particular class requires four or more dependencies, this is, more often than not, a tell-tale sign that your class is asking for too much
And so its easily to get more than 3 dependencies that way with calculator alone having many different functions.
So how should I reformat code to avoid having too many dependencies?