微信号:phpdaily

介绍:PHP在线专注于PHP编程语言学习,PHP开发经验分享,工作问题解决以及PHP在线技能测评等多功能为一体的服务系统,希望给工作学习中的PHPER带来些帮助。

PHP设计模式

2018-07-08 20:45 杰克船长

微信公众号:PHP在线

单例模式理解:
  1. 使某个类的对象只被创建一次

  2. 单例模式的最大好处就是减少资源的浪费,保证整个环境中只存在一个实例化的对象,特别适合资源连接类的编写。

  3. 单例模式的意思就是只创建一个资源(对象,数据库链接等),说白了,本质就是防止外部实例化类+判断是否存在来返回或创建后返回对象。

// 单例模式(口诀:三私一公)
class Singleton{
 //私有化构造方法,禁止外部实例化对象
 private function __construct(){}
//私有化__clone,防止对象被克隆
 private function __clone(){}
//私有化内部实例化的对象
 private static $instance = null;
// 公有静态实例方法
 public static function getInstance(){
   if(self::$instance == null){
     //内部实例化对象
     self::$instance = new self();
   }
    return self::$instance;
  }
}
工厂模式理解:
  1. 工厂方法或者类生成对象,而不是在代码中直接new。

  2. 我们定义一个专门用来创建其它对象的类。 这样在需要调用某个类的时候,我们就不需要去使用new关键字实例化这个类,而是通过我们的工厂类调用某个方法得到类的实例。
    好处:当我们对象所对应的类的类名发生变化的时候,我们只需要改一下工厂类类里面的实例化方法即可。不需要外部改所有的地方。

class Factory{

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

}

$db=Factory::createDatabase();
注册器模式理解:
  1. 全局共享和交换对象

  2. 单纯使用工厂模式还是要不断的创建对象,结合注册树模式,就简化了创建对象的麻烦。

代码笔记1:

Register.php,用来将一些对象注册到全局的注册树上,可以在任何地方访问。set():将对象隐射到全局树上,_unset():从树上移除。get():去注册到树上的对象。在框架初始化的时候,会做注册器的初始化操作,然后可以在任何地方去访问注册器的方法。

namespace IMooc;
class Register{
 protected static $objects;

 static function set($alias,$object){
   self::$objects[$alias] = $object;
 }

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

function _unset($alias){
     unset(self::$objects[$alias]);

 }
}
在工厂模式写下
class Factory{
static function createDatabase(){
   $db =Database::getInstance();
   Register::set('db1', $db);
   return $db;
 }
}
在index.php
$db = IMooc\Factory::createDatabase();
$db1 = \IMooc\Register::get('db1');

var_dump($db);
var_dump($db1);
代码笔记2
class Register
{
   protected static $objects =null;

   //注册
   public static function bind($alias, $obj)
   
{
       self::$objects[$alias]=$obj;
   }

   //解绑
   public static function unbind($alias)
   
{
       unset(self::$objects[$alias]);
   }

   //获得
   public static function get($alias)
   
{
       return self::$objects[$alias];
   }
}


class A
{

}

Register::bind('a',new A());
var_dump(Register::get('a'));
适配器模式理解:
  1. 使用适配器策略是为了更好的兼容。类似于手机电源适配器,如果能用一个充电器对所有手机充电当然是最方便的。无论什么手机,都只需要拿一个充电器。否则,不同手机不同充电器,太麻烦。

  2. 新建一个接口 IDatabase 然后在这个接口里面申明统一的方法体,再让不同的类去实现这个接口,和重写其抽象方法。当我们在入口文件使用到不同的类的时候,就只是实例化的类名不同,其它调用方法体的地方都一致

应用场景

如程序数据库有关联mysql、mysqli、pdo、sqlite、postgresql等操作,而你需要根据情况换数据库操作时,可以使用适配器模式统一接口,这样代码中除了数据库配置之外,就不需要做而外的更改。

同理cache(缓存)的场景也是,无论使用memcache还是redis等,在更换的时候都会很方便,节约时间。

<?php
header('Content-Type:text/html;charset=utf-8');
/**
* 适配器模式演示代码
* Target适配目标: IDataBase接口
* Adaptee被适配者: mysql和mysql_i、postgresql的数据库操作函数
* Adapter适配器 :mysql类和mysql_i、postgresql类
*/


/**
* Interface IDatabase 适配目标,规定的接口将被适配对象实现
* 约定好统一的api行为
*/

interface IDatabase
{
// 定义数据库连接方法
public function connect($host, $username, $password, $database);
// 定义数据库查询方法
public function query($sql);
// 关闭数据库
public function close();
}

/**
* Class Mysql 适配器
*/

class Mysql implements IDatabase
{
protected $connect; // 连接资源

/**
* 实现连接方法
*
* @param $host host
* @param $username 用户名
* @param $password 密码
* @param $database 数据库名
*/

public function connect($host, $username, $password, $database)
{
$connect = mysql_connect($host, $username, $password);
mysql_select_db($database, $connect);
$this->connect = $connect;
//其他操作
}

/**
* 实现查询方法
*
* @param $sql 需要被查询的sql语句
* @return mi
*/

public function query($sql)
{
return mysql_query($sql);
}

// 实现关闭方法
public function close()
{
mysql_close();
}
}

/**
* Class Mysql 适配器
*/

class Mysql_i implements IDatabase
{
protected $connect; // 连接资源

/**
* 实现连接方法
*
* @param $host host
* @param $username 用户名
* @param $password 密码
* @param $database 数据库名
*/

public function connect($host, $username, $password, $database)
{
$connect = mysqli_connect($host, $username, $password, $database);
$this->connect = $connect;
//其他操作
}

/**
* 实现查询方法
*
* @param $sql 需要被查询的sql语句
*/

public function query($sql)
{
return mysqli_query($this->connect, $sql);
}

// 实现关闭
public function close()
{
mysqli_close($this->connect);
}
}

/**
* Class Postgresql 适配器
*/

class Postgresql implements IDatabase
{
protected $connect; // 连接资源

/**
* 实现连接方法
*
* @param $host
* @param $username
* @param $password
* @param $database
*/

public function connect($host, $username, $password, $database)
{
$this->connect = pg_connect("host=$host dbname=$database user=$username password=$password");
//其他操作
}

/**
* 实现查询方法
*
* @param $sql 需要被查询的sql语句
*/

public function query($sql)
{
// 其他操作
}

// 实现关闭方法
public function close()
{
}
}



/**
* 客户端使用演示
* 这里以mysql为例
* 只要模式设计好,不论有多少种数据库,实现和调用方式都是一样的
* 因为都是实现的同一个接口,所以都是可以随意切换的
*/


$host = 'localhost';
$username = 'root';
$password = 'root';
$database = 'mysql';

//$client = new Postgresql();
//$client = new Mysql();
$client = new Mysql_i();
$client->connect($host, $username, $password, $database);
$result = $client->query("select * from db");
while ($rows = mysqli_fetch_array($result)) {
var_dump($rows);
}
$client->close();



 
PHP在线 更多文章 PHP面试题 Redis数据结构详解,五种数据结构分分钟掌握 PHP开发一个属于自己MVC框架 互联网秒杀设计 这些GIT经验够你用一年了
猜您喜欢 快速摆脱“学生气”的秘招 为什么只会Vue的都是前端小白? 京东被五部门联合约谈勒令整改, 刚喊完“正道成功”的刘强东内心要崩溃 【虚拟化】QEMU 代码分析:BIOS 的加载过程 第六十八讲 细说vector(4)