前言:把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的形式进行替代。