【问题标题】:Building Classes to Abstract Functionality of API为 API 的抽象功能构建类
【发布时间】:2019-04-15 17:46:47
【问题描述】:

我正在考虑构建一组类来处理与各种相似但相互竞争的 API 的交互。信用卡处理就是一个很好的例子。我想要一个应用程序开发人员使用的具有charge()refund() 等方法的类,与商家处理器是谁无关。然后我希望能够构建处理与特定商家处理器 API 交互的类。

所以我可能有一个与 Stripe API 交互,另一个用于 Authorize.Net 等。然后是某种从应用程序开发人员那里抽象 API 细节的主类或包装类。

过去,我使用包装器类来完成此操作,其中我使用相同的方法(以及它们各自的 API 交互)为每个 API 创建了一个类,然后在应用程序中使用了一个包装器类。使用示例可能如下所示:

$merchant = new Merchant( 'Stripe' );
$merchant->set_credentials( 'api_user', 'api_password' );
$merchant->set_cc( '4111-1111-1111-1111' );
$merchant->set_exp( '0121' );
$merchant->set_amount( 100.00 );
$merchant->charge();

用值“Stripe”实例化这个类意味着这个类在幕后将工作负载传递给适当的类来处理这种交互。

我的目标是:

  • 从应用程序开发人员那里抽象出 API,而不必知道 关于特定处理器的任何信息,除了名称(这样他们就可以 创建类的实例),或者如果 处理器发生变化。
  • 由于我最终需要支持更多商家处理器,因此可以加入 处理与其 API 交互的新类。

包装类是执行此操作的方法,还是 PHP 提供了其他更有效的机制来处理此类设置?

【问题讨论】:

  • 你考虑过继承/接口吗?
  • 您也可以简单地创建一个包含所有必需方法的接口。然后为每个实现创建类并让它们实现相同的接口。然后你只需要在你的应用程序中输入提示接口,你就可以注入你想要的任何实现。

标签: php class wrapper


【解决方案1】:

我将为您的内部 API 创建一个接口,每个外部处理器一个实现,以及一个用于创建正确实例的工厂类。

代码示例(PHP 7.1):

interface MerchantInterface {
    public function set_credentials(string $username, string $password);
    public function set_cc(string $number);
    public function set_exp(string $number);
    public function set_amount(float $amount);
    public function charge();
}

class StripeMerchant implements MerchantInterface {
    public function set_credentials(string $username, string $password) {}
    public function set_cc(string $number)  {}
    public function set_exp(string $number) {}
    public function set_amount(float $amount) {}
    public function charge() {}
}

class AuthorizeNetMerchant implements MerchantInterface {
    public function set_credentials(string $username, string $password) {}
    public function set_cc(string $number)  {}
    public function set_exp(string $number) {}
    public function set_amount(float $amount) {}
    public function charge() {}
}

class MerchantFactory {
    public const MERCHANT_STRIPE = 'Stripe';
    public const MERCHANT_AUTHORIZE_NET = 'Authorize.Net';

    public static function create(string $merchant): MerchantInterface {
        switch ($merchant) {
            case self::MERCHANT_STRIPE:
                return new StripeMerchant();
            case self::MERCHANT_AUTHORIZE_NET:
                return new AuthorizeNetMerchant();
            default:
                throw new Exception('Unexpected Merchant');
        }
    }
}

$stripeMerchant = MerchantFactory::create(MerchantFactory::MERCHANT_STRIPE);
$authorizeNetMerchant = MerchantFactory::create(MerchantFactory::MERCHANT_AUTHORIZE_NET);

根据您的要求,您还可以使用构建器模式而不是工厂来创建不同的实例。建造者会照顾你的二传手。如果您有许多可选参数(这里似乎不是这种情况)或者您想让您的 Merchants 不可变,这可能会很有用。

【讨论】:

    猜你喜欢
    • 2014-08-27
    • 1970-01-01
    • 2013-12-03
    • 1970-01-01
    • 1970-01-01
    • 2011-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多