要求:计算长方形及三角形的周长与面积
面向过程的写法如下:
class Polygon_old { private $sides = []; private $shapes = ['rect', 'triangle']; // 支持的多边形 private $shape = ''; // 多边形形状 public function __construct(string $shape, array $sides) { if (in_array($shape, $this->shapes)) { $this->shape = $shape; } $this->sides = $sides; } public function perimeter () { switch ($this->shape) { case 'rect' : $perimeter = ($this->sides[0] + $this->sides[1]) * 2; break; case 'triangle' : $perimeter = $this->sides[0] + $this->sides[1] + $this->sides[2]; break; default: throw new \Exception("不支持的图像计算类型"); } return $perimeter; } public function area () { switch ($this->shape) { case 'rect' : $area = $this->sides[0] * $this->sides[1]; break; case 'triangle' : $p = ($this->sides[0] + $this->sides[1] + $this->sides[2]) / 2; $area = sqrt($p * ($p - $this->sides[0]) * ($p-$this->sides[1]) * ($p - $this->sides[2])); break; default: throw new \Exception("不支持的图像计算类型"); } return $area; } }
以上代码会有一些问题
代码耦合度太高,难以维护。所有多边形的周长和面积全都使用一个方法去完成,如果再新增一个计算圆形的周长和面积的话,必须要修改该类。有过经验的应该知道,修改正式环境的代码极易出现问题。
另外,我只要计算圆形的周长和面积。为什么要让和计算圆形无关的代码参与编译。
改进如下
Polygon.php代码如下:
<?php namespace simplefactory; class Polygon { private $shape = null; public function __construct(string $shape, array $sides) { $class = '\simplefactory\\' . $shape; if (class_exists($class)) { /* 基本工厂模式的运用 */ $this->shape = new $class($sides); } else { throw new \Exception('不支持的图形计算类型'); } } public function perimeter () { return $this->shape->perimeter(); } public function area () { return $this->shape->area(); } }
图形计算的基类Shape.php,代码如下:
<?php namespace simplefactory; abstract class Shape { protected $sides = []; public function __construct(array $sides) { $this->sides = $sides; } abstract public function perimeter (); abstract public function area (); }
计算长方形周长面积类Rect.php,代码如下:
<?php namespace simplefactory; class Rect extends Shape { public function perimeter () { return ($this->sides[0] + $this->sides[1]) * 2; } public function area () { return $this->sides[0] * $this->sides[1]; } }
计算三角形周长面积类Triangle.php,代码如下:
<?php namespace simplefactory; class Triangle extends Shape { public function perimeter () { return $this->sides[0] + $this->sides[1] + $this->sides[2]; } public function area () { $p = ($this->sides[0] + $this->sides[1] + $this->sides[2]) / 2; return sqrt($p * ($p - $this->sides[0]) * ($p-$this->sides[1]) * ($p - $this->sides[2])); } }
常见的工厂模式的应用:在MVC设计中,根据参数来new 出相应控制器