PHP 三种基础设计模式(工厂模式、单例模式、注册器模式)以及适配器模式

相关内容:
1. PHP 三种基础设计模式(工厂模式、单例模式、注册器模式)以及适配器模式
2. PHP 设计模式之策略模式、数据对象映射模式、观察者模式、原型模式、装饰器模式、迭代器模式、代理模式

1. 工厂模式;

  • 使用一个工厂方法或者类生成对象,而不是在代码中直接 new
  • 如果不使用工厂模式,如果想要创建一个对象,就需要 new 这个对象。如果是工厂模式的话,就是用一个工厂方法来替换直接 new 对象的操作
  • 在之前的基础框架上继续演示
    在这里插入图片描述
  • 新增:Library/Database.php
<?php 
namespace Library;

class Database{

}
  • 新增:Library/Factory.php
<?php 
namespace Library;

// 工厂类
class Factory{

    static function createDatabase(){
        $db = new Database;
        return $db; 

    }
}

  • 修改:index.php
<?php
define('BASEDIR', __DIR__);
include BASEDIR . '/Library/Loader.php';

spl_autoload_register('\\Library\\loader::autoload');

// 工厂模式
// 需要一个工厂方法替换掉这个 new 对象的操作
// $db = new \Library\Database();

// 工厂模式和直接 new 一个对象相比的优势是:
// 如果需要 new 的那个类在很多个 PHP 文件里都有 new 的操作
// 如果这个对象发生了一些变更,比如类名或者参数发生了变化
// 那这时候如果不使用工厂模式,就需要每一个 PHP 文件都去修改代码
// 而使用了工厂模式之后,只需要在工厂方法中吧类的名称或者参数修改即可
// 其它很多高级的设计模式也都依赖于工厂模式
$db = Library\Factory::createDatabase();

2. 单例模式;

  • 使某个类的对象只允许被创建一次
    • 案例:假设我们有一个数据库的类要实现到连接数据库。
    • 如果我们不使用单例模式,就像之前的工厂模式那样,那就可以有很多个 PHP 文件创建数据库连接,这就是一种对资源的浪费。实际只要创建一个数据库链接即可。
  • 修改文件:Library/Database.php
<?php 
namespace Library;

class Database{
	
	protected static $db;
	
	// 构造方法声明为 private,屏蔽在其它地方直接创建数据库连接操作
	private function __construct(){
	}
	
	// 获取实例
	// 类本身的代码里可以调用上面的私有方法
	static function getInstance(){
		if(is_null(self::$db)){
			// 构造对象赋值给静态属性
			self::$db = new self();
		}
		return self::$db;
		
	}

    function where($where){
        return $this;
    }

    function order($order){
        return $this;
    }

    function limit($limit){
        return $this;
    }

}

  • 修改:index.php
<?php
define('BASEDIR', __DIR__);
include BASEDIR . '/Library/Loader.php';

spl_autoload_register('\\Library\\loader::autoload');

// 单例模式
$db = Library\Database::getInstance();

  • 修改:Library/Factory.php
<?php 
namespace Library;

// 工厂加单例
class Factory{

    static function createDatabase(){
        // $db = new Database;
        $db = Database::getInstance();	// 单例
        return $db; 

    }
}

3. 注册器模式;

  • 解决全局共享和交换对象
  • 工厂模式和单例模式的缺点是必须去调用工厂或者类。用注册器模式可以直接取到对象。
  • 注册器模式用来将一些对象注册到全局树上,就可以用来被任何地方直接访问
  • 实例:新建 Library/Register.php
<?php 
<?php 
namespace Library;

class Register{

    protected static $objects;

    // 将一个对象注册到全局注册树上
    function set($alias, $object){
        self::$objects[$alias] = $object;

    }

	static function get($name){
        return self::$objects[$name];
    }

    // 从注册树上移除
    function _unset(){
        unset(self::$objects[$alias]);
    }

}

  • 修改:Library/Factory.php
<?php 
namespace Library;

// 工厂加单例
class Factory{

    static function createDatabase(){
        // $db = new Database;
       	$db = Database::getInstance();	// 单例
        Register::set('db1',$db);       // 注册
        return $db; 

    }
}

  • 修改:index.php
<?php
define('BASEDIR', __DIR__);
include BASEDIR . '/Library/Loader.php';

spl_autoload_register('\\Library\\loader::autoload');


// 工厂方法只需要调用一次
// 其它任何地方再要调用数据库对象不需要调用工厂方法、也不需要调用单例模式获取实例
// 直接在注册器上获取对象
Library\Factory::createDatabase();	// 工厂模式里注册
$db = Library\Register::get("db1");

4. 适配器模式。

  • 适配器模式可以将截然不同的函数接口封装成统一的 API 接口
  • 实际应用举例,PHP 的数据库操作有 mysqli、pdo 等,可以应用适配器模式统一成一致。类似的场景还有 cache 适配器,将 memcached、redis、file、apc 等不同的缓存函数,统一成一致
  • 实例:修改文件 Library/IDatabase.php
<?php
// 声明接口
// 接口约定了统一的 API 方式
// 之后分别创建适配器实例,实现接口的方法
namespace Library;

interface IDatabase{
	
	// 连接数据库
	function connect($host, $user, $password, $dbname);
	
	// 查询
	function query($sql);
	
	// 关闭数据库
	function close();
	
}
  • 新增:Library/Database/MySQLi.php
<?php
namespace Library\Database;

class MySQli implements IDatabase{
	
	protected $conn;
	
	function connect($host, $user, $password, $dbname){
		$conn = mysqli_connect($host, $user, $password, $dbname);
		$this->conn = $conn;
	}
	
	function query($sql){
		return mysqli_query($this->conn, $sql);
	}
	
	function close(){
		mysqli_close($this->conn);
	}
}

  • 新增:Library/Database/PDO.php
<?php
namespace Library\Database;

class PDO implements IDatabase{
	
	protected $conn;
	
	function connect($host, $user, $password, $dbname){
		$conn =  new \PDO("mysql:host=$host;dbname=$dbname", $user, $password);
		$this->conn = $conn;
	}
	
	function query($sql){
		return $this->conn->query($sql);
	}
	
	function close(){
		unset($this->conn);
	}
}

  • 修改:index.php
<?php
// 调用数据库
$db = new \Library\Database\MySQLi();
// $db = new \Library\Database\PDO();
$db->connect('127.0.0.1', 'root', 'asdf', 'test');
$db->query("show databases");
$db->close();  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值