Php 构建类以抽象API的功能

Php 构建类以抽象API的功能,php,class,wrapper,Php,Class,Wrapper,我正在考虑构建一组类来处理与各种类似但相互竞争的API的交互。信用卡处理就是一个很好的例子。我想要一个类,它包含应用程序开发人员使用的诸如收费或退款之类的方法,而不依赖于谁是商家处理器。然后,我希望能够构建处理与特定商户处理器API交互的类 因此,我可能有一个与条带API交互,另一个用于Authorize.Net等。然后是某种主类或包装类,从应用程序开发人员抽象API细节 在过去,我使用一个包装类来完成这项工作,在这里,我使用相同的方法为每个API创建了一个类以及它们各自的API交互,然后在应用

我正在考虑构建一组类来处理与各种类似但相互竞争的API的交互。信用卡处理就是一个很好的例子。我想要一个类,它包含应用程序开发人员使用的诸如收费或退款之类的方法,而不依赖于谁是商家处理器。然后,我希望能够构建处理与特定商户处理器API交互的类

因此,我可能有一个与条带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();
用值条带实例化这个类意味着在幕后这个类将工作负载传递给适当的类来处理这个交互

我的目标是:

从应用程序开发人员那里提取API,使其不必知道 关于特定处理器的任何信息,除了名称,以便他们可以 创建类的实例,或者如果 处理器更改。 当我最终需要支持更多的商户处理器时,我可以顺便来看看 处理与API交互的新类。
包装类是实现这一点的方法,还是PHP提供了其他更有效的机制来处理这种类型的设置?

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

代码示例PHP7.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);

根据您的需求,您还可以使用生成器模式而不是工厂来创建不同的实例。建设者会照顾好你的二传手。如果您有许多可选参数,这可能会很有用。这里的情况似乎不是这样,或者您希望使您的商户不可变。

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