以自己目前的经验来看,工厂模式是对具有相同操作但具体内容又不同的类进行封装,从而简化代码同时也降低耦合读。
比如PHP与数据库进行交互的扩展,有mysqli扩展或PDO扩展,但是两种扩展在数据库上的连接方式不同,在数据库上的增删查改方式也不同。 此时的需求就是按照指定的扩展对数据库进行操作,比如指定了PDO扩展,就已PDO的方式操作数据库。下面是代码示例:
不使用工厂模式来进行数据库连接:
<?php
class sql{
public $method;
public $conn;
public function __construct($method) {
$this->method=$method;
}
//以指定的方式连接数据库
public function connect(){
if($this->method=="PDO"){
$dsn="mysql:host=localhost;dbname=test";
$this->conn=new PDO($dsn,'root','123456');
}elseif($this->method=="mysqli"){
$this->conn=mysqli_connect('localhost','root','123456');
}
}
public function insert($data){
if($this->method="PDO"){
// PDO的相关插入操作
$sql="insert into test(`name`,`number`) values(?,?)";
$stmt=$this->conn->prepare($sql);
$stmt->bindValue(1,$data['name']);
$stmt->bindValue(2,$data['number']);
if($stmt->execute()){
echo "插入成功";
}else{
echo "插入失败";
}
$stmt=null;
}elseif($this->method='mysqli'){
$sql="insert into test(`name`,`number`) values({$data['name']},{$data['number']})";
if(mysqli_query($this->conn,$sql)){
echo "插入成功";
}else{
echo "插入失败";
}
}
}
}
$sql=new sql('mysqli');
$sql->connect();
$sql->insert();
这种方式,首先代码的阅读效果很差,然后如果在以后的某一天,想要修改PDO扩展的逻辑,将很烦燥,而且不注意的话还可能把mysqli的逻辑给修改了。
使用工厂模式来进行数据库连接:
//所有方式的基类,固定接口 DataBase.php
<?php
/** Date: 18-8-30 Time: 下午10:38*/
abstract class DataBase
{
public $conn;
abstract public function connect();
abstract public function insert($data);
}
//PDO类 Pdo.php
<?php
/** Date: 18-8-30 Time: 下午10:35*/
include_once "DataBase.php";
class Pdo extends DataBase{
public function connect() {
$dsn="mysql:host=localhost;dbname=test";
$this->conn=new PDO($dsn,'root','123456');
}
public function insert($data) {
// PDO的相关插入操作
$sql="insert into test(`name`,`number`) values(?,?)";
$stmt=$this->conn->prepare($sql);
$stmt->bindValue(1,$data['name']);
$stmt->bindValue(2,$data['number']);
if($stmt->execute()){
echo "插入成功";
}else{
echo "插入失败";
}
$stmt=null;
}
}
//MySqli类 MySqli.php
<?php
/** Date: 18-8-30 Time: 下午10:35*/
include_once "MySqli.php";
class MySqli extends DataBase{
public function connect() {
$dsn="mysql:host=localhost;dbname=test";
$this->conn=new PDO($dsn,'root','123456');
return $this;
}
public function insert($data) {
$sql="insert into test(`name`,`number`) values({$data['name']},{$data['number']})";
if(mysqli_query($this->conn,$sql)){
echo "插入成功";
}else{
echo "插入失败";
}
}
}
//工厂类 Factory.php
<?php
/** Date: 18-8-30 Time: 下午10:36*/
include_once "MySqli.php";
include_once "Pdo.php";
class Factory {
public function getInstance($method=''){
if($method==''){
echo "请选择方式";
}
try{
$reflectionClass=new ReflectionClass($method);
}catch (Throwable $e){
echo "该方式不存在";
}
return $reflectionClass->newInstance();
}
}
//客户端类 Client.php
<?php
/** Date: 18-8-30 Time: 下午10:49*/
include_once "Factory.php";
$factory=new Factory();
$pdo=$factory->getInstance('Pdo');
$pdo->connect();
$pdo->insert();
//或者
$mysqli=$factory->getInstance('MySqli');
$mysqli->connect();
$mysqli->insert();
在DataBase类中,固定子类需要实现的共有方法,然后子类继承实现DataBase类,然后在Factory类中,通过类的反射来实例化指定的类,客户端类中,就来调用Factory类,从而实现工厂模式。
分析使用工厂模式的好处:提高了代码的灵活性,降低了耦合度。
1.将各个类的实现分离开,代码阅读上更加美观
2.只给用户提供一个Factory类的接口,用户就可以使用相关的函数,而不必去管里面是怎样实现的
3.子类是完全分离开的,对于一个子类的修改,并不会影响到另一个子类的功能,并且子类还可以进行自己功能的扩展