zoukankan      html  css  js  c++  java
  • PHP设计模式-工厂模式、单例模式、注册模式

    本文参考慕课网《大话PHP设计模式》-第五章内容编写,视频路径为:http://www.imooc.com/video/4876

    推荐阅读我之前的文章: php的设计模式

    三种基本设计模式,包括:

    1. 工厂模式,工厂方法或者类生成对象,而不是在代码中直接new
    2. 单例模式,使每个类的对象仅允许创建一个
    3. 注册模式,全局共享和交换对象

    一、工厂模式

    如果我们不使用工厂模式的话,当我们需要创建一个对象的时候,需要new一个对象。

    当使用工厂模式的时候,我们使用工厂替换new

    <?php
    namespace Libs;
    
    class Factory
    {
        public static function createDatabase()
        {
            $db = new Database();
            return $db;
        } 
    }

    调用时,不是使用 $db = new  LibsDatabase();

    而是 $db =  LibsFactory::createDatabase();

    为什么工厂模式更优?

    因为如果我们在很多地方需要用到Database时,如果我们这个Database的名字或参数等发生变化,在我们大量的new创建实例情况下,则在修改的时候就要全部作调整,而使用工厂模式后,我们可以只在工厂中直接做修改。

    二、单例模式

    假如我们使用数据库,如果不使用单例模式,那么相当于我们每次调用数据库都进行了一次连接,这是对资源的浪费。所以我们在这种情况下使用单例模式,这样只连接了一次数据库,可以任何需要的地方进行数据的操作。

    下面我们看例子:

    <?php
    namespace Libs;
    
    
    class Database
    {  
        private static $db;
        private function __construct()
        {
            echo "我构造啦<br>";
            self::$db = mysqli_connect("host", "user", "pwd", "dbname", "port","socket");
        }
        public static function getInstance()
        {
            if(self::$db){
                echo "直接return<br/>";
                return self::$db;
            }else{
                echo "new 啦<br/>";
                self::$db = new self();
                return self::$db;
              }
        }
        public function where($where)
        {
            return $this;
        }
        public function order($order)
        {
            return $this;
        }
        public function limit($limit)
        {
            return $this;
        }
    }

    调用方法:

    $db = LibsDatabase::getInstance();
    $db = LibsDatabase::getInstance();
    $db = LibsDatabase::getInstance();
    $db = LibsDatabase::getInstance();

    打印结果:

    new 啦
    我构造啦
    直接return
    直接return
    直接return

    注意代码中,构造函数为private属性,构造实例方法getInstance为static属性,$db属性为private/protected.

    所以,不管调用多少次,都只会创建一次实例。

    三、注册模式

    单例模式解决的是如何在整个项目中创建唯一对象实例的问题,工厂模式解决的是如何不通过new简历实例对象的方法。那么注册树模式想解决的问题是什么呢?首先我们看一下上面两种模式的局限:

    首先,单例模式创建唯一对象的过程,本身还有一种判断,需要判断对象是否存在。每次创建实例对象都需要判断。

    其次,工厂模式更多考虑的是扩展维护的问题。

    总体来说,单例和工厂模式都可以产生更加合理的对象,但是怎么方便调用这些对象呢?能够统筹管理安排这些对象呢?因而,注册树模式应运而生,将每一个对象都放在注册树上,需要的时候取下来。

    那么注册树模式如何实现?首先,我们需要一个作为注册树的类,所有对象“插入”到注册树上,这个注册树应该由一个静态变量来充当,而且这个注册树应该是一个二维数组,且包含 插入对象实例方法set()和撤销方法_unset()(加下划线是因为unset默认为php的关键字 所以不能作为方法名使用)

    还需要一个读取对象的方法get()

    下面上实例

     
    
    <?php
    //创建单例
    class Single{
        public $hash;
        static protected $ins=null;
        final protected function __construct(){
            $this->hash=rand(1,9999);
        }
    
        static public function getInstance(){
            if (self::$ins instanceof self) {
                return self::$ins;
            }
            self::$ins=new self();
            return self::$ins;
        } 
    }
    
    //工厂模式
    class RandFactory{
        public static function factory(){
            return Single::getInstance();
        }
    }
    
    //注册树
    class Register{
        protected static $objects;
        public static function set($alias,$object){
            self::$objects[$alias]=$object;
        }
        public static function get($alias){
            return self::$objects[$alias];
        }
        public static function _unset($alias){
            unset(self::$objects[$alias]);
        }
    }
    
    Register::set('rand',RandFactory::factory());
    
    $object=Register::get('rand');
    
    print_r($object);


    推荐阅读:php模式设计之 注册树模式

  • 相关阅读:
    浅谈JS异步轮询和单线程机制
    nginx、php-fpm、swoole HTTP/TCP压测对比
    HTTP.Socket.TCP详解
    HTTP 的长连接和短连接
    docker 解决network has active endpoints
    centos7.5 ab压力测试安装和swoole压力测试
    win7下docker环境centos容器中安装mysql5.7
    centos7 lamp环境搭建
    在 Windows 上进行 Laravel Homestead 安装、配置及测试
    laravel windows安装(composer)
  • 原文地址:https://www.cnblogs.com/ddddemo/p/5623418.html
Copyright © 2011-2022 走看看