0 代理模式
代理模式,即通过 代理对象 访问 目标对象,可以在目标对象实现的基础上,增加额外的功能性操作
-
静态代理
即在代理类中重写需要调用的方法,实现思路直接,但需要维护很多代理类
-
动态代理
相关内容作为参数传入,如java的 newProxyInstance
1 php适合代理模式的__call()方法
- 当对象调用不存在 或者 受权限限制的方法时,__call()会被自动调用
- php重载(overload):作为一种弱类型语言,本身不能像java, c++一样直接实现重载;但可通过特殊方法实现,如 __call
class Magic {
function __call($name,$arguments) {
if($name=='foo') {
if(is_int($arguments[0])) $this->foo_for_int($arguments[0]);
if(is_string($arguments[0])) $this->foo_for_string($arguments[0]);
}
}
private function foo_for_int($x) {
print("oh an int!");
}
private function foo_for_string($x) {
print("oh a string!");
}
}
$x = new Magic();
$x->foo(3);
$x->foo("3");
2 对象实例化的两种方式
在使用该对象时直接new
- 程序运行时,内存大致分为:栈空间段、堆空间段、代码段、初始化静态段。每次实例化一次类,都会创建一个对象,会在 【栈空间段】开辟一个新的空间来保存该对象。
- 因此在不需要保持某一对象多个实例时,这种方式很不可取
class Test {
function a () {
$person1 = new Person();
$person1->getAge();
}
function b () {
$person2 = new Person();
$person1->getSex();
}
}
__construct构造方法
- 具有构造函数的类会在每次创建新对象时先调用此方法
- 避免了对 对象创建多个实例的问题
class Test {
private $person;
function __construct() {
$this->person = new Person();
}
function a () {
$person->getAge();
}
function b () {
$person->getSex();
}
}
3 为什么需要代理模式
构建一个完整的项目时,考虑到 【埋点 / 性能监控 / 缓存等】等操作,比如这样一个简单的记录
function a() {
echo microtime(true);
$person->getAge();
echo microtime(true);
}
类似操作变多时,会带来两个问题:1. 需要在各个调用处单独处理,代码冗余; 2. 修改时(如监控变动)需多处修改。因此考虑代理模式设计,思路如下: