2017-11-17 58 views
6

Vui lòng kiểm tra sau lớp mà tôi đã tạo ra để xây dựng vài khung hình XML ..mở rộng hoặc thực hiện SimpleXML để tránh khô

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/>' 
     ); 
    } 
} 

cách tốt nhất để tránh trùng lặp của $frame->addChild('command')$command->addChild('authKey', 'authkey') mà không thay đổi trật tự của các yếu tố là gì?

Vui lòng giúp cải thiện mã. Cảm ơn

Trả lời

0

Mặc dù mã bạn có thể được đơn giản hóa, có các biến chứng. Cách tôi đã thực hiện nó di chuyển việc xây dựng khung thành phương pháp frame. Mỗi thói quen khác xây dựng cơ sở của nút <command> và chuyển nó lên, phương thức khung sau đó thêm bit khóa authkey. Mã này sẽ làm tương tự - NHƯNG nó sẽ phải được thực hiện trên tất cả các khung ...

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(); 
    } 
} 
0

Dường như phụ thuộc của bạn không quá lẫn lộn vì vậy đây là một ví dụ khá đơn giản, nơi bạn có thể di chuyển này thành một phương pháp riêng. Hãy nhớ rằng trong PHP, các đối tượng được truyền bằng tham chiếu. Điều đó có nghĩa là biến đối tượng thực sự chỉ là một con trỏ bộ nhớ đối tượng, và trái ngược với cách các biến vô hướng và mảng được truyền theo mặc định (theo giá trị ... không có con trỏ bộ nhớ).

Việc lấy đi là đối tượng luôn giống nhau bất kể nó được sử dụng ở đâu miễn là bạn không clone nó.

<?php 
class CommandBuilder 
{ 
    public function preBuild(\SimpleXMLElement $node) 
    { 
     $command = $node->addChild('command'); 
     $command->addChild('authKey', 'authkey'); 
    } 
} 

Bây giờ, thay vì gọi hai phương thức đó, bạn chỉ cần gọi $this->preBuild($frame).

2

Làm thế nào về một cái gì đó như thế này, nơi bạn tạo ra một lớp người xây dựng riêng biệt:

class CommandBuilder 
{ 
    private $commandName; 

    private $params = []; 

    public function __construct($commandName) { 
    $this->commandName = $commandName; 
    } 

    // convenience method, to allow for cleaner fluent interface usage 
    public static function create($commandName) { 
    return new self($commandName); 
    } 

    public function addParam($paramName, $paramValue) { 
    $this->params[] = [ 'name' => $paramName, 'value' => $paramValue ]; 

    return $this; 
    } 

    public function build() { 
    $app = new SimpleXMLElement('<app/>'); 
    $commandContainer = $app->addChild('command'); 
    $command = $commandContainer->addChild($this->commandName); 
    foreach($this->params as $param) { 
     $command->addChild($param[ 'name' ], $param[ 'value' ]); 
    } 
    $commandContainer->addChild('authKey', 'authKey'); 

    return $app->asXML(); 
    } 
} 

và sau đó có một lớp riêng biệt mà xây dựng các lệnh ứng dụng cụ thể:

class AppCommands 
{ 
    public function login($username, $password) { 
    return CommandBuilder::create('login')->addParam('username', $username) 
              ->addParam('password', $password) 
              ->build(); 
    } 

    public function info($id) { 
    return CommandBuilder::create('product')->addParam('id', $id) 
               ->build(); 
    } 
} 

Cách sử dụng vẫn như nhau, ngoại trừ bạn khởi tạo AppCommands, thay vì CommandBuilder:

$ac = new AppCommands; 

echo $ac->login('MyUsername', 'MyPassword'); 
echo PHP_EOL; 
echo $ac->info(5); 

View this example on eval.in

Nếu bạn muốn, bạn có thể dĩ nhiên cũng chủ động chuyển authKey đến CommandBuilder thay vì cứng mã hóa nó bên, với một cái gì đó như:

class CommandBuilder 
{ 
    private $commandName; 

    private $authKey; 

    private $params = []; 

    public function __construct($commandName, $authKey) { 
    $this->commandName = $commandName; 
    $this->authKey = $authKey; 
    } 

    public static function create($commandName, $authKey) { 
    return new self($commandName, $authKey); 
    } 

    /* ... */ 

    public function build() { 

    /* ... */ 

    $commandContainer->addChild('authKey', $this->authKey); 

    return $app->asXML(); 
    } 
0

Làm thế nào về cách viết một "bộ xương "phương thức chấp nhận làm tham số có thể gọi và thực thi nó ở giữa, như vậy. (Một bất lợi là bây giờ, các tham số, như $username$password, được lặp lại.)

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); 
     }); 
    } 

    // ... 
} 
Các vấn đề liên quan