在OOP PHP中编写计算器类的更简单方法
我创建了一个名为Calculator的类,带有加、减、乘和除函数。计算器仅限于将两个数字相加并返回结果。 我对OOP比较陌生,希望获得一些关于类的输入,我是否走了很长的路,如果我走了,是否有其他方法来简化类 代码如下:在OOP PHP中编写计算器类的更简单方法,php,oop,Php,Oop,我创建了一个名为Calculator的类,带有加、减、乘和除函数。计算器仅限于将两个数字相加并返回结果。 我对OOP比较陌生,希望获得一些关于类的输入,我是否走了很长的路,如果我走了,是否有其他方法来简化类 代码如下: class Calculator { private $_val1 , $_val2; public function __construct($val1, $val2){ $this->_val1 = $val1; $th
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>";
类计算器{
私人$\u val1,$\u val2;
公共函数构造($val1,$val2){
$this->_val1=$val1;
$this->_val2=$val2;
}
公共功能添加(){
返回$this->_val1+$this->_val2;
}
公共函数减法(){
返回$this->_val1-$this->_val2;
}
公共函数乘法(){
返回$this->_val1*$this->_val2;
}
公共职能划分(){
返回$this->_val1/$this->_val2;
}
}
$calc=新计算器(3,4);
echo“3+4=”.$calc->add()。“”;
$calc=新计算器(15,12);
echo“15-12=”.$calc->subtract()。“”;
$calc=新计算器(20,2);
echo“20*2=”.$calc->multiply()。“”;
$calc=新计算器(20,2);
echo“20/2=”.$calc->divide()。“”;
你可能会做这样的事情
$calc = new Calculator();
$calc->sum($x, $y, $z);
$calc->substract($x, $y);
....
看看这个例子。可以使用func_num_args()给出任意数量的参数
//输出:参数数:3
一般来说,我们不会在此类类中固定值。
您的方法应该按参数获取它们的2个值,而不是选择私有成员
例如:
public function add($v1, $v2)
{
return $v1 + $v2;
}
因此,计算器成为了一种工具,我们不需要分配这种对象。
这就是为什么计算器方法应该是静态的
public static function add($v1, $v2)
{
return $v1 + $v2;
}
这样,您只需调用Calculator::add(1,2)
。
你可以在任何地方找到这样的课程。就像数学或3D中的向量、矩阵一样。或者写入输出或类似的内容
记住,这是一种方法,既不是最好的也不是最坏的。我不认为简单的计算器是OOP的好例子。一个对象需要一组方法和一组表示其状态的变量,并且可以用来区分对象的实例。我建议尝试制作“穆迪”计算器。心情愉快的计算器会给每个结果加2,心情愤怒的计算器会从每个结果中减去2 IMHO,您应该使用多态性。
可以帮助你理解这个原则 这是我的想法 首先,为您需要的任何操作定义一个接口
interface OperationInterface
{
public function evaluate(array $operands = array());
}
然后,创建计算器支架
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);
}
}
然后可以定义一个操作,例如加法
class Addition implements OperationInterface
{
public function evaluate(array $operands = array())
{
return array_sum($operands);
}
}
你会像这样使用它:
$calculator = new Calculator;
$calculator->setOperands(array(4,2));
$calculator->setOperation(new Addition);
echo $calculator->process(); // 6
在这一点上,如果您想添加任何新行为,或者修改现有行为,只需创建或编辑一个类
例如,假设您想要一个模运算
class Modulus implements OperationInterface
{
public function evaluate(array $operands = array())
{
$equals = array_shift($operands);
foreach ($operands as $value) {
$equals = $equals % $value;
}
return $equals;
}
}
那么
$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
此解决方案允许您的代码成为第三方库 如果您计划重用此代码或将其作为库分发,用户无论如何都不会修改您的源代码。
但是如果他想要一个未定义的
减法
或后向减法
方法怎么办
他只需要在他的项目中创建自己的减法
类,该类实现操作接口
,以便使用您的库
它更容易阅读
在项目架构中查看时,更容易看到这样的文件夹
- app/
- lib/
- Calculator/
- Operation/
- Addition.php
- Modulus.php
- Substraction.php
- OperationInterface.php
- Calculator.php
$sum1 = new SumNode(new Value(5), new Value(3));
$sum2 = new SumNode(new Value(1), new Value(2));
$op = new SubNode($sum1, $sum2);
$result = $op->evaluate();
并立即知道哪个文件包含所需的行为。此任务有很多解决方案,下面是其中之一:
<?
class Calculator
{
/**
* @var float
*/
/**
* @var float
*/
private $_val1,
$_val2;
/**
* @var int
*/
private static $_result = 0;
/**
* @param $val1
* @param $val2
*/
public function __construct($val1 = '', $val2 = '')
{
if ((!empty($val1) && !empty($val2)) && (!is_numeric($val1) && !is_numeric($val2))) {
$this->_val1 = (float)$val1;
$this->_val2 = (float)$val2;
}
}
/**
* @param $val1
*/
public function setVal1($val1)
{
$this->_val1 = (float)$val1;
}
/**
* @param $val2
*/
public function setVal2($val2)
{
$this->_val2 = (float)$val2;
}
/**
* @param string $operator
*
* @return float|int|string
*/
public function getResult($operator = '')
{
if (is_numeric($this->_val1) && is_numeric($this->_val2)) {
switch ($operator) {
case '+':
self::$_result = $this->_val1 + $this->_val2;
break;
case '-':
self::$_result = $this->_val1 - $this->_val2;
break;
case '*':
self::$_result = $this->_val1 * $this->_val2;
break;
case '/':
self::$_result = $this->_val1 / $this->_val2;
break;
}
} else {
echo 'Alert alert alert)) some of operands not set or not number';
}
return self::$_result;
}
}
我会这样做
interface Evaluable {
public function evaluate();
}
class Value implements Evaluable {
private $value;
public function __construct($value) {
$this->value = $value;
}
public function evaluate() {
return $this->value();
}
}
class Node implements Evaluable {
protected $left;
protected $right;
public function __construct(Evaluable $left, Evaluable $right) {
$this->left = $left;
$this->right = $right;
}
}
class SumNode extends Node {
public function evaluate() {
return $this->left->evaluate() + $this->right->evaluate();
}
}
$op = new SumNode(new Value(2), new Value(3));
$result = $op->evaluate();
这样,您可以轻松地添加新操作
class SubNode extends Node {
public function evaluate() {
return $this->left->evaluate() - $this->right->evaluate();
}
}
还有像这样的连锁经营
- app/
- lib/
- Calculator/
- Operation/
- Addition.php
- Modulus.php
- Substraction.php
- OperationInterface.php
- Calculator.php
$sum1 = new SumNode(new Value(5), new Value(3));
$sum2 = new SumNode(new Value(1), new Value(2));
$op = new SubNode($sum1, $sum2);
$result = $op->evaluate();
请花一分钟将代码正确对齐。当代码乱七八糟时,几乎不可能读取它。请为您对齐它。:-)啊,对不起,我想我们是并行编辑的:)不妨使用一些链接功能来制作echo$calculator->setoperans(数组(4,2))->setOperation(新添加)->process()代码>可能?只需添加返回$this
在setOperands
和setOperation
方法上我喜欢stackoverflow。我肯定会在开关中添加一个默认大小写(除了一个例外),以防止输入错误和未知操作数。此外,您应该抛出异常,而不是执行回显。如果没有异常,代码将返回未定义的结果,从而导致PHP错误消息和/或奇怪的行为。除此之外,关于chandresh_cool.的建议,请参见我的其他评论。。对于计算公式的简单实用函数(如本例),它们可能是一个好主意,但如果您希望您的类是可单元测试的,请不要过度使用静态方法。您可能喜欢阅读-这家伙的答案是肯定的“是”。我同意。我的答案和图基的相似。我们都看了Misko的精彩视频:pDid你真的检查了脚本?乍一看,您缺少两件事:类节点
没有实现求值()
方法,类值
没有方法值()
,只有属性值
。但除此之外,得到图案的想法也很好!(Y) 哎呀,我刚刚想到,在PHP>=5.4上,可以在类扩展中实现“接口”方法。。。