PHP:设计模式之工厂模式

工厂模式是一种创建型设计模式,适用于动态创建多种不同类型的类的实例。在程序运行时确定对象类型,且存在一个抽象基类及其多个派生子类需要立即创建的情况。工厂模式通常通过静态方法实现,如`Create()`或`factoryMethod()`,接收参数来标识要创建的对象类型。在示例中,ShapeFactory类包含一个静态方法`createInstance()`,接受形状类型和尺寸作为参数,确保对象创建的正确性。使用工厂模式会导致与应用程序其他部分的紧密耦合。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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数组。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值