开发者

Avoid Type casting on Factory Pattern

I am writing a payment service class in Dart that wraps more than 1 payment provider. The expectation is the caller can simply switch one to another without any hassle. Let's imagine I have classes like this:

enum PaymentProvider { providerA, providerB }

abstract class PaymentService {
   void processPayment(Order oder);
}

class PaymentServiceA implements PaymentService {
    final String appKey;
    final String merchantId;
    
    PaymentServiceA(this.appKey, this.merchantId);


    @override
    void processPayment(Order oder) {
      // concrete implementation to process payment
    }

    String getVoucher() {
       // return voucher code
    }
}

class PaymentServiceB implements PaymentService {
    final PaymentBOptions options;
    
    PaymentServiceB(this.options);


    @override
    void processPayment(Order oder) {
      // concrete implementation to process payment
    }

    List<PaymentBHistory> getPaymentHistory() {
      // return payment history
    }

}

class PaymentBOptions {
   final bool sendEmailReceipt;
   final Function()? successCallback;

   PaymentBOptions(this.sendEmailReceipt, this.successCallback);
}

So here PaymentServiceA and PaymentServiceB have same method (processPayment) so we can create base class PaymentService and let them implements this base class. However as you can see each of them also has different constructor parameter and specific methods.

How is the bes开发者_运维问答t approach to create PaymentService that wrap more than 1 provider like this?

I was trying to use factory pattern like this:

abstract class PaymentService {
   factory PaymentService(PaymentProvider provider) {
      switch(provider) {
        case PaymentProvider.providerA:
          String appKey = "xxxx";
          String merchantId = "123"
          return PaymentServiceA(appKey, merchantId);
        case PaymentProvider.providerB:
          PaymentBOptions options = PaymentBOptions(() {
              
          });
          return PaymentServiceB(options);        
      }
   }

 
   void processPayment(Order order);
}

But I don't think this is the good practice because:

  1. If we create PaymentServiceA or PaymentServiceB instance using PaymentService factory method it will return as PaymentService and we need to cast to appropriate class in order to access specific PaymentService method.
  2. We can't supply specific constructor parameter of PaymentServiceA or PaymentServiceB outside PaymentService abstract class via factory constructor.

Any idea on how is the best practice and what's the suitable design pattern when facing this kind of scenario?

Thanks.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜