三个基本设计模式
2016-06-23 17:46
302 查看
本文参考慕课网《大话PHP设计模式》-第五章内容编写,视频路径为:http://www.imooc.com/video/4876
推荐阅读我之前的文章: php的设计模式
三种基本设计模式,包括:
工厂模式,工厂方法或者类生成对象,而不是在代码中直接new
单例模式,使每个类的对象仅允许创建一个
注册模式,全局共享和交换对象
一、工厂模式
如果我们不使用工厂模式的话,当我们需要创建一个对象的时候,需要new一个对象。
当使用工厂模式的时候,我们使用工厂替换new
而是 $db = Libs\Factory::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;
}
}
调用方法:
打印结果:
注意代码中,构造函数为private属性,构造实例方法getInstance为static属性,$db属性为private/protected.
所以,不管调用多少次,都只会创建一次实例。
三、注册模式
单例模式解决的是如何在整个项目中创建唯一对象实例的问题,工厂模式解决的是如何不通过new简历实例对象的方法。那么注册树模式想解决的问题是什么呢?首先我们看一下上面两种模式的局限:
首先,单例模式创建唯一对象的过程,本身还有一种判断,需要判断对象是否存在。每次创建实例对象都需要判断。
其次,工厂模式更多考虑的是扩展维护的问题。
总体来说,单例和工厂模式都可以产生更加合理的对象,但是怎么方便调用这些对象呢?能够统筹管理安排这些对象呢?因而,注册树模式应运而生,将每一个对象都放在注册树上,需要的时候取下来。
那么注册树模式如何实现?首先,我们需要一个作为注册树的类,所有对象“插入”到注册树上,这个注册树应该由一个静态变量来充当,而且这个注册树应该是一个二维数组,且包含 插入对象实例方法set()和撤销方法_unset()(加下划线是因为unset默认为php的关键字 所以不能作为方法名使用)
还需要一个读取对象的方法get()
下面上实例
推荐阅读:php模式设计之 注册树模式
推荐阅读我之前的文章: php的设计模式
三种基本设计模式,包括:
工厂模式,工厂方法或者类生成对象,而不是在代码中直接new
单例模式,使每个类的对象仅允许创建一个
注册模式,全局共享和交换对象
一、工厂模式
如果我们不使用工厂模式的话,当我们需要创建一个对象的时候,需要new一个对象。
当使用工厂模式的时候,我们使用工厂替换new
<?php namespace Libs; class Factory { public static function createDatabase() { $db = new Database(); return $db; } }调用时,不是使用 $db = new Libs\Database();
而是 $db = Libs\Factory::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;
}
}
调用方法:
<span style="font-size:18px;">$db = Libs\Database::getInstance(); $db = Libs\Database::getInstance(); $db = Libs\Database::getInstance(); $db = Libs\Database::getInstance();</span>
打印结果:
<span style="font-size:18px;">new 啦 我构造啦 直接return 直接return 直接return</span>
注意代码中,构造函数为private属性,构造实例方法getInstance为static属性,$db属性为private/protected.
所以,不管调用多少次,都只会创建一次实例。
三、注册模式
单例模式解决的是如何在整个项目中创建唯一对象实例的问题,工厂模式解决的是如何不通过new简历实例对象的方法。那么注册树模式想解决的问题是什么呢?首先我们看一下上面两种模式的局限:
首先,单例模式创建唯一对象的过程,本身还有一种判断,需要判断对象是否存在。每次创建实例对象都需要判断。
其次,工厂模式更多考虑的是扩展维护的问题。
总体来说,单例和工厂模式都可以产生更加合理的对象,但是怎么方便调用这些对象呢?能够统筹管理安排这些对象呢?因而,注册树模式应运而生,将每一个对象都放在注册树上,需要的时候取下来。
那么注册树模式如何实现?首先,我们需要一个作为注册树的类,所有对象“插入”到注册树上,这个注册树应该由一个静态变量来充当,而且这个注册树应该是一个二维数组,且包含 插入对象实例方法set()和撤销方法_unset()(加下划线是因为unset默认为php的关键字 所以不能作为方法名使用)
还需要一个读取对象的方法get()
下面上实例
<span style="font-size:18px;"><?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);</span>
推荐阅读:php模式设计之 注册树模式
相关文章推荐
- Python基础学习代码之函数和函数式编程
- cordova android (一)
- UILongPressGestureRecognizer长按手势
- 拦截导弹=最小路径覆盖+DP+水
- 类的 与自定义事件
- iOS 检查本地是否存在某个文件
- 《C++ Primer Plus》学习笔记——C++程序创建到运行的整个过程
- Python2与Python3的区别(五):range
- 地鼠的困境 最大匹配
- android -解压和压缩zip
- BIEE12c安装日志
- Material Design 学习(二)
- 深入浅出聊Unity3D项目优化:从Draw Calls到GC
- avcodec_decode_video2()
- Spring MVC程序中得到静态资源文件css,js,图片
- 字典数据存入数据库(转换为二进制)
- Mybatis 学习记录
- Javascript中的数值转换问题(基础知识必备)
- 扩展类:类型转换
- 闲写c++