使用计算得出的“包含”或“必需”是否有不好的代码味道?

时间:2019-08-06 09:03:09

标签: php configuration

是否使用计算的包含/要求难闻的代码气味,并且对性能有不良影响吗?而且我想让包含的文件执行代码也是一件不好的事,但是如果记录了该行为,这还可以吗?

背景信息/我提出问题的原因:

我需要调用API以获得有关某些服务的信息。我大约有50个服务,每个服务需要调用API 0-6次。所以我在寻找一种配置方式

  • API调用的参数(两次调用的参数类型不同,可以是字符串,也可以是数组)
  • 定义要调用的API

我想为每个包含调用的服务创建一个文件,并将信息作为单个数组返回,如下所示:

<?php

    // Params for Call 1
    $anArrayWithSomeParams = array('param1', 'param2', 'param3', 'param4');

    // Params for Call 2
    $aString = 'string1';
    $anotherString = 'string2'

    // Params for Call 3-6
    ...

    $someInformation            = $dmy->getSomeInformation($anArrayWithSomeParams);
    $notNeededHere              = NULL;
    $moreInformation            = $dmy->getMoreInformation($aString,$anotherString);
    ...

    $allData = array( '0'   => $someInformation,
                    '1'     => $notNeededHere
                    '2'     => $tablespace,
                    ....
    );
?>

然后我可以包含该文件,并使用变量alldata来访问数据并对其进行如下处理:

require_once('class.dummy.php');
$directories = array("dir1", "dir2", "dir3");
$dmy = new dummy();

foreach($directories as $path) {
    $allData = NULL;
    $executeDataCollection = $path.'myFile.php';
    require($executeDataCollection);
    print "<pre>";
    print_r($allData);
    print "</pre>";
}

虽然这可能有效,但它似乎不是一个很好的解决方案。我想知道是否有人可以给我一些更优雅/复杂的处理方式的提示。

谢谢!

1 个答案:

答案 0 :(得分:2)

使用require和类似的方法都是不好的做法。

您应该更多地以OOP方式考虑如何实现这一点。为了实现这样的目标,我建议使用接口和抽象类。在您的情况下,您需要根据需要调用具有不同参数的一些APIS,则应使用以下模式/原理:

接口看起来像:

interface ApiGateway {

   /**
    * This will execute call with optional parameters
    *
    **/
   public function call($parameters = null);
}

抽象类

abstract class ApiGatewayAbstract implements ApiGateway
{

   /** return Adapter for handle API call **/
   abstract protected function getAdapter();
   /** return list of arguments for call */
   abstract protected function getArguments();

   public function call($parameters = null)
   {
       $adapter = $this->getAdapter();
       $arguments = $this->getArguments();

       // this will be HTTPAdapter for executing API call you need with specific params and arguments
       return $adapter->execute($arguments, $parameters);
   }
}

现在您可以开始实施特定的ApiGateways:

class MyApiGateway extends ApiGatewayAbstract
{
    protected $arguments = [];
    protected $adapter;

    public function __construct(HttpClientInterface $httpClient, array $arguments = [])
    {
        $this->arguments = $arguments;
        $this->adapter = $httpClient;
    }

    protected function getArguments()
    {
       return $this->arguments;
    }

    protected function getAdapter()
    {
       return $this->adapter;
    }

}

最后一步将是您的ApiGateways的工厂:

class ApiGatewayFactory
{
    // dynamic way to get Specific api gateway by name, or you can implement for each api gateway specific method
    public function getApiGateway($name, HttpClientInterface $adapter, array $arguments) 
    {
         $className = 'Namespace\\'.$name;
         if (!class_exist($className) {
            throw new \Exception('Unsuported ApiGateway');
         }

         // here you can use reflection or simply do:

         return new $className($adapter, $arguments);
    }
}

通过这种方法,您将达到所需的简洁方式,并遵循S.O.L.I.D.的一些原则。因此,您可以添加更多具有特定用例的ApiGateways,或添加其他适配器(soap,http,socket)等。

希望这会有所帮助,这也只是示例,您可以了解这些模式以及如何实现它们。但是这个例子应该可以帮助您理解这种方法。