PHP 設計模式之三種工廠模式


簡單工廠

通過靜態方法傳入不同的參數創建不同的對象,實現對象創建和使用的分離

<?php
class mysql_conn {
    private $dbh = null;
    private $host = 'localhost';
    private $port = '3306';
    private $user = 'root';
    private $password = '****';
    private $dbname = 'test';

    public function __construct() {
        $this->dbh = new PDO('mysql:host=' . $this->host . ';port=' . $this->port . ';dbname=' . $this->dbname, $this->user, $this->password);
    }

    public function get_table_data($table_name) {
        foreach($this->dbh->query("SELECT * from `$table_name`") as $row) {
            echo "<pre>";
            print_r($row);
            echo "</pre>";
        }
    }
}

class psql_conn {
    private $dbh = null;
    private $host = 'localhost';
    private $port = '5432';
    private $user = 'postgres';
    private $password = '****';
    private $dbname = 'test';

    public function __construct() {
        $this->dbh = new PDO('pgsql:host=' . $this->host . ';port=' . $this->port . ';dbname=' . $this->dbname, $this->user, $this->password);
    }

    public function get_table_data($table_name) {
        foreach($this->dbh->query("SELECT * from `$table_name`") as $row) {
            echo "<pre>";
            print_r($row);
            echo "</pre>";
        }
    }

    public function custom_query($sql) {
        $stmt = $this->dbh->prepare($sql);
        $stmt->execute();
        foreach ($stmt as $row) {
            echo "<pre>";
            print_r($row);
            echo "</pre>";
        }
    }
}

class Factory {
    public static function pdo_conn($db = 'mysql') {
        if ($db == 'mysql') {
            return new mysql_conn();
        }
        else if ($db == 'psql') {
            return new psql_conn();
        }
    }
}

// mysql
// $mysql_dbh = Factory::pdo_conn('mysql');
// $mysql_dbh->get_table_data('user');
// $mysql_dbh->get_table_data('order');

// postgresql
// $psql_dbh = Factory::pdo_conn('psql');
// $psql_dbh->custom_query('select * from student');

 

通過上面的代碼可以看出,簡單工廠的缺點就是后面如果想增加新的連接,需要頻繁地去修改靜態方法

工廠方法

通過定義一個抽象的核心工廠類,並定義創建產品對象的接口。
創建具體產品示例的工作延遲到其工廠子類去完成。

當系統需要新增一個產品是,無需修改現有系統代碼,只需要添加一個具體產品類和其對應的工廠子類,使系統的擴展性變得很好,符合面向對象編程的開閉原則;

<?php
interface database_option {
    public function custom_query($sql);
    public function get_table_data($table_name);
}

class mysql_conn implements database_option {
    private $dbh = null;
    private $host = 'localhost';
    private $port = '3306';
    private $user = 'root';
    private $password = '****';
    private $dbname = 'test';

    public function __construct() {
        $this->dbh = new PDO('mysql:host=' . $this->host . ';port=' . $this->port . ';dbname=' . $this->dbname, $this->user, $this->password);
    }

    public function get_table_data($table_name) {
        foreach($this->dbh->query("SELECT * from `$table_name`") as $row) {
            echo "<pre>";
            print_r($row);
            echo "</pre>";
        }
    }

    public function custom_query($sql) {
        $stmt = $this->dbh->prepare($sql);
        $stmt->execute();
        foreach ($stmt as $row) {
            echo "<pre>";
            print_r($row);
            echo "</pre>";
        }
    }
}

class psql_conn implements database_option {
    private $dbh = null;
    private $host = 'localhost';
    private $port = '5432';
    private $user = 'postgres';
    private $password = '****';
    private $dbname = 'test';

    public function __construct() {
        $this->dbh = new PDO('pgsql:host=' . $this->host . ';port=' . $this->port . ';dbname=' . $this->dbname, $this->user, $this->password);
    }

    public function get_table_data($table_name) {
        foreach($this->dbh->query("SELECT * from `$table_name`") as $row) {
            echo "<pre>";
            print_r($row);
            echo "</pre>";
        }
    }

    public function custom_query($sql) {
        $stmt = $this->dbh->prepare($sql);
        $stmt->execute();
        foreach ($stmt as $row) {
            echo "<pre>";
            print_r($row);
            echo "</pre>";
        }
    }
}

abstract class Factory {
    abstract static function pdo_conn();
}

class mysql_Factory extends Factory {
    public static function pdo_conn() {
        return new mysql_conn();
    }
}

class psql_Factory extends Factory {
    public static function pdo_conn() {
        return new psql_conn();
    }
}

// mysql
// $mysql_dbh = mysql_Factory::pdo_conn();
// $mysql_dbh->get_table_data('order');

// psql
// $psql_dbh = psql_Factory::pdo_conn();
// $psql_dbh->custom_query('select * from student');

 

工廠方法是簡單工廠的進一步抽象,由於使用了面向對象的多態性,工廠方法保持了簡單工廠的優點,在工廠方法中,核心的工廠類不再負責所有產品的創建,而是將具體創建工作交給子類。所以可以在不修改工廠方法的情況下引入新的產品,復合開閉原則。

抽象工廠

提供一個創建一系列相關或相互依賴對象的接口,而無須指定它們具體的類。

在工廠方法模式中,一個具體的工廠負責生產一類具體的產品,即一對一的關系,但是,如果需要一個具體的工廠生產多種產品對象,那么就需要用到抽象工廠模式了。

<?php
interface database_option {
    public function custom_query($sql);
    public function get_table_data($table_name);
}

class mysql_conn implements database_option {
    private $dbh = null;
    private $host = 'localhost';
    private $port = '3306';
    private $user = 'root';
    private $password = '****';
    private $dbname = 'test';

    public function __construct() {
        $this->dbh = new PDO('mysql:host=' . $this->host . ';port=' . $this->port . ';dbname=' . $this->dbname, $this->user, $this->password);
    }

    public function get_table_data($table_name) {
        foreach($this->dbh->query("SELECT * from `$table_name`") as $row) {
            echo "<pre>";
            print_r($row);
            echo "</pre>";
        }
    }

    public function custom_query($sql) {
        $stmt = $this->dbh->prepare($sql);
        $stmt->execute();
        foreach ($stmt as $row) {
            echo "<pre>";
            print_r($row);
            echo "</pre>";
        }
    }
}

class psql_conn implements database_option {
    private $dbh = null;
    private $host = 'localhost';
    private $port = '5432';
    private $user = 'postgres';
    private $password = '****';
    private $dbname = 'test';

    public function __construct() {
        $this->dbh = new PDO('pgsql:host=' . $this->host . ';port=' . $this->port . ';dbname=' . $this->dbname, $this->user, $this->password);
    }

    public function get_table_data($table_name) {
        foreach($this->dbh->query("SELECT * from `$table_name`") as $row) {
            echo "<pre>";
            print_r($row);
            echo "</pre>";
        }
    }

    public function custom_query($sql) {
        $stmt = $this->dbh->prepare($sql);
        $stmt->execute();
        foreach ($stmt as $row) {
            echo "<pre>";
            print_r($row);
            echo "</pre>";
        }
    }
}

abstract class Factory {
    abstract public static function create_mysql_conn();
    abstract public static function create_psql_conn();
}

class db_Factory extends Factory {
    public static function create_mysql_conn() {
        return new mysql_conn();
    }

    public static function create_psql_conn() {
        return new psql_conn();
    }
}

// mysql
// $mysql_dbh = db_Factory::create_mysql_conn();
// $mysql_dbh->get_table_data('order');

// psql
// $psql_dbh = db_Factory::create_psql_conn();
// $psql_dbh->custom_query('select * from student');

 

原文地址:https://www.ryanzoe.top/%e8%ae%be%e8%ae%a1%e6%a8%a1%e5%bc%8f/php-factory-design-pattern/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM