《PHP设计模式介绍》第十一章 代理模式(3)_PHP教程

编辑Tag赚U币
教程Tag:暂无Tag,欢迎添加,赚取U币!

推荐:《PHP设计模式介绍》第十章 规范模式
在一个应用软件的成型过程中,一些意想不到的商业逻辑到处出现。比如,基于价格的考虑,这个任务必须减少项目;而那个任务也因为销售税而必须选择合适的比率;而其它的任务也必须因为其他的特别

因为WeatherReport实际上并不是你程序中定义的类, SoapClient都象stdClass的实例化一样的返回所有的对象。这时你也可以获得返回对象的属性的值。

class ProxyTestCase extends UnitTestCase {
function TestGetWeatherReport() {
$moline_weather = $this->client->getWeatherReport(‘KMLI’);
$this->assertIsA($moline_weather, ‘stdClass’);
$weather_tests = array(
‘timestamp’ => ‘String’
,’station’ => ‘stdClass’
,’phenomena’ => ‘Array’
,’precipitation’ => ‘Array’
,’extremes’ => ‘Array’
,’pressure’ => ‘stdClass’
,’sky’ => ‘stdClass’
,’temperature’ => ‘stdClass’
,’visibility’ => ‘stdClass’
,’wind’ => ‘stdClass’
);
foreach($weather_tests as $key => $isa) {
$this->assertIsA($moline_weather->$key,
$isa,
“$key should be $isa, actually [%s]”);
}
}
}

上面的代码创建了属性和返回类型的映射。你可以迭代这些预期值的列表,并使用assertIsA()验证正确的类型。当然你以可以同样的验证其他的集合对象。

class ProxyTestCase extends UnitTestCase {
function TestGetWeatherReport() {
// continued 。。。
$temp = $moline_weather->temperature;
$temperature_tests = array(
‘ambient’ => ‘Float’
,’dewpoint’ => ‘Float’
,’relative_humidity’ => ‘Integer’
,’string’ => ‘String’
);
foreach($temperature_tests as $key => $isa) {
$this->assertIsA($temp->$key,
$isa,
“$key should be $isa, actually [%s]”);
}
}
}

上面的方法输出的实际效果如下:

stdClass Object
(
[timestamp] => 2005-02-27T13:52:00Z
[station] => stdClass Object
(
[icao] => KMLI
[wmo] => 72544
[iata] =>
[elevation] => 179
[latitude] => 41。451
[longitude] => -90。515
[name] => Moline, Quad-City Airport
[region] => IL
[country] => United States
[string] => KMLI - Moline, Quad-City Airport, IL, United States @ 41。451’N -90。515’W 179m
)
// 。。。
[temperature] => stdClass Object
(
[ambient] => 0。6
[dewpoint] => -2。8
[relative_humidity] => 78
[string] => 0。6c (78% RH)
)
// 。。。
)

延迟代理

现在你基本掌握了PHP5风格的SoapClient(如何做一个远程代理),但是你怎么才能写一个延迟实例化的代理给SoapClient呢?

class GlobalWeather {
private $client;
// ‘Station getStation(string $code)’, public function getStation($code) {
return $this->client->getStation($code);
}
}

getStation()可以代理$client变量指向的getStation()方法。不管如何,从这点上看, SoapClient实例并没有创建,也没有存储到$client变量,因为上面已说过,对WSDL文件进行远程处理应该延迟到真正需要的时候。

你可以在插入一段延迟加载的代码之前做一下client的调用,来延迟SoapClient的实例化

class GlobalWeather {
private $client;
private function lazyLoad() {
if (! $this->client instanceof SoapClient) {
$this->client = new SoapClient(
‘http://live。capescience。com/wsdl/GlobalWeather。wsdl’);
}
}
// ‘Station getStation(string $code)’, public function getStation($code) {
$this->lazyLoad();
return $this->client->getStation($code);
}
}

lazyLoad()中创建SoapClient对象是一定要的。这里存在一个问题:如果我是一个懒惰的编码者,让我非常不爽是:我不得不在所有的代理方法中加入$this->lazyLoad();。有更加简便的方法吗?当然有,重写一遍吧,使用PHP5新的特性来返回对象。改lazyLoad()的名字为client(),并在这个方法里面实例化$client,代理中的方法访问client()方法优于访问$client属性。把延迟实例化做的更加简单!

分享:《PHP设计模式介绍》第九章 观测模式
一些面向对象的编程方式,提供了一种构建对象间复杂网络互连的能力。当对象们连接在一起时,它们就可以相互提供服务和信息。 通常来说,当某个对象的状态发生改变时,你仍然需要对象之间能互

来源:模板无忧//所属分类:PHP教程/更新时间:2008-08-22
相关PHP教程