什么是工厂模式
工厂模式是一种类,可以理解为创建类实例的工厂,它具有创建对象的某些方法。可以使用工厂类创建对象,而不直接使用 new。这样,如果想要更改所创建的对象类型,只需更改该工厂即可。使用该工厂的所有代码会自动更改。
根据抽象程度不同,php工厂模式分为:简单工厂、工厂方法和抽象工厂。
区别
三种工厂的区别是,抽象工厂由多条产品线,而工厂方法只有一条产品线,是抽象工厂的简化。而工厂方法和简单工厂相对,大家初看起来好像工厂方法增加了许多代码但是实现的功能和简单工厂一样。但本质是,简单工厂并未严格遵循设计模式的开闭原则,当需要增加新产品时也需要修改工厂代码。但是工厂方法则严格遵守开闭原则,模式只负责抽象工厂接口,具体工厂交给客户去扩展。在分工时,核心工程师负责抽象工厂和抽象产品的定义,业务工程师负责具体工厂和具体产品的实现。
1、简单工厂
简单工厂又叫静态工厂方法模式,这样理解可以确定,简单工厂模式是通过一个静态方法创建对象的。
<?php
/**
* 产品接口
* Interface ProductInterface
*/
interface ProductInterface
{
public function showProductInfo();
}
/**
* 接口实现 产品A
* Class ProductA
*/
class ProductA implements ProductInterface
{
function showProductInfo()
{
echo 'This is product A.';
}
}
/**
* 接口实现 产品B
* Class ProductB
*/
class ProductB implements ProductInterface
{
function showProductInfo()
{
echo 'This is product B.';
}
}
//=======================以下为工厂===============================
/**
* 工厂类
* Class ProductFactory
*/
class ProductFactory
{
/**
* 工厂静态方法
* @param $ProductType
* @return mixed
*/
public static function factory($ProductType)
{
$ProductType = 'Product' . strtoupper($ProductType);
if(class_exists($ProductType))
{
return new $ProductType();
} else {
throw new \Exception("Error Processing Request", 1);
}
}
}
//=======================工厂方法调用===============================
$factory = ProductFactory::factory('A');
$factory->showProductInfo();
echo '<hr>';//横线
$factory = ProductFactory::factory('B');
$factory -> showProductInfo();
//结果
//This is product A.
//This is product B.
2、工厂方法
<?php
/**
* 产品接口
* Interface ProductInterface
*/
interface ProductInterface
{
public function showProductInfo();
}
/**
* 接口实现 产品A
* Class ProductA
*/
class ProductA implements ProductInterface
{
function showProductInfo()
{
echo 'This is product A.';
}
}
/**
* 接口实现 产品B
* Class ProductB
*/
class ProductB implements ProductInterface
{
function showProductInfo()
{
echo 'This is product B.';
}
}
//=======================以下为工厂===============================
/**
* 工厂接口
* Interface CommFactory
*/
interface factory {
public function getProduct();
}
/**
* 产品A工厂方法
* Class ProductA
*/
class ProductAFactory implements factory {
public function getProduct(){
return new ProductA();
}
}
/**
* 产品B工厂方法
* Class ProductB
*/
class ProductBFactory implements factory {
public function getProduct() {
return new ProductB();
}
}
//=======================工厂方法调用===============================
$factory = new ProductAFactory();
echo $factory->getProduct()->showProductInfo();
echo '<hr>';//横线
$factory = new ProductBFactory();
echo $factory->getProduct()->showProductInfo();
//结果
//This is product A.
//This is product B.
3、抽象工厂
<?php
/**
* 产品接口
* Interface ProductInterface
*/
interface ProductInterface
{
public function showProductInfo();
}
/**
* 接口实现 产品A
* Class ProductA
*/
class ProductA implements ProductInterface
{
function showProductInfo()
{
echo 'This is product A.';
}
}
/**
* 接口实现 产品B
* Class ProductB
*/
class ProductB implements ProductInterface
{
function showProductInfo()
{
echo 'This is product B.';
}
}
/**
* 抽象工厂模式另一条产品线
* Interface Grade
*/
interface Grade {
function getYear();
}
/**
* 另一条产品线的具体产品
* Class Grade1
*/
class Grade1 implements Grade {
public function getYear() {
echo '2013 ';
}
}
/**
* 另一条产品线的具体产品
* Class Grade2
*/
class Grade2 implements Grade {
public function getYear() {
echo '2019 ';
}
}
//=======================以下为工厂===============================
/**
* 抽象工厂
* Interface AbstractFactory
*/
interface AbstractFactory {
public function getProduct();
public function getGrade();
}
/**
* 具体工厂可以产生每个产品线的产品
* Class Grade1TeacherFactory
*/
class Grade1ProductAFactory implements AbstractFactory {
public function getProduct() {
return new ProductA();
}
public function getGrade() {
return new Grade1();
}
}
/**
* 具体工厂可以产生每个产品线的产品
* Class Grade1ProductBFactory
*/
class Grade1ProductBFactory implements AbstractFactory {
public function getProduct() {
return new ProductB();
}
public function getGrade() {
return new Grade1();
}
}
/**
* 具体工厂可以产生每个产品线的产品
* Class Grade2ProductAFactory
*/
class Grade2ProductAFactory implements AbstractFactory {
public function getProduct() {
return new ProductA();
}
public function getGrade() {
return new Grade2();
}
}
//=======================工厂方法调用===============================
$factory = new Grade1ProductAFactory();
$factory->getGrade()->getYear() . $factory->getProduct()->showProductInfo();
echo '<hr>';//横线
$factory = new Grade1ProductBFactory();
$factory->getGrade()->getYear() . $factory->getProduct()->showProductInfo();
echo '<hr>';//横线
$factory = new Grade2ProductAFactory();
$factory->getGrade()->getYear() . $factory->getProduct()->showProductInfo();
//结果
//2013 This is product A.
//2013 This is product B.
//2019 This is product A.