单例模式
/*
含义:
作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统全局地提供这个实例。它不会创建实例副本,而是会向单例类内部存储的实例返回一个引用。
单例模式的三个要点:
1)需要一个保存类的唯一实例的静态成员变量
2)构造函数和克隆函数必须声明为私有的,防止外部程序new类从而失去单例模式的意义
3)必须提供一个访问这个实例的公共的静态方法(通常为getInterface方法),从而返回唯一实例的一个引用
为什么要使用单例模式
针对单次页面级请求共享同一对象资源
应用场合
1)应用程序与数据库交互(单例模式可以避免大量的new操作,因为每一次new操作都会消耗内存资源和系统资源)
2)控制配置信息(系统中需要用一个类来全局控制某些配置信息)
*/
class Single{
static private $interface = null;
final private function __construct(){ }
final private function __clone(){ }
final static public function getInterface(){
if( self::$interface == null ){
self::$interface = new Single();
}
return self::$interface;
}
}
$t1 = Single::getInterface();
$t2 = Single::getInterface();
echo ($t1===$t2)?'相同':'不同';
/*
class Single2 extends Single{
public function __construct(){}
}
$t1 = new Single2();
$t2 = new Single2();
echo ($t1===$t2)?'相同':'不同';
*/
工厂模式
/*
精髓:
根据不同的参数生成不同的类实例
工厂模式要点:
通常工厂模式有一个关键的构造,即一般被命名为factory的静态方法。这个静态方法可以接受任意数量的参数,并且必须返回一个对象。
为什么要使用工厂模式
工厂类就是一个专门用来创建其它对象的类,工厂类在多态性编程中非常重要。它允许动态替换类,修改配置,会使应用程序更加灵活。
应用场合
1)当客户程序不需要知道要使用对象的创建过程。
2)客户程序使用的对象存在变动的可能,或者根本就不知道使用哪一个具体的对象。
*/
//运算基类
abstract class Operation {
abstract public function getValue($num1,$num2);
}
//加
class SumOperation extends Operation {
public function getValue($num1,$num2){
return $num1 + $num2;
}
}
//减
class SubOperation extends Operation {
public function getValue($num1,$num2){
return $num1/$num2;
}
}
//工厂类
class Factory {
static public function getOp( $op ){
$opClassName = $op . 'Operation';
return new $opClassName();
}
}
$num1 = 6;
$num2 = 3;
$Op = Factory::getOp('Sub');
echo $Op->getValue($num1,$num2);
观察者模式
/*
在观察者模式中,会改变的是主题的状态以及观察者的数目。用这个模式,你可以改变依赖于主题状态的对象,却不必改变主题。——找出程序中会变化的方面,然后将其和固定不变的方面相分离!
主题和观察者都使用接口:观察者利用主题的接口向主题注册,而主题利用观察者接口通知观察者。这样可以让两者之间运作正常,又同时具有松耦合的优点! ——针对接口编程,不针对实现编程!
观察者模式利用“组合”将许多观察者组合进主题中。对象(观察者——主题)之间的这种关系不是通过继承产生的,而是在运行时利用组合的方式产生的。 ——多用组合,少用继承!
*/
class User {
static $observe = [];
public function addObserve( $observeObj ){
self::$observe[] = $observeObj;
}
public function register(){
//触发当前事件对应的操作
//...
echo "用户登录了...<br />";
//通知观察者、执行观察的对应的操作
foreach ( self::$observe as $obs ) {
$obs->update();
echo "<br />";
}
}
}
//以下都是观察者
//----------------------------------------------------
abstract class UserObserve {
abstract public function update();
}
//日志
class UserLog extends UserObserve {
public function update(){
echo 'UserLog update';
}
}
//积分
class IntegralLog extends UserObserve {
public function update(){
echo 'IntegralLog update';
}
}
$U = new User();
$U->addObserve( new UserLog() );
$U->addObserve( new IntegralLog() );
$U->register();
适配器模式
适配器模式将一个类的换成客户端需要的另一个接口,使原本不兼容的接口能一起工作。一个现实中的例子,假如屋里墙上只有两项插口,而风扇有三个插头,这时需要再拿一个移动插线板,插线板接入墙壁插口的一段是两项插头,插线板另外一段能够提供三项插口给风扇,这时候插线板起到了一个适配器的作用。
在应用中,适配器模式分为类适配器和对象适配器。
类适配器
类适配器中适配器继承原有的Adaptee类,自己实现原类没有的操作。
对象配器
类适配器使用的是继承模式,而对象适配器使用的是组合模式,将adaptee作为adapter的一个引用。
由于组合在耦合性上小于继承,对象适配器显得更加灵活,当然它的缺点是增加代码量。 需要重写adapee中的方法的数量太大的话,可以考虑在adapter中使用__call方法委托adapee取得客户端调用的方法