PHP设计模式--工厂模式

    以自己目前的经验来看,工厂模式是对具有相同操作但具体内容又不同的类进行封装,从而简化代码同时也降低耦合读。

    比如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.子类是完全分离开的,对于一个子类的修改,并不会影响到另一个子类的功能,并且子类还可以进行自己功能的扩展

    原文作者:Electricight
    原文地址: https://blog.csdn.net/qq_33302798/article/details/82229308
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞