动态参数

时间:2015-12-30 12:14:15

标签: php dependency-injection

所以我在这里做了一些搜索,但我找不到答案......

我有以下课程:

class SomeCrmService
{
    public function __construct($endpoint, $key)
    {
        $this->request = new Request($endpoint);
        $this->request->setOption(CURLOPT_USERPWD, $key);
        $this->request->setOption(CURLOPT_HTTPHEADER, array(
            "Content-type : application/json;", 'Accept : application/json'
        ));
        $this->request->setOption(CURLOPT_TIMEOUT, 120);
        $this->request->setOption(CURLOPT_SSL_VERIFYPEER, 0);
    }

我遇到的问题是我想注入Request以便我可以更改我正在使用的库,并且在测试时更容易模拟。我需要传递$endpoint var,这可能是(客户,联系人等)所以我认为这是唯一的选择,如上所述。有没有办法让这个代码稍好一些,并注入Request并使用mutator或其他东西来设置$endpoint var?

由于

2 个答案:

答案 0 :(得分:2)

我建议采用这样的方法,扩展第三方Request类并允许它接受$endpoint和getter:

<?php

class EndpointRequest extends Request
{
    protected $endpoint;

    public function __construct($endpoint, $key)
    {
        $this->setOption(CURLOPT_USERPWD, $key);
        $this->setOption(CURLOPT_HTTPHEADER, array(
            "Content-type : application/json;", 'Accept : application/json'
        ));
        $this->setOption(CURLOPT_TIMEOUT, 120);
        $this->setOption(CURLOPT_SSL_VERIFYPEER, 0);
    }

    public function getEndpoint()
    {
        return $this->endpoint;
    }
}

class SomeCrmService
{
    public function __construct(EndpointRequest $request)
    {
        $this->request = $request;
    }
}

答案 1 :(得分:1)

使用 Factory 设计模式:

<?php

class RequestFactory {

    public function create($endpoint) {
        return new Request($endpoint);
    }

}

class SomeCrmService
{
    public function __construct($endpoint, $key, RequestFactory $requestFactory)
    {
        // original solution
        // $this->request = new Request($endpoint);
        // better solution
        $this->request = $requestFactory->create($endpoint);

        // here comes the rest of your code
    }

}

通过使用工厂设计模式,您不必扩展其他类 - 因为实际上您不想扩展它们。您没有添加新功能,您希望拥有可测试的环境。)