理解面向对象的编程 - 我可以改进什么?

时间:2014-01-16 00:25:35

标签: php oop

切入追逐:我的应用程序将使用一个API来使用cURL进行调用。但是这个API需要保密,所以我使用框架来创建自己的API来查询外部API。我已经这样做了,但它真的很乱,而且编码很糟糕 - 所以我想尽可能正确地做到这一点,为了我自己的学习。

我首先创建我的interface

interface APICall {

    /**
     * Return data from the API
     * @returns json
     */
     public function callData($method, $parameters);

}

然后我创建了我的类,它将执行cURL(现在只执行GET请求):

class curl {

    private static $apiUrl = 'http://api.somewebsite.com/v1/';

    public function __construct() {

        if (!function_exists('curl_init')) 
            exit('CURL is not installed!');

    }

    public function getCurl($method, $parameters) {

        $url = self::$apiUrl . $method . '?' . $parameters;

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $output = curl_exec($ch);
        curl_close($ch);

        return $output;

    }

    // Another function for a POST request could go here

}

好的,现在我为每个特定的电话创建我的课程,例如“获取用户列表”:

class users extends curl implements APICall {

    /**
     * Get list of users
     */

    public function callData($method, $parameters) {

        $this->getCurl($method, $parameters);

    }

}

好的 - 现在我不完全确定这会起作用(现在是头脑风暴),但我觉得我会遇到一些问题:

  1. 我的curl课程中的__construct,我不认为这应该包含“检查cURL是否已安装”检查 - 但这最好去哪里?

  2. 我正在curl类中的每个方法中构建$url - 这看起来很糟糕,因为我最终会重复这个 - 但是我在哪里创建要使用的?

  3. 我觉得我好像在使用$method& $parameters非常频繁,这是正常的吗?

  4. 很抱歉,如果这是相当多的,只是试图理解它,因为我当前的编码实践是垃圾!

2 个答案:

答案 0 :(得分:1)

  1. 在代码安装程序中(例如,emerge,webapp-config,rpm等),框架中的专用/安装路径,或者在需要时位于文件顶部。仅在最坏情况下的构造函数中。

  2. 创建一个实现您的界面并从中扩展的抽象类。或者使用PHP 5.4特征。

  3. 也许。我宁愿看到与API中的每个方法相对应的方法调用。但这是首选之一。

答案 1 :(得分:1)

class curl {
    private $method;
    private $parameters;
    private $url;

    public function __construct($url,$method,$parameters = array()) {
        if (!function_exists('curl_init')){ 
            throw new Exception('CURL is not installed!');
        }
        $this -> setUrl($url);
        $this -> setMethod($method);
        $this -> setParameters($parameters);        
    }

    public function setMethod($method){
        $this -> method = $method;
        return $this;
    }

    public function getMethod(){
        return $this -> method;
    }

    public function setParameters(array $parameters){
        $this -> parameters = $parameters;
        return $this;
    }

    public function getParameters(){
        return $this -> parameters;
    }

    public function setUrl($url){
        $this -> url = $url;
        return $this;
    }

    public function getUrl(){
        return $this -> url;
    }

    public function execute() {    
        // add method support, so you don't need an extra POST method   
        $url = $this -> createUrl();
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $this -> getUrl());
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $output = curl_exec($ch);
        curl_close($ch);

        return $output;
    }

    private function createUrl(){
        return $this -> url . $this -> getMethod() . '?' . http_build_query($this -> getParameters());
    }
}

你不需要使用构造函数,但我认为没有url和方法的curl是没有意义的。因此,您可以通过将其放入构造函数中来创建对url和方法的依赖项。添加Setter和Getter支持以从外部更改对象的状态。您不需要创建不同的执行函数,一个就足够了。网址创建的问题也解决了。从外面设置网址。所以你也可以在其他环境中使用curl。

尝试注入curl类,不要扩展它。例如:

class specificApi implements ApiInterface {
    private $curl;

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

    public function execute(){
        return $this -> curl -> setUrl('someUrl') -> setMethod('someMethod') -> execute();
    }
}

在下一步中,您将认识到curl总是需要一些构造函数参数,因此您需要创建一个创建curl类的工厂。您将注入工厂并在api类中创建curl类的实例。