|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
HTML中的任何元素都要亲自实践,只有明白了什么元素会起到什么效果之后,你才会记忆深刻,而一味的啃书,绝对是不行的,我想大部分新手之所以觉得概念难学,大部分是一个字“懒”,懒是阻止进步的最大敌人,所以克服掉懒的习惯,才能更快的学好一样东西。 PHP V5.3 经由过程其延后静态绑定(LSB)特征处理了面向对象编程(OOP)的一些成绩。懂得 LSB 若何修复 PHP 的 OOP 编程成绩和若何完成需求利用 LSB 的一些尽人皆知的面向对象设计形式。
面向对象编程(OOP)可以让开辟人员经由过程利用数据笼统、封装、模块化、多态性和承继削减和简化代码 — 在对 OOP 有着深入的了解的条件下。对 OOP 特征的懂得还让 PHP 编码者得以使用设计形式 — 一些尽人皆知的用来处理罕见成绩的算法。PHP 自 V3.0 就已供应了 OOP 功效,但直到 V5.3 到来时,PHP 的 OOP 完成内的奇异的地方仍是会禁止一些罕见设计形式的利用。跟着 PHP V5.3 的延后静态绑定(LSB)特征的呈现,这些奇异的地方均已完全消逝。
本文向您引见了在 PHP V5.3 呈现之前,存在成绩的一些设计形式,注释了这些形式为什么不克不及任务。然后展现了 PHP V5.3 的 LSB 特征,并给出了单例和举动纪录设计形式。
从头回忆 OOP
假如您曩昔曾接触过 PHP OOP,那末极可能会出于以下缘由而决意不利用它:
读过诸多传播鼓吹 PHP OOP 有成绩的博文中的一条。
曾测验考试完成一个复杂的设计形式,但没有胜利。
而关于 PHP V5.3,有关 OOP 的博文都是正面的,而且 PHP OOP 的成绩在很大水平上已失掉处理。是时分重回 PHP OOP 了。经由过程本文,您将看到在 V5.3 呈现之前曾存在成绩的一些设计形式:单例、生成器、工场办法和举动纪录。
单例、生成器和工场办法设计形式被视为是 创立型 的形式,因它们可协助对象的构建。单例形式多是最经常使用的 OOP 设计形式之一了 ;它限制了一个类的对象实例数只能为 1。好比数据库毗连池就是单例设计形式的一个例子:咱们普通不想让使用法式具有毗连池类的多个资本密集型实例。
在需求分别庞杂对象的构建和暗示时,就需求用到生成器设计形式,您可使用不异的机关进程来创立多个对象。生成器形式的完成可以很庞杂,但一旦生成器可用,它就能够简化生成器所创立对象的机关和利用。具有输入 HTML、XML 或 PDF 才能的改变器就是需求利用生成器的一个例子。
而工场办法形式,望文生义,界说的是一个用来大批产出对象的办法的完成。您可以在使用法式需求创立其类型依附于子类的完成的对象时,利用工场办法形式。
举动纪录形式则可用来在域类内包装关系数据库耐久性办法。一个举动纪录的每一个实例都关系到数据库内的特定行。这个类包括了要拔出、删除和更新数据库内的一行或多个行的办法。举动纪录设计形式是由 Martin Fowler 在 Patterns of Enterprise Application Architecture 内界说的,并因在 Ruby on Rails 内的利用而日趋盛行。
前-LSB 的创立型设计形式完成成绩
上述提到的一切这四个设计形式均利用了静态的属性和办法。例如,看一下清单 1 内所示的这个毗连池单例。
清单 1. 一个复杂的单例
<?php
class ConnPool {
private static $onlyOne;
private static $count = 0;
private function __construct() {
// real-world db conn stuff here...
}
public static function getInstance() {
if (!is_object(self::$onlyOne)) {
$klass = __CLASS__;
self::$onlyOne = new $klass();
self::$count++;
}
return self::$onlyOne;
}
public static function getInstanceCount() {return self::$count;}
}
$db = ConnPool::getInstance();
assert (1 == $db->getInstanceCount());
$db2 = ConnPool::getInstance();
assert (1 == $db2->getInstanceCount());
?>
请注重这个静态的 $onlyOne 变量。该变量被设计用来保留毗连池对象的一个实例。$onlyOne 之前的静态润色符将此变量关系到类自己。$onlyOne 变量是一个类属性,由于其感化域是这个类。而 $onlyOne 属性只要一个实例。当一个属性不具有静态润色符时,就称其是一个对象属性,由于该属性对类的每一个实例都是唯一的。
注重到 ConnPool 的机关函数办法(called __construct)是空的。在一个临盆完成中,可使用该办法来创立数据库毗连池的距离。
静态 getInstance 办法包括单例的模板代码。只要在静态的 $onlyOne 变量为空时,它才会创立一个 $onlyOne 实例。请注重它是若何利用 __CLASS__ 变量来取得类的类型并随即创立该类的一个实例的。
利用 getInstanceCount 办法只是为了证实只创立了毗连池的一个实例。清单 1 底部的四行代码则证实不管恳求 ConnPool 池类的一个实例几何次,它城市前往不异的对象。
所以, 到今朝为止,此单例一切正常 — 直到您决意想要以面向对象的承继树的模式对这个毗连池停止子类处置来撑持多个数据库。清单 2 显示了这个承继树(为了明晰起见,删除实例计数器和机关函数代码)。
清单 2. 在没有 LSB 时对单例停止的一次掉败测验考试
<p><?php
class ConnPool {
private static $onlyOne;
protected static $klass = __CLASS__;
public static function getInstance() {
if (!is_object(self::$onlyOne)) {
self::$onlyOne = new self::$klass();
}
return self::$onlyOne;
}
}
class ConnPoolAS400 extends ConnPool {
protected static $klass = __CLASS__;
}
$db = ConnPoolAS400::getInstance();
assert ('ConnPoolAS400' == get_class($db)); // fails
?>
为了撑持多个类型的单例类,ConnPool 类添加了一个 $klass 静态变量并假定它会在子类中被掩盖。 ConnPoolAS400 子类扩大了 ConnPool 类并供应了 $klass 属性本人的版本。 咱们的预期是当 ConnPoolAS400 类的实例创立时,$klass 属性会保留 ConnPoolAS400。然而当履行这些代码时,它不会按预期的那样运转。当 PHP 适用函数 get_class 前往 ConnPool 而不是 ConnPoolAS400 时,代码底部的声明会掉败。 成绩是 ConnPool 类的 getInstance 办法利用的是它本人的 $klass 属性版而非 ConnPoolAS400 的掩盖版。 <P style="TEXT-INDENT: 2em">
我先解释一下我的学习思路。 |
|