基本上我有一个类发送SOAP请求,房间信息接收响应,它一次只能处理一个房间..例如:
class roomParser {
private $numRooms;
private $adults;
private $dailyPrice;
public function parse(){}
public function send(){}
};
$room = new roomParser( $arrival, $departue );
$return = $room->parse();
if ( $return ) { }
现在我有基本上支持多个房间的困境,每个房间我必须单独保存每日价格,成人数量的信息,所以我必须对每个房间信息进行会话化,因为它是一个多步骤的形式..
我应该只创建我的对象的多个实例,或以某种方式修改我的类,以便它支持房间数组中的任何#房间,并且在房间数组中它包含每个房间的属性?
编辑#1:在接受建议后,我尝试实现命令模式:
<?php
interface Parseable {
public function parse( $arr, $dept );
}
class Room implements Parseable {
protected $_adults;
protected $_kids;
protected $_startDate;
protected $_endDate;
protected $_hotelCode;
protected $_sessionNs;
protected $_minRate;
protected $_maxRate;
protected $_groupCode;
protected $_rateCode;
protected $_promoCode;
protected $_confCode;
protected $_currency = 'USD';
protected $_soapAction;
protected $_soapHeaders;
protected $_soapServer;
protected $_responseXml;
protected $_requestXml;
public function __construct( $startdate,$enddate,$rooms=1,$adults=2,$kids=0 ) {
$this->setNamespace(SESSION_NAME);
$this->verifyDates( $startdate, $enddate );
$this->_rooms= $rooms;
$this->_adults= $adults;
$this->_kids= $kids;
$this->setSoapAction();
$this->setRates();
}
public function parse( $arr, $dept ) {
$this->_price = $arr * $dept * rand();
return $this;
}
public function setNamespace( $namespace ) {
$this->_sessionNs = $namespace;
}
private function verifyDates( $startdate, $enddate ) {}
public function setSoapAction( $str= 'CheckAvailability' ) {
$this->_soapAction = $str;
}
public function setRates( $rates='' ) { }
private function getSoapHeader() {
return '<?xml version="1.0" encoding="utf-8"?>
<soap:Header>
</soap:Header>';
}
private function getSoapFooter() {
return '</soap:Envelope>';
}
private function getSource() {
return '<POS>
<Source><RequestorId ID="" ID_Context="" /></Source>
</POS>';
}
function requestXml() {
$this->_requestXml = $this->getSoapHeader();
$this->_requestXml .='<soap:Body></soap:Body>';
return $this->_requestXml;
}
private function setSoapHeaders ($contentLength) {
$this->_soapHeaders = array('POST /url HTTP/1.1',
'Host: '.SOAP_HOST,
'Content-Type: text/xml; charset=utf-8',
'Content-Length: '.$contentLength);
}
}
class RoomParser extends SplObjectStorage {
public function attach( Parseable $obj ) {
parent::attach( $obj );
}
public function parseRooms( $arr, $dept ) {
for ( $this->rewind(); $this->valid(); $this->next() ) {
$ret = $this->current()->parse( $arr, $dept );
echo $ret->getPrice(), PHP_EOL;
}
}
}
$arrive = '12/28/2010';
$depart = '01/02/2011';
$rooms = new RoomParser( $arrive, $depart);
$rooms->attach( new Room( '12/28/2010', '01/02/2011') );
$rooms->attach( new Room( '12/29/2010', '01/04/2011') );
echo $rooms->count(), ' Rooms', PHP_EOL;
答案 0 :(得分:3)
你所定义的是一个处理单个房间的对象,当然,如果你想处理多个房间,你应该创建一个只是这些单房间对象集合的对象。
如果您打算以与RoomParsers相同的方式与MultiRoomParser进行交互,则此方案可能是Composite Pattern的良好候选者。基本上,您的MultiRoomParser将包含RoomParsers的集合,当您在MultiRoomParser上调用诸如parse()之类的方法时,它只是遍历其集合中的所有RoomParsers并在每个元素上调用parse()。
答案 1 :(得分:1)
根据问题中的信息,我可能会使用Command Pattern
所有房间都应该实现一个parse()命令
interface Parseable
{
public function parse($arr, $dept);
}
房间实例可能看起来像这样
class Room implements Parseable
{
protected $_price;
protected $_adults;
public function parse($arr, $dept) {
// nonsense calculation, exchange with your parse logic
$this->_price = $arr * $dept * rand();
return $this;
}
public function getPrice()
{
return $this->_price;
}
}
要浏览它们,我会将它们添加到存储所有房间的Invoker中,并且知道如何调用它们的parse()方法,并且如果需要,还知道如何处理从parse()返回
class RoomParser extends SplObjectStorage
{
// makes sure we only have objects implementing parse() in store
public function attach(Parseable $obj)
{
parent::attach($obj);
}
// invoking all parse() methods in Rooms
public function parseRooms($arr, $dept)
{
for($this->rewind(); $this->valid(); $this->next()) {
$ret = $this->current()->parse($arr, $dept);
// do something with $ret
echo $ret->getPrice(), PHP_EOL;
}
}
// other methods
}
然后你可以像这样使用它:
$parser = new RoomParser;
$parser->attach(new Room);
$parser->attach(new Room);
$parser->attach(new Room);
$parser->attach(new Room);
echo $parser->count(), ' Rooms', PHP_EOL;
$parser->parseRooms(1,2);
请注意,Invoker扩展SplObjectStorage
,因此它实现了Countable,Iterator,Traversable,Serializable和ArrayAccess。
答案 2 :(得分:0)
我想说制作对象的多个实例是有道理的。这是对象的工作方式。