PHP设计模式--工厂模式

博客介绍了工厂模式在数据库连接中的应用。以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.子类是完全分离开的,对于一个子类的修改,并不会影响到另一个子类的功能,并且子类还可以进行自己功能的扩展

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值