PHP:设计模式之工厂模式

    xiaoxiao2021-03-25  47

    工厂模式是一种创建型模式,它可能会被用于创建多种不同类型的类的多个对象。工厂模式在以下的场景中比较适用:

    1、当程序编写的时候,并不能确定在生成对象的时候其确切的对象类型,只有当程序运行的才会确定。在动态的应用程序中,这种情况非常常见。

    2、举个例子,现在有一个抽象的基类,它的几个不同的派生子类需要立即被创建。这种设计结构是很适合使用工厂模式的,因为我们一旦创建了一个对象,对这个对象的使用就会和期望的保持一致,而不用关心它的确切类型。

    工厂模式通常通过一个静态方法来实现,一般情况下,该方法被命名为Create()、factory()、factoryMethod()或createInstance()。这个方法至少应接收一个参数,用于标示将要创建的对象的类型。这个方法会返回该类型的一个对象。

    示例程序:

    abstract class Shape { abstract protected function getPerimeter(); abstract protected function getArea(); } 将其保存为:shape.php

    class Triangle extends Shape { private $_sides = array(); private $_perimeter = NULL; function __construct($s0, $s1, $s2) { $this->_sides[] = $s0; $this->_sides[] = $s1; $this->_sides[] = $s2; $this->_perimeter = array_sum($this->_sides); } public function getArea() { return sqrt(($this->_perimeter / 2) * (($this->_perimeter / 2) - $this->_sides[0]) * (($this->_perimeter / 2) - $this->_sides[1]) * (($this->_perimeter / 2) - $this->_sides[2]) ); } function getPerimeter() { return $this->_perimeter; } } 将其保存为:triangle.php

    class Rectangle { protected static $_count = 0; protected $width; protected $height; function __construct($width, $height) { $this->width = $width; $this->height = $height; self::$_count++; echo "已成功创建".self::$_count."个Rectangle对象<br>"; } function __destruct() { echo "销毁一个Rectangle对象<br>"; } function getArea() { echo "Rectangle面积是:".($this->width * $this->height."<br>"); } function getConunt() { return self::$_count; } }将其保存为:rectangle.php

    abstract class ShapeFactory { static function createInstance($shape, array $sizes) { switch ($shape) { case 'rectangle': return new Rectangle($sizes[0], $sizes[1]); break; default: return new Triangle($sizes[0], $sizes[1], $sizes[2]); break; } } } 将其保存为:shapeFactory.php

    接下来创建一个测试程序:testFactory.php

    require('shapeFactory.php'); require('shape.php'); require('triangle.php'); require('rectangle.php'); if (isset($_GET['shape'], $_GET['dimensions'])) { $obj = ShapeFactory::createInstance($_GET['shape'], $_GET['dimensions']); echo $obj->getArea(); } else { echo "Error"; } 在浏览器中运行这个程序:

    localhost/demo/php/testFactory.php?shape=rectangle&dimensions[]=12&dimensions[]=10

    http://localhost/demo/php/testFactory.php?shape=triangle&dimensions[]=6&dimensions[]=8&dimensions[]=10

    总结一下:在示例中工厂类将会是抽象的,我们永远也得不到工厂类的一个实例,就像示例中的Shape类本身一样。同时工厂类没有任何属性,它只有一个用于创建对象实例的静态方法,该方法至少有一个参数,用于标示要创建的实例的类型,在示例中,又添了一个$sizes参数用于接收各边长,同时我们使用了类型提示来保证输入的参数为数组类型。

    使用工厂模式时,由于它内部的验证,使得工厂类和应用程序的其他部分紧密耦合在一起。看一下ShapeFactory的createInstance()方法,它会假设传进一个$sizes数组。

    转载请注明原文地址: https://ju.6miu.com/read-50121.html

    最新回复(0)