I have created a class called Calculator with the add, subtract, multiply and divide function. The calculator is limited to adding two numbers and returning the result. I am relatively new to OOP,would like to get some input on the class, did i take the long route and if i did is there another way to simplify the class.
Here is the code:
class Calculator {
private $_val1 , $_val2;
public function __construct($val1, $val2){
$this->_val1 = $val1;
$this->_val2 = $val2;
}
public function add(){
return $this->_val1 + $this->_val2;
}
public function subtract(){
return $this->_val1 - $this->_val2;
}
public function multiply (){
return $this->_val1 * $this->_val2;
}
public function divide () {
return $this->_val1 / $this->_val2;
}
}
$calc = new Calculator(3,4);
echo "<p>3 + 4 = ".$calc->add(). "</p>";
$calc = new Calculator (15,12);
echo "<p>15 - 12 = ".$calc->subtract(). "</p>";
$calc = new Calculator (20,2);
echo "<p> 20 * 2 = ".$calc->multiply(). "</p>";
$calc = new Calculator (20,2);
echo "<p> 20 / 2 = ".$calc ->divide(). "</p>";
IMHO, you should use Polymorphism.
This Video may help you understanding this principle
Here's my way of thinking.
First, define an interface for any operations you'd need
interface OperationInterface
{
public function evaluate(array $operands = array());
}
Then, create the calculator holder
class Calculator
{
protected $operands = array();
public function setOperands(array $operands = array())
{
$this->operands = $operands;
}
public function addOperand($operand)
{
$this->operands[] = $operand;
}
/**
* You need any operation that implement the given interface
*/
public function setOperation(OperationInterface $operation)
{
$this->operation = $operation;
}
public function process()
{
return $this->operation->evaluate($this->operands);
}
}
Then you can define an operation, for example, addition
class Addition implements OperationInterface
{
public function evaluate(array $operands = array())
{
return array_sum($operands);
}
}
And you would use it like :
$calculator = new Calculator;
$calculator->setOperands(array(4,2));
$calculator->setOperation(new Addition);
echo $calculator->process(); // 6
With that point, if you want to add any new behaviour, or modify an existing one, just create or edit a class.
For example, say you want a Modulus operation
class Modulus implements OperationInterface
{
public function evaluate(array $operands = array())
{
$equals = array_shift($operands);
foreach ($operands as $value) {
$equals = $equals % $value;
}
return $equals;
}
}
Then,
$calculator = new Calculator;
$calculator->setOperands(array(4,2));
$calculator->setOperation(new Addition); // 4 + 2
echo $calculator->process(); // 6
$calculator->setOperation(new Modulus); // 4 % 2
echo $calculator->process(); // 0
$calculator->setOperands(array(55, 10)); // 55 % 10
echo $calculator->process(); // 5
If you plan to reuse this code or give it away as a library, the user wouldn't by any case modify your source code.
But what if he wants a Substraction
or a BackwardSubstraction
method which are not defined ?
He just has to create his very own Substraction
class in his project, which implements OperationInterface
in order to work with your library.
When looking in the project architecture it's easier to see a folder like this
- app/
- lib/
- Calculator/
- Operation/
- Addition.php
- Modulus.php
- Substraction.php
- OperationInterface.php
- Calculator.php
And immediatly know which file contains the desired behaviour.
I don't think a plain calculator is a good example for OOP. An object needs both a set of methods and a set of variables that represent its state, and can be used to differentiate instances of the object. I would suggest trying to make "moody" calculators. A calculator with a happy mood will add 2 to each result, and an angry calculator will subtract 2 from each result.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With