以OOP之名--重构PHP代码小教程(1)

    技术2025-08-21  22

    前言:把TennisGame进行到底

    Step 3: OOP化

    OOP是种便于程序设计的好概念,尤其是类型声明引入PHP后,OOP的作用被强化了。

    把player OOP化

    <?php class TennisGame{ public function getScore(Player $player1, Player $player2){ $score = ''; if($player1->score == $player2->score){ switch($player1->core){ 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($player1->score >= 4 || $player2->score >=4 ){ $nimusResult = $player1->score - $player2->score; if($minusResult == 1) $score = "Advantange" . $player1->name; else if($minusResult == -1) $score = "Advantange" . $player2->name; else if ($minusResult >= 2) $score = "Win for" . $player1->name; else $score = "Win for" . $player2->name; return $score; } for($i = 1;$i < 3; $i ++){ if($i == 1) $tempScore = $player1->score; else { $score .="-"; $tempScore = $player2->score; } switch($tempScore){ case 0: $score .="Love"; break; case 1: $score .="Fifteen"; break; case 2: $score .="Thirty"; break; case 3: $score .="Forty"; break; } } return $score; } } class Player{ public $name; public $score; public function __construct(string $name,int $score){ $this->name = $name; $this->score = $score; } } $player1 = new Player('one',2); $player2 = new Player('two',3); $tennisGame = new TennisGame(); echo $tennisGame->getScore($player1,$player2); // echo $tennisGame; ?>

    Step 4: Score OOP化

    这里分别针对游戏结束,游戏进行中等情况进行OOP化,这样,就可以把getScore的内容进行压缩。

    <?php class TennisGame{ public function getScore(Player $player1, Player $player2){ if($player1->score == $player2->score){ return new EqualScore($player1); } if($player1->score >= 4 || $player2->score >=4 ){ return new EndgameScore($player1, $player2); } return new RegularScore($player1, $player2); } } class Player{ public $name; public $score; public function __construct(string $name,int $score){ $this->name = $name; $this->score = $score; } } class EqualScore{ public $player1; public function __construct(Player $player1){ $this->player1 = $player1; } public function __toString(){ switch($player1->core){ 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; } } } class EndgameScore{ public $player1,$player2; public function __construct(Player $player1,Player $player2){ $this->player1 = $player1; $this->player2 = $player2; } public function __toString(){ $nimusResult = $this->player1->score - $this->player2->score; if($minusResult == 1) $score = "Advantange" . $this->player1->name; else if($minusResult == -1) $score = "Advantange" . $this->player2->name; else if ($minusResult >= 2) $score = "Win for" . $this->player1->name; else $score = "Win for" . $this->player2->name; return $score; } } class RegularScore{ public $player1,$player2; public function __construct(Player $player1,Player $player2){ $this->player1 = $player1; $this->player2 = $player2; } public function __toString(){ $score = ''; for($i = 1;$i < 3; $i ++){ if($i == 1) $tempScore = $this->player1->score; else { $score .="-"; $tempScore = $this->player2->score; } switch($tempScore){ case 0: $score .="Love"; break; case 1: $score .="Fifteen"; break; case 2: $score .="Thirty"; break; case 3: $score .="Forty"; break; } } return $score; } } $player1 = new Player('one',2); $player2 = new Player('two',3); $tennisGame = new TennisGame(); echo $tennisGame->getScore($player1,$player2); // echo $tennisGame; ?>

    Step 5:针对多种Score,通过继承把__construct提取出来

    <?php class TennisGame{ public function getScore(Player $player1, Player $player2){ if($player1->score == $player2->score){ return new EqualScore($player1); } if($player1->score >= 4 || $player2->score >=4 ){ return new EndgameScore($player1, $player2); } return new RegularScore($player1, $player2); } } class Player{ public $name; public $score; public function __construct(string $name,int $score){ $this->name = $name; $this->score = $score; } } abstract class Score{ public $player1,$player2; public function __construct(Player $player1,Player $player2){ $this->player1 = $player1; $this->player2 = $player2; } abstract function __toString(); } class EqualScore extends Score{ public function __toString(){ switch($player1->core){ 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; } } } class EndgameScore extends Score{ public function __toString(){ $nimusResult = $this->player1->score - $this->player2->score; if($minusResult == 1) $score = "Advantange" . $this->player1->name; else if($minusResult == -1) $score = "Advantange" . $this->player2->name; else if ($minusResult >= 2) $score = "Win for" . $this->player1->name; else $score = "Win for" . $this->player2->name; return $score; } } class RegularScore extends Score{ public function __toString(){ $score = ''; for($i = 1;$i < 3; $i ++){ if($i == 1) $tempScore = $this->player1->score; else { $score .="-"; $tempScore = $this->player2->score; } switch($tempScore){ case 0: $score .="Love"; break; case 1: $score .="Fifteen"; break; case 2: $score .="Thirty"; break; case 3: $score .="Forty"; break; } } return $score; } } $player1 = new Player('one',2); $player2 = new Player('two',3); $tennisGame = new TennisGame(); echo $tennisGame->getScore($player1,$player2); // echo $tennisGame; ?>

    Step 6:switch变量以array常量来进行规范化

    <?php class TennisGame{ public function getScore(Player $player1, Player $player2){ if($player1->score == $player2->score){ return new EqualScore($player1); } if($player1->score >= 4 || $player2->score >=4 ){ return new EndgameScore($player1, $player2); } return new RegularScore($player1, $player2); } } class Player{ public $name; public $score; public function __construct(string $name,int $score){ $this->name = $name; $this->score = $score; } } abstract class Score{ public $player1,$player2; const VALUES = [ 0=>'Love', 1=>'Fifteen', 2=>'Thirty', 3=>'Forty' ]; public function __construct(Player $player1,Player $player2){ $this->player1 = $player1; $this->player2 = $player2; } public function getScore(int $score){ return self::VALUES[$score] ?? ''; } abstract function __toString(); } class EqualScore extends Score{ public function __toString(){ $score = $this->getScore($this->player1->score); return $score ? $score.'-All':'Deuce'; } } class EndgameScore extends Score{ public function __toString(){ $nimusResult = $this->player1->score - $this->player2->score; if($minusResult == 1) $score = "Advantange" . $this->player1->name; else if($minusResult == -1) $score = "Advantange" . $this->player2->name; else if ($minusResult >= 2) $score = "Win for" . $this->player1->name; else $score = "Win for" . $this->player2->name; return $score; } } class RegularScore extends Score{ public function __toString(){ // $score = ''; // for($i = 1;$i < 3; $i ++){ // if($i == 1) // $tempScore = $this->player1->score; // else // { // $score .="-"; // $tempScore = $this->player2->score; // } // switch($tempScore){ // case 0: // $score .="Love"; // break; // case 1: // $score .="Fifteen"; // break; // case 2: // $score .="Thirty"; // break; // case 3: // $score .="Forty"; // break; // } // } // return $score; return $this->getScore($this->player1->score) . '-' . $this->getScore($this->player2->score); } } $player1 = new Player('one',2); $player2 = new Player('two',3); $tennisGame = new TennisGame(); echo $tennisGame->getScore($player1,$player2); // echo $tennisGame; ?>

    Step 7:最后一步三目运算符压缩程序

    <?php class TennisGame{ public function getScore(Player $player1, Player $player2){ if($player1->score == $player2->score){ return new EqualScore($player1); } if($player1->score >= 4 || $player2->score >=4 ){ return new EndgameScore($player1, $player2); } return new RegularScore($player1, $player2); } } class Player{ public $name; public $score; public function __construct(string $name,int $score){ $this->name = $name; $this->score = $score; } } abstract class Score{ public $player1,$player2; const VALUES = [ 0=>'Love', 1=>'Fifteen', 2=>'Thirty', 3=>'Forty' ]; public function __construct(Player $player1,Player $player2){ $this->player1 = $player1; $this->player2 = $player2; } public function getScore(int $score){ return self::VALUES[$score] ?? ''; } abstract function __toString(); } class EqualScore extends Score{ public function __toString(){ $score = $this->getScore($this->player1->score); return $score ? $score.'-All':'Deuce'; } } class EndgameScore extends Score{ public function __toString(){ $diff = $this->player1->score - $this->player2->score; $name = $diff > 0 ? $this->player1->name:$this->player2->name; return (abs($diff) ===1 ? 'Advantage':'Win for ') . $name; } } class RegularScore extends Score{ public function __toString(){ return $this->getScore($this->player1->score) . '-' . $this->getScore($this->player2->score); } } $player1 = new Player('one',7); $player2 = new Player('two',15); $tennisGame = new TennisGame(); echo $tennisGame->getScore($player1,$player2); ?>

    后记:最后的几步逻辑与原始代码有所出入,重点在演示每一步是怎么做的。关键在于OOP化,把需要做成OOP的内容提取出来,独立成class,同时用到了三目运算符进行程序压缩,以及switch以array的形式进行替代。

    Processed: 0.014, SQL: 9