创造型
一、单例模式
单例模式是指在整个应用中只能创建一个对象实例。一般是用于创建对象,确保某一个类只能有一个实例。
在计算机系统中,数据库操作、日志对象、缓存、显卡驱动程序等一般会被设计为单例模式。
示例:
/**
* 单例
*/
class Db
{
private static $_instance;
// 私有化构造方法,防止外部new实例
private function __construct(...)
{
// 这里主要用于连接数据库,细节此处省略
}
// 覆盖__clone()方法,禁止克隆
private function __clone()
{
}
// 返回对象实例
public static function getInstance()
{
// 判断是否存在对象实例
if(! (self::$_instance instanceof self) ) {
// 不存在则创建保存
self::$_instance = new self();
}
// 返回对象实例
return self::$_instance;
}
}
二、工厂模式
工厂模式是我们最常用的实例化对象模式,是用工厂方法代替new操作的一种模式。
使用工厂模式的好处是,如果你想要更改所实例化的类名等,则只需更改该工厂方法内容即可,不需逐一寻找代码中具体实例化的地方(new处)修改了。为系统结构提供灵活的动态扩展机制,减少了耦合。
根据抽象程度的不同,PHP工厂模式分为三种:
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
简单工厂模式:又称静态工厂方法模式
,之所以可以这么说,是因为简单工厂模式是通过一个静态方法
来创建对象的。
工厂方法模式:定义一个用于创建对象的接口,让子类决定哪个类实例化。 他可以解决简单工厂模式中的封闭开放原则问题。
抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口。
结构型
一、注册树
注册树模式是指将一个个对象实例注册到一颗全局对象树上,需要使用时从对象树上采摘。方便我们管理对象实例。
示例代码:
/*
* [Register description]
*@ 注册树模式
*/
class Register
{
protected static $objects;
public static function set($alias,$object)
{
self::$objects[$alias]=$object;
}
public static function get($alias)
{
if(isset(self::$objects[$alias]))
{
return self::$objects[$alias];
}else
{
throw new \Exception('对象未被注册');
}
}
public static function _unset($alias)
{
unset(self::$objects[$alias]);
}
}
我们可以通过单例、工厂、注册树结合使用,方便对实例的使用管理。
二、适配器模式
适配器模式(有时候也称包装样式或者包装)将一个类的接口适配成用户所期待的。一个适配允许通常因为接口不兼容而不能在一起工作的类工作在一起。将不同的接口适配成统一的API接口。
应用场景:
如程序数据库有关联mysql、mysqli、pdo、sqlite、postgresql等操作,而你需要根据情况换数据库操作时,可以使用适配器模式统一接口,这样代码中除了数据库配置之外,就不需要做而外的更改。
同理cache(缓存)的场景也是,无论使用memcache还是redis等,在更换的时候都会很方便,节约时间
三、装饰器模式
装饰模式(Decorator Pattern) :动态地给一个对象增加一些额外的职责(Responsibility),就增加对象功能来说,装饰模式比生成子类实现更为灵活。其别名也可以称为包装器(Wrapper)
行为型
一、策略模式
将一组特定的行为和算法封装成类,以适应某些特定的上下文环境,这就是策略模式
比如:假如一个电商系统,针对不同的男性和女性 要各自跳转不同的商品类目,并且所有的广告位展示不同的广告
二、观察者模式
观察者模式属于行为模式,是定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新。
当一个对象状态发生改变后,会影响到其他几个对象的改变,这时候可以用观察者模式。
php提供的两个接口,一个被观察者接口SplSubject,一个或多个观察者接口SPLObserver,和一个可以储存对象的类SplObjectStorage
观察者模式符合接口隔离原则,实现了对象之间的松散耦合。
三、迭代器模式
概念:提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。当需要访问一个聚合对象,而且不管这些对象是什么都需要遍历的时候,就应该考虑使用迭代器模式。
Iterator(迭代器):迭代器定义访问和遍历元素的接口,接口抽象方法:
Iterator::current — 返回当前元素
Iterator::key — 返回当前元素的键
Iterator::next — 向前移动到下一个元素
Iterator::rewind — 返回到迭代器的第一个元素
Iterator::valid — 检查当前位置是否有效
示例:使用迭代模式实现斐波那契数列
class Num implements \Iterator
{
// 初始化 指针 ,初始位置元素 ,前一个元素
protected $key = 0;
protected $current = 0;
protected $prev = 1;
public function current()
{
return $this->current;
}
public function key()
{
return $this->key;
}
// 重制指针
public function rewind()
{
$this->key = 0;
$this->current = 0;
$this->prev = 1;
}
public function valid()
{
return true;
}
// 获取下一个元素
public function next()
{
// 将当前值保存到 newprev
$newprev = $this->current;
// 将上一个值与当前值的和赋给当前值
$this->current = $this->current + $this->prev;
// 前一个当前值赋给上一个值
$this->prev = $newprev;
$this->key ++;
}
}
$n = new Num();
foreach($n as $k=>$v)
{
echo $v.PHP_EOL;
if($k > 8){
break;
}
}
#输出结果
0
1
1
2
3
5
8