前言:由于一些历史原因,偶尔还是会遇到一些陈年老码,笔者学习PHP的过程中第二个阶段就重构了一些项目实战的源代码(基于PHP4+HMTL4的改成PHP7+HTML5)。就目前业界而言,多数PHP网站只是一锤子买卖--业者花一次钱,之后就要求跑一万年,因此至今仍然有一些基于PHP4、PHP5、HTML4的项目在运行。但是,针对一些需要更新后续的网站,要么第一次创建时需要考虑选择MVC框架,要么就需要重构PHP代码。
关于重构,不同人有不同观点:OOP化,函数更新,函数签名重置,MVC化,等等。
本将着重在OOP化上,以2个例子TennisGame以及Insturance为例子一步一步演示如何进行OOP重构。
案例一:网球小案例 tennisgame.php
这里是个非OOP的小代码,后续会基于该代码进行修改。可以看得出除了class、new一类的内容,代码本身几乎没有什么OOP的内容。
<?php
class TennisGame{
public $score = '';
public function getScore($player1Name, $player2Name, $p1Score, $p2Score){
if($p1Score == $p2Score){
switch($p1Score){
case 0:
$this->score = 'Love-All';
break;
case 1:
$this->score = 'Fifteen-All';
break;
case 2:
$this->score = 'Thirty-All';
break;
case 3:
$this->score = 'Forty-All';
break;
default:
$this->score = 'Deuce';
break;
}
}
else if($p1Score >= 4 || $p2Score >=4 ){
$nimusResult = $p1Score - $p2Score;
if($minusResult == 1)
$this->score = "Advantange" . $player1Name;
else if($minusResult == -1)
$this->score = "Advantange" . $player2Name;
else if ($minusResult >= 2)
$this->score = "Win for" . $player1Name;
else
$this->score = "Win for" . $player2Name;
}else{
for($i = 1;$i < 3; $i ++){
if($i == 1)
$tempScore = $p1Score;
else
{
$this->score .="-";
$tempScore = $p2Score;
}
switch($tempScore){
case 0:
$this->score .="Love";
break;
case 1:
$this->score .="Fifteen";
break;
case 2:
$this->score .="Thirty";
break;
case 3:
$this->score .="Forty";
break;
}
}
}
}
public function __toString(){
return $this->score;
}
}
$tennisGame = new TennisGame();
$tennisGame->getScore('one','two',2,3);
echo $tennisGame;
?>
命令行php tennisgame.php
返回Thirty-Forty
Step 0 : getScore,常见的getter就是用来返回值的,这里的最后一行就变得多余了,以echo替换,进而,toString()也变得多余了:
<?php
class TennisGame{
public $score = '';
public function getScore($player1Name, $player2Name, $p1Score, $p2Score){
if($p1Score == $p2Score){
switch($p1Score){
case 0:
$this->score = 'Love-All';
break;
case 1:
$this->score = 'Fifteen-All';
break;
case 2:
$this->score = 'Thirty-All';
break;
case 3:
$this->score = 'Forty-All';
break;
default:
$this->score = 'Deuce';
break;
}
}
else if($p1Score >= 4 || $p2Score >=4 ){
$nimusResult = $p1Score - $p2Score;
if($minusResult == 1)
$this->score = "Advantange" . $player1Name;
else if($minusResult == -1)
$this->score = "Advantange" . $player2Name;
else if ($minusResult >= 2)
$this->score = "Win for" . $player1Name;
else
$this->score = "Win for" . $player2Name;
}else{
for($i = 1;$i < 3; $i ++){
if($i == 1)
$tempScore = $p1Score;
else
{
$this->score .="-";
$tempScore = $p2Score;
}
switch($tempScore){
case 0:
$this->score .="Love";
break;
case 1:
$this->score .="Fifteen";
break;
case 2:
$this->score .="Thirty";
break;
case 3:
$this->score .="Forty";
break;
}
}
}
return $this->score;
}
}
$tennisGame = new TennisGame();
echo $tennisGame->getScore('one','two',2,3);
?>
Step 1:认真考虑变量是否是类变量还是方法的局部变量
关于局部变量还是类变量,没有一个统一的概念。在这里,我们姑且把类变量$score修改成局部变量
<?php
class TennisGame{
public function getScore($player1Name, $player2Name, $p1Score, $p2Score){
$score = '';
if($p1Score == $p2Score){
switch($p1Score){
case 0:
$score = 'Love-All';
break;
case 1:
$score = 'Fifteen-All';
break;
case 2:
$score = 'Thirty-All';
break;
case 3:
$score = 'Forty-All';
break;
default:
$score = 'Deuce';
break;
}
}
else if($p1Score >= 4 || $p2Score >=4 ){
$nimusResult = $p1Score - $p2Score;
if($minusResult == 1)
$score = "Advantange" . $player1Name;
else if($minusResult == -1)
$score = "Advantange" . $player2Name;
else if ($minusResult >= 2)
$score = "Win for" . $player1Name;
else
$score = "Win for" . $player2Name;
}else{
for($i = 1;$i < 3; $i ++){
if($i == 1)
$tempScore = $p1Score;
else
{
$score .="-";
$tempScore = $p2Score;
}
switch($tempScore){
case 0:
$score .="Love";
break;
case 1:
$score .="Fifteen";
break;
case 2:
$score .="Thirty";
break;
case 3:
$score .="Forty";
break;
}
}
}
return $score;
}
}
$tennisGame = new TennisGame();
echo $tennisGame->getScore('one','two',2,3);
?>
step 2:提早return原则
提早return原则是一般写程序时一个常见的优化原则,把能return的放到if语句块中,尽早return。
<?php
class TennisGame{
public function getScore($player1Name, $player2Name, $p1Score, $p2Score){
$score = '';
if($p1Score == $p2Score){
switch($p1Score){
case 0:
$score = 'Love-All';
break;
case 1:
$score = 'Fifteen-All';
break;
case 2:
$score = 'Thirty-All';
break;
case 3:
$score = 'Forty-All';
break;
default:
$score = 'Deuce';
break;
}
return $score;
}
if($p1Score >= 4 || $p2Score >=4 ){
$nimusResult = $p1Score - $p2Score;
if($minusResult == 1)
$score = "Advantange" . $player1Name;
else if($minusResult == -1)
$score = "Advantange" . $player2Name;
else if ($minusResult >= 2)
$score = "Win for" . $player1Name;
else
$score = "Win for" . $player2Name;
return $score;
}
for($i = 1;$i < 3; $i ++){
if($i == 1)
$tempScore = $p1Score;
else
{
$score .="-";
$tempScore = $p2Score;
}
switch($tempScore){
case 0:
$score .="Love";
break;
case 1:
$score .="Fifteen";
break;
case 2:
$score .="Thirty";
break;
case 3:
$score .="Forty";
break;
}
}
return $score;
}
// public function __toString(){
// return $this->score;
// }
}
$tennisGame = new TennisGame();
echo $tennisGame->getScore('one','two',2,3);
// echo $tennisGame;
?>