清单开始于一个小型 IConfiguration 类,该类定义所有 Configuration 类或派生类所提供的接口。此接口将在类与其所有使用者之间定义契约。契约声明了实现 IConfiguration 的所有类必须配有 get() 方法并且 IConfiguration 的所有使用者都必须坚持仅使用 get() 方法。
下面的这段代码是在 PHP V5 中运行的,但最好使用提供的接口系统,如下所示。 清单 7. interface1.php5
<?php interface IConfiguration { function get( $key ); } class Configuration implements IConfiguration { ... } class DBConfiguration extends Configuration { ... } $c = new DBConfiguration(); echo( $c->get( 'imgpath' )."\n" ); ?> 一方面,读者可以更清楚地了解运行状况;另一方面,单个类可以实现多个接口。清单 8 显示了如何扩展 Configuration 类来实现 Iterator 接口,对于 PHP 来说,该接口是内部接口。
清单 8. interface2.php5
<?php interface IConfiguration { ... } class Configuration implements IConfiguration, Iterator { private $_items = array(); public function __construct() { $this->load(); } protected function load() { } protected function add( $key, $value ) { $this->_items[ $key ] = $value; } public function get( $key ) { return $this->_items[ $key ]; } public function rewind() { reset($this->_items); } public function current() { return current($this->_items); } public function key() { return key($this->_items); } public function next() { return next($this->_items); } public function valid() { return ( $this->current() !== false ); } } class DBConfiguration extends Configuration { ... } $c = new DBConfiguration(); foreach( $c as $k => $v ) { echo( $k." = ".$v."\n" ); } ?> Iterator 接口使所有类都可以看似是其使用者的阵列。正如您在脚本末尾看到的那样,您可以使用 foreach 运算符重申 Configuration 对象中的所有配置项。PHP V4 没有这种功能,但您可以在应用程序中通过各种方式使用此功能。
接口机制的优点是可以将契约快速集中在一起而无须实现任何方法。最后阶段是实现接口,您必须实现所有指定的方法。PHP V5 中另一个有帮助的新功能是 抽象类,使用抽象类可以轻松地用一个基类实现接口的核心部分,然后用该接口创建实体类。 抽象类的另一个用途是为多个派生类创建一个基类,在这些派生类中,基类决不会被实例化。例如,当 DBConfiguration 和 Configuration 同时存在时,则只能使用 DBConfiguration。Configuration 类只是一个基类 —— 一个抽象类。因此,您可以使用 abstract 关键字强制该行为,如下所示。 清单 9. abstract.php5
<?php abstract class Configuration { protected $_items = array(); public function __construct() { $this->load(); } abstract protected function load(); public function get( $key ) { return $this->_items[ $key ]; } } class DBConfiguration extends Configuration { protected function load() { $this->_items[ 'imgpath' ] = 'images'; } } $c = new DBConfiguration(); echo( $c->get( 'imgpath' )."\n" ); ?> 现在,所有要将 Configuration 类型的对象实例化的尝试都会出错,因为系统认为该类是抽象的并且不完整。
静态方法和成员 PHP V5 中的另一个重要的新功能是支持对类使用静态成员和方法。通过使用这种功能,您可以使用流行的单例模式。这种模式对于 Configuration 类是十分理想的,因为应用程序应当仅有一个配置对象。 |