重构代码:私有变量

时间:2014-07-09 16:50:53

标签: php

我必须折射很多代码,而且我一直在反复讨论一些设计问题,我无法决定哪些更好:

class LintRequestDispatcher {

  private $_info;
  private $_build_log;
  private $_results;

  public function __construct($info, $build_log) {
    $this->_info = $info;
    $this->_build_log = $build_log;
  }

  public function processLog() {
    $file_contents = file_get_contents($this->_build_log);
    $lines = explode("\n", $file_contents);
    $errors = array();
    foreach ($lines as $line) {
      if (preg_match('/^.+=.+ in (.+) on line (\d+)$/', $line, $tokens)) {
        $errors[] = array('file' => $tokens[1] , 'line_number' => $tokens[2], 'message' => $tokens[0]);
      }
    }

    $arr = array('job_name' => $this->_info['job_name'], 'build_number' => $this->_info['build_number'], 'errors' => $errors);
    $this->_results = $arr;
  }

  public function post(Client $client) {
    $request = $client->createRequest(
        'POST',
        '/app.php/api/reports/lint',
        array('Content-Type' => 'application/json'),
        json_encode($this->_results)
    );

    $request->send();
  }
}
  1. 变量$info$build_log是否应该通过构造函数传入并存储为私有变量(并且可能有getter / setter方法来访问变量)或者它应该只是传入使用它的函数?在这种情况下,唯一使用此功能的函数是processLog()。我觉得通过构造函数传递变量并存储变量是不必要的。

  2. processLog()post()应合并为1个功能吗? processLog()将结果存储在$_results私有变量中,然后调用post()以使用它。但是单元测试可能很难?

  3. 这些问题应该担心吗?

2 个答案:

答案 0 :(得分:0)

  1. 如果我使用一个类作为容器来将函数组合在一起(而不是使用它作为一个完整的对象的定义)我更喜欢传入变量而不是将它们存储为成员。 / p>

  2. 您可以将它们组合成一个函数,如果您肯定processLog()的结果只会用作post()的输入。

  3. 您是否应该担心这取决于其他一些事情。你是团队的一员吗?这段代码会由其他人维护吗?您确定始终以正确的顺序调用代码(即使在多线程环境中)吗?您将实例化一个LintRequestDispatcher类型的对象并重用它吗?这不是最好的方法,但是如果你试图快速破解某些东西,那么我就不会担心它。如果这是一个更大的项目的一部分,我建议将解析器拆分为自己的类。

答案 1 :(得分:0)

我认为:

  1. 如果要使用构造函数,可以使用以下代码,因为变量仅用于特定函数。或者,如果您不想使用构造函数,只需将参数移至processLog(),无需$_info$_build_log。为表现我建议第二个。

    class LintRequestDispatcher {
    
        private $_info;
        private $_build_log;
        private $_results;
    
        public function __construct($info = null, $build_log = null) {
            $this->_info = $info;
            $this->_build_log = $build_log;
        }
    }
    
  2. 根据no的建议。 1,最好将两种功能结合起来。但是,如果您希望能够对两个函数进行单元测试,只需将post()函数放入processLog()

    public function processLog(Client $client, $info, $build_log) {
        $file_contents = file_get_contents($build_log);
        $lines = explode("\n", $file_contents);
        $errors = array();
        foreach ($lines as $line) {
            if (preg_match('/^.+=.+ in (.+) on line (\d+)$/', $line, $tokens)) {
                $errors[] = array('file' => $tokens[1] , 'line_number' => $tokens[2], 'message' => $tokens[0]);
            }
        }
    
        $arr = array('job_name' => $info['job_name'], 'build_number' => $info['build_number'], 'errors' => $errors);
        $this->post($client, $arr);
    }
    
    public function post(Client $client, $results) {
        $request = $client->createRequest(
            'POST',
            '/app.php/api/reports/lint',
            array('Content-Type' => 'application/json'),
            json_encode($results)
        );
    
       $request->send();
    }
    
  3. 我不认为这些是关键问题,但考虑在processLog()上添加一些验证。你真的不知道输入是什么,它可以是一个空字符串,也可能是错误的文件名/路径。