PHP 设计模式
设计模式在很多语言都有用到,PHP 也不例外,下面是一些常见的 PHP 设计模式,做个记录。
工厂模式
平常我们获取实例,都是使用 new
来获取,如果在后期对类有修改,就需要改很多个地方,而工厂模式类可以把实例化对象封装成方法,后期修改只需修改工厂类就行。
// 工厂模式
class Factory
{
public static function getDb()
{
$db = new Db();
return $db;
}
}
// 使用
$db = Factory::getDb();
单例模式
对于需要频繁创建和销毁的对象,为了节约系统资源,只创建一个实例,可以提高一定的性能,例如 MySQL, Redis 等,单例模式的作用就是确保只有一个实例被创建,避免重复构造。
但是滥用单例模式会带来一些问题,如数据库单例可能会因为连接对象过多而溢出;如单例对象长时间不使用,有可能会被系统当垃圾回收,这会导致对象状态丢失。
// 单例模式
class Db
{
protected $conn;
private function __construct() {}
public static function getConnection()
{
if (self::$conn) {
return self::$conn;
} else {
self::$conn = new self();
return self::$conn;
}
}
}
// 此时工厂模式也需要更改
class Factory
{
public static function getDb()
{
$db = Db::getConnection();
return $db;
}
}
注册树模式
注册树模式有点类似全局变量,注册实例、获取实例、删除实例。
// 注册树模式
class Register
{
protected static $instances;
public static function set($alias, $instance)
{
self::$instances[$alias] = $instance;
}
public static function get($alias)
{
if (isset(self::$instances[$alias])) {
return self::$instances[$alias];
} else {
return null;
}
}
public static function remove($alias)
{
unset(self::$instances[$alias]);
}
}
// 更改工厂模式
class Factory
{
public static function getDb()
{
$db = Db::getConnection();
Register::set('db', $db);
}
}
// 获取实例
$db = Register::get('db');
适配器模式
适配器模式的作用是用于将不同实例的接口适配成一个同一的接口,方便调用,例如将 PDO 数据库封装、新的 API 接口与旧的 API 接口兼容等等。
// 目标角色
interface Target
{
public function func1();
public function func2();
}
// 源角色
class Adaptee
{
public function func1()
{
echo 'func1';
}
}
// 类适配器角色
class Adapter implements Target
{
private $adaptee;
function __construct(Adaptee $adaptee)
{
$this->adaptee = $adaptee;
}
// 调用源角色 func1 方法
public function func1()
{
$this->adaptee->func1();
}
// 目标角色新增方法
public function func2(){
echo 'func2';
}
}
// 使用
$adaptee = new Adaptee();
$adapter = new Adapter($adaptee);
$adapter->func1();
$adapter->func2();
观察者模式
观察者模式是指一个实例通过添加一个方法(即注册观察者),当该实例有更改时,会将消息发送到已注册的观察者实例上,由观察者做后续操作,这两个过程耦合程度很低。
// 观察者接口
interface Observer
{
public function watch();
}
// 比如一篇文章
interface Subject
{
public function register(Observer $observer);
public function notify();
}
// 主题
class Action implements Subject
{
private $_observers = [];
public function register(Observer $observer)
{
$this->_observers[] = $observer;
}
public function notify()
{
foreach ($this->_observers as $observer) {
$observer->watch();
}
}
}
// 观察者
class People implements Observer
{
public function watch()
{
echo 'People watching.';
}
}
// 应用实例
$action = new Action();
$action->register(new People());
$action->notify();