单例模式
参数传递增加额外开销
class DataBase
{
protected static $db;
private function __construct(){}
private function __clone(){}
public static function getInstance()
{
if (!self::$db instanceof self){
self::$db = new self();
}
return self::$db;
}
}
$db = DataBase::getInstance();
echo '单例模式<br>';
var_dump($db);
echo '<br>';
链式操作
例如yii框架中: \yii2\db\ActiveRecord.php与yii2\db\Query.php 文件
self::find()->select('*')->andFilterWhere(['***'=>'***'])->asArray()->one();
# 精髓在于数据库类中方法最后 return $this;
工厂模式
防止多处new 对象,牵一发动全身。工厂类是其他调用的统一入口。
/* 工厂模式
* 防止多处new 对象,牵一发动全身。工厂类是其他调用的统一入口。
*/
class F
{
public function createDb()
{
$db = DataBase::getInstance(); # DataBase class的更改不会影响调用者,降低耦合度
return $db;
}
}
$F = new F();
$db = $F->createDb();
echo '工厂模式<br>';
var_dump($db);
echo '<br>';
注册器模式
// 注册器模式
class Register
{
protected static $objects;
public static function set($alias, $object)
{
self::$objects[$alias] = $object;
}
public static function get($name)
{
return self::$objects[$name];
}
public function _unset($alias)
{
unset(self::$objects[$alias]);
}
}
// 注册器模式创建数据库实例
class RDB
{
public function __construct()
{
$db = DataBase::getInstance(); # DataBase class的更改不会影响调用者,降低耦合度
Register::set('db1', $db); # 注册器模式 项目初始化时建立实例
return $db;
}
}
$R = new RDB(); # 想问运行时初始化一次
$db1 = Register::get('db1'); # 获取数据库实例方式 这样不用总是创建工厂类实例
echo '工厂模式<br>';
var_dump($db1);
echo '<br>';
适配器模式(可能是新增加的功能)
是在想使用一个已经存在的类,但是他的接口并不符合要求,因为在编码过程中要遵循对扩展开放,对修改关闭的原则,所以不能对原有的类进行修改,这时便需要使用适配器模式
将截然不同的函数接口封装成统一的API ,例如将MySQL,mysqli,pdo统一。
先定义个interface
// 适配器模式(可能是新增加的功能)
// 是在想使用一个已经存在的类,但是他的接口并不符合要求,因为在编码过程中要遵循对扩展开放,对修改关闭的原则,所以不能对原有的类进行修改,这时便需要使用适配器模式
// 将截然不同的函数接口封装成统一的API ,例如将MySQL,mysqli,pdo统一。
// 先定义个interface
interface ADatabase{
function connect($host, $user,$passwd, $dbname);
function query($sql);
function close();
}
class T_Mysql implements ADatabase
{
protected $conn;
public function connect($host, $user, $passwd, $dbname)
{
$conn = mysql_connect($host, $user, $passwd);
mysql_select_db($dbname, $conn);
$this->conn = $conn;
}
public function query($sql)
{
$res = mysql_query($sql, $this->conn);
return $res;
}
public function close()
{
mysql_close($this->conn);
}
}
class T_MySQLi implements ADatabase
{
protected $conn;
public function connect($host, $user, $passwd, $dbname)
{
$conn = mysqli_connect($host, $user, $passwd,$dbname);
$this->conn = $conn;
}
public function query($sql)
{
$res = mysqli_query($this->conn, $sql);
return $res;
}
public function close()
{
mysqli_close($this->conn);
}
}
class T_PDO implements ADatabase
{
protected $conn;
public function connect($host, $user, $passwd, $dbname)
{
$conn = new PDO("mysql:host=$host;dbname=$dbname", $user, $passwd);
$this->conn = $conn;
}
public function query($sql)
{
$res = $this->conn->query($sql);
return $res;
}
public function close()
{
unset($this->conn);
}
}
echo '适配器模式<br>';
策略模式(已有功能,多样化)
定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化; 使用的关键点是面对对象、面向接口编程。
/*
* 策略模式(已有功能,多样化)
* 定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化; 使用的关键点是面对对象、面向接口编程。
*/
class Strategy
{
public $obj;
public function __construct($obj)
{
$this->setObj($obj);
}
public function setObj($obj)
{
$this->obj = $obj;
}
public function query($sql)
{
$res = $this->obj->query($sql);
$this->obj->close();
return $res;
}
}
$mysql = new T_Mysql();
$mysql->connect('39.105.143.144', 'root', '621149wan', 'test');
# 传参实例可随意变换,例如新增,实现解耦
$db = new Strategy($mysql);
$res = $db->query("select * from t limit 1");
echo '策略模式<br>';
var_dump($res);
echo '<br>';
数据映射模式
数据库中的表对应一个类,字段名对应类中属性。
类中增删改属性,变更数据库数据。
观察者模式
// 观察者模式
// 当一个对象发生改变时,依赖他的对象全部会收到通知
abstract class EventGenerator
{
private $observers = array();
function addObserver(Observer $observer)
{
$this->observers[] = $observer;
}
function notify()
{
foreach ($this->observers as $observer)
{
$observer->update();
}
}
}
interface Observer
{
function update($event = null);
}
class Observer1 implements Observer
{
function update($event = null)
{
echo 'update1';
}
}
class Observer2 implements Observer
{
function update($event = null)
{
echo 'update2';
}
}
class Event extends EventGenerator
{
function trigger()
{
$this->notify();
}
}
$event = new Event;
$event->addObserver(new Observer1);
$event->addObserver(new Observer2);
echo '观察者模式<br>';
$event->trigger();
echo '<br>';
原型模式
// 原型模式
// 适用于创建大对象 ,省去每次类初始化的开销,原型模式只需进行内存拷贝
// Draw 画图类,假如它是个大对象,想画一个方形 还想画个矩形
class Draw
{
public $x;
public $y;
public $pic;
public function rect($x, $y){
$this->x = $x;
$this->y = $y;
$this->pic = '画了个长'.$x.'宽'.$y.'的图<br>';
}
public function deepCopy()
{
$serialize_obj = serialize($this);
$clone_obj = unserialize($serialize_obj);
return clone $clone_obj;
}
public function getBigger(){
$this->pic = '画了个长'.($this->x+3).'宽'.($this->y+3).'的图<br>';
}
}
echo '原型模式<br>';
$prototype = new Draw();
$canvas1 = $prototype->deepCopy();
$canvas2 = $prototype->deepCopy();
$canvas1->rect(1,5);
$canvas2->rect(2,5);
$canvas1->getBigger(); # 举例 这种情况下要用原型模式
$canvas2->getBigger();
echo $canvas1->pic;
echo $canvas2->pic;
迭代器模式
class All implements \Iterator
{
protected $ids;
protected $index;
public function __construct($data)
{
$this->ids = $data;
}
public function current() //获取当前的元素
{
return $this->ids[$this->index];
}
public function next() //获取下一个元素
{
$this->index++;
}
public function valid() //验证当下是否还有下一个元素
{
return $this->index < count($this->ids);
}
public function rewind() //重置迭代器指针
{
$this->index = 0;
}
public function key() //迭代器指针的位置
{
return $this->index;
}
}
$arr = ['1', '2', '4']; //客户端
$users = new All($arr);
foreach ($users as $user) {
var_dump($user);
}