请检查我创建的以下类,以构建少量XML框架。
class CommandBuilder
{
public function __construct()
{
//
}
public function login($username, $password)
{
$frame = $this->frame();
$command = $frame->addChild('command');
$login = $command->addChild('login');
$login->addChild('username', $username);
$login->addChild('password', $password);
$command->addChild('authKey', 'authkey');
return $frame->asXML();
}
public function info($id)
{
$frame = $this->frame();
$command = $frame->addChild('command');
$login = $command->addChild('product');
$login->addChild('id', $id);
$command->addChild('authKey', 'authkey');
return $frame->asXML();
}
protected function frame()
{
return new SimpleXMLElement(
'<app/>'
);
}
}
避免重复$frame->addChild('command')
和$command->addChild('authKey', 'authkey')
而不改变元素顺序的最佳方法是什么?
请帮助改进代码。感谢
答案 0 :(得分:0)
虽然你的代码可以简化,但也有并发症。我完成它的方式将框架的构建移动到frame
方法。每个其他例程构建<command>
节点的基础并将其传递,然后帧方法添加authkey位。这段代码也会这样做 - 但它必须在所有帧上完成......
class CommandBuilder
{
public function __construct()
{
//
}
public function login($username, $password)
{
$command = new SimpleXMLElement('<command />');
$login = $command->addChild('login');
$login->addChild('username', $username);
$login->addChild('password', $password);
return $this->frame($command);
}
public function info($id)
{
$command = new SimpleXMLElement('<command />');
$login = $command->addChild('product');
$login->addChild('id', $id);
return $this->frame($command);
}
protected function frame( $node ) {
$node->addChild('authKey', 'authkey');
$xml = new DOMDocument();
$xml->loadXML('<app/>');
// Convert SimpleXML to DOMDocument
$fromDom = dom_import_simplexml($node);
// Add in the $node passed in to the frame
$xml->documentElement->appendChild($xml->importNode($fromDom, true));
return $xml->saveXML();
}
}
答案 1 :(得分:0)
看起来你的依赖关系不是太混乱所以这是一个相当简单的例子,你可以将它移动到它自己的方法中。请记住,在PHP中,对象通过引用传递。这意味着对象变量实际上只是一个指向对象的内存指针,与默认情况下标量和数组变量的传递方式形成对比(通过值...也就是没有内存指针)。
需要注意的是,只要你没有clone,对象就会一直使用它。
<?php
class CommandBuilder
{
public function preBuild(\SimpleXMLElement $node)
{
$command = $node->addChild('command');
$command->addChild('authKey', 'authkey');
}
}
现在,您只需拨打$this->preBuild($frame)
。
答案 2 :(得分:0)
如何编写一个“骨架”方法,接受一个可调用的参数,并在中间执行它,就像这样。 (缺点是现在,重复参数,如$username
和$password
。)
class CommandBuilder
{
// ...
private function createCommand(callable $cmdEnricher)
{
$frame = $this->frame();
$command = $frame->addChild('command');
$cmdEnricher($command);
$command->addChild('authKey', 'authkey');
return $frame->asXML();
}
public function login($username, $password)
{
return $this->createCommand(function ($command) use ($username, $password) {
$login = $command->addChild('login');
$login->addChild('username', $username);
$login->addChild('password', $password);
});
}
public function info($id)
{
return $this->createCommand(function ($command) use ($id) {
$login = $command->addChild('product');
$login->addChild('id', $id);
});
}
// ...
}