2

我想知道在一个 PHP 框架中实现两个 similair API 的好方法是什么?

我的想法是这样的:

  • /vendors/wrapperA.php - 扩展父级,实现 API (A)
  • /vendors/wrapperB.php - 扩展父级,实现 API (B)
  • Parent.php -唯一直接引用以使用 API 包装器的脚本
  • $config[] 数组用于 Parent.php 中的配置
  • index.php - 一个实现且仅引用 Parent.php的网站

假设 API 有很多方法,但我们只实现了两个简单的 API 调用:

  • connect() - 创建到服务的连接。
  • put() - 如果成功返回一个“putID”。

由于 API (A)和 API (B)不同,这就是包装器通过抽象这两种方法来实现其实用程序的方式。

现在,我的观点是:

  • 在 PHP 中实现这一点的好方法是什么?
  • connect() 语句需要验证是否存在有效连接。
  • put() 语句需要返回一个 ID
  • 我们不想暴露 put 方法中的差异,它只需要根据我们是否正确配置 API 身份验证来工作(无论是什么情况 - 通过密钥或其他方式)

IE

就像是

<?php $parent = new Parent();
$parent->connect(); //connect to one or both API's.
$parent->put('foo'); //push foo to the API
?>

目前,我的所有代码都在 Parent.php 中。

在 Parent.php 中包含所有代码的问题

  1. 代码蔓延
  2. 如果我添加第三个 API,则缺少模块化插件。
  3. 代码混乱 - 哪个 API 是哪个?

编辑:根据 Marin 的回答设计的解决方案

<?php 

/*** Interface ***/

interface API_Wrapper {
    function connect();
    function put($file);
} 

/*** API Wrappers ***/
class API_A_Wrapper implements API_Wrapper {
    function connect() {}
    function put($file) { print 'putting to API A.'; }
}

class API_B_Wrapper implements API_Wrapper {
    function connect() {}
    function put($file) { print 'putting to API B.'; }
}

/*** Factory ***/
class Factory {
  public static function create($type){ 
    switch ($type) {
      case "API_A" : 
        $obj = new API_A_Wrapper(); 
      break;
      case "API_B" :
        $obj = new API_B_Wrapper();  
      break;
    }
    return $obj;
   } 

} 

/*** Usage ***/

$wrapperA = Factory::create("API_A");
$wrapperA->put('foo');

$wrapperB = Factory::create("API_B");
$wrapperB->put('foo');
4

2 回答 2

1

将接口与关系一起使用,并在需要时单独调用:

interface Interface {
    function somefunction();
}

class Wrapper1 implements Relation {
    public function connect() {
        return;
    }
}

class Wrapper2 {
    public function action(Interface $s) {
        $textData = $s->query();
        return;
    }
}

$p = new Wrapper1();

$i = new Wrapper2();
$i->action($p);

使用工厂作为关系:

function __autoload($class)
{
    include_once($class . '.php');
}

class DBfactory
{
    public static $pDB;

    public static function factory($szType = "")
    {
    if(!is_object(self::$pDB))
    {
        switch($szType)
        {
            case 'mysql':
                self::$pDB = new DBmysql;
                break;
            case 'mssql':
                self::$pDB = new DBmssql;
                break;
            default:
                self::$pDB = new DBmysql;
                break;
        }
    }
    return self::$pDB;
    }
}  
于 2013-03-04T23:49:20.840 回答
0

你需要的是依赖注入。您有 2 个类 - 您称它们为包装器 - 每个类都涵盖不同的 API,但必须符合相同的接口。在您的网站中,您希望交替使用任一类,实际上是使用任何底层 API 而不会影响代码库的其余部分,因此是通用Parent接口。

但是,在某些时候,您的代码将不得不决定使用哪个包装器,如果您想包含新的Parent实现,您担心必须手动将这些新包装器包含在您的代码库中。

这个问题通过依赖注入来解决。这个想法是有一个专用的对象 - 一个工厂 - 封装可用包装器的所有细节,并且任何需要此刻包装器的代码都可以向该工厂询问它。显然,您的代码只需要处理Parent接口的工厂和实例。

至于工厂如何决定实例化哪个包装器是您的选择。许多人使用包含哪个类必须与代码的哪个部分一起使用的配置文件。这可以通过使用与包装器客户端关联的 id(即使用它们的代码)来实现,并且客户端在请求包装器时会给工厂这个 id。然后,工厂只需查找 id 并提供一个 ad-hoc 实例。

于 2013-03-05T00:32:57.010 回答