欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android多種支付方式的實(shí)現(xiàn)示例

 更新時間:2023年09月06日 09:29:57   作者:派大星不吃蟹  
App的支付流程,添加多種支付方式,不同的支付方式,對應(yīng)的操作不一樣,有的會跳轉(zhuǎn)到一個新的webview,有的會調(diào)用系統(tǒng)瀏覽器,有的會進(jìn)去一個新的表單頁面,等等,本文就給大家詳細(xì)介紹一下Android 多種支付方式的優(yōu)雅實(shí)現(xiàn),需要的朋友可以參考下

1.場景

App 的支付流程,添加多種支付方式,不同的支付方式,對應(yīng)的操作不一樣,有的會跳轉(zhuǎn)到一個新的webview,有的會調(diào)用系統(tǒng)瀏覽器,有的會進(jìn)去一個新的表單頁面,等等。

并且可以添加的支付方式也是不確定的,由后臺動態(tài)下發(fā)。

如下圖所示:

根據(jù)上圖 ui 理一下執(zhí)行流程:

  • 點(diǎn)擊不同的添加支付方式 item。
  • 進(jìn)入相對應(yīng)的添加支付方式流程(表單頁面、webview、彈框之類的)。
  • 在第三方回調(diào)里面根據(jù)不同的支付方式執(zhí)行不同的操作。
  • 調(diào)用后臺接口查詢添加是否成功。
  • 根據(jù)接口結(jié)果展示不同的成功或者失敗的ui.

2.以前的實(shí)現(xiàn)方式

用一個 Activity 承載,上述所有的流程都在 Activity 中。Activity 包含了列表展示、多種支付方式的實(shí)現(xiàn)和 ui。

偽代碼如下:

class AddPaymentListActivity : AppCompatActivity(R.layout.activity_add_card) {
    private val addPaymentViewModel : AddPaymentViewModel = ...
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        addPaymentViewModel.checkPaymentStatusLiveData.observer(this) { isSuccess ->
            // 從后臺結(jié)果判斷是否添加成功
            if (isSuccess) {
                addCardSuccess(paymentType)
            } else {
                addCardFailed(paymentType)
            }
        }
    }
    private fun clickItem(paymentType: PaymentType) {
        when (paymentType) {
            PaymentType.ADD_GOOGLE_PAY -> //執(zhí)行添加谷歌支付流程
            PaymentType.ADD_PAY_PEL-> //執(zhí)行添加PayPel支付流程
            PaymentType.ADD_ALI_PAY-> //執(zhí)行添加支付寶支付流程
            PaymentType.ADD_STRIPE-> //執(zhí)行添加Stripe支付流程
        }
    }
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when (resultCode) {
            PaymentType.ADD_GOOGLE_PAY -> {
                // 根據(jù)第三方回調(diào)的結(jié)果,拿到key
                // 根據(jù)key調(diào)用后臺的Api接口查詢是否添加成功
            }
            PaymentType.ADD_PAY_PEL -> // 同上
            // ...
        }
    }
    private fun addCardSuccess(paymentType: PaymentType){
        when (paymentType) {
            PaymentType.ADD_GOOGLE_PAY -> // 添加對應(yīng)的支付方式成功,展示成功的ui,然后執(zhí)行下一步操作
            PaymentType.ADD_PAY_PEL-> // 同上
            // ...
        }
    }
    private fun addCardFailed(paymentType: PaymentType){
        when (paymentType) {
            PaymentType.ADD_GOOGLE_PAY -> // 添加對應(yīng)的支付方式失敗,展示失敗的ui
            PaymentType.ADD_PAY_PEL-> // 同上
            // ...
        }
    }
    enum class PaymentType {
        ADD_GOOGLE_PAY, ADD_PAY_PEL, ADD_ALI_PAY, ADD_STRIPE
    }
}

雖然看起來根據(jù) paymentType 來判斷,邏輯條理也還過得去,但是實(shí)際上復(fù)雜度遠(yuǎn)遠(yuǎn)不止如此。

• 不同的支付方式跳轉(zhuǎn)的頁面相差很大。

• 結(jié)果的回調(diào)獲取也相差很大,并不是所有的都在onActivityResult中。

• 成功和失敗實(shí)際上也不能統(tǒng)一來處理,里面包含很多的if…else…判斷。

• 如果支付方式是后臺動態(tài)下發(fā)的,處理起來判斷邏輯就更多了。

此外,最大的問題:擴(kuò)展性問題。

當(dāng)新來一種支付方式,例如微信支付之類的,改動代碼就很大了,基本就是將整個Activity中的代碼都要改動??梢哉f上面這種方式的可擴(kuò)展性為零,就是簡單的將代碼都揉在一起。

3.優(yōu)化后的代碼

要想實(shí)現(xiàn)高內(nèi)聚低耦合,最簡單的就是套用常見的設(shè)計模式,回想一下,發(fā)現(xiàn)策略模式+簡單工廠模式非常這種適合這種場景。

先看下優(yōu)化后的代碼:

class AddPlatformActivity : BaseActivity() {
    private var addPayPlatform: IAddPayPlatform? = null
    private fun addPlatform(payPlatform: String) {
        // 將后臺返回的支付平臺字符串變成枚舉類
        val platform: PayPlatform = getPayPlatform(payPlatform) ?: return
        addPayPlatform = AddPayPlatformFactory.getCurrentPlatform(this, platform)
        addPayPlatform?.getLoadingLiveData()?.observe(this@AddPlatformActivity) { showLoading ->
                if (showLoading) startLoading() else stopLoading()
            }
        addPayPlatform?.addPayPlatform(AddCardParameter(platform))
    }
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        // 將onActivityResult的回調(diào)轉(zhuǎn)接到需要監(jiān)聽的策略類里面
        addPayPlatform?.thirdAuthenticationCallback(requestCode, resultCode, data)
    }
}

4.策略模式

意圖: 定義一系列的算法,把它們一個個封裝起來, 并且使它們可相互替換。

主要解決: 在有多種算法相似的情況下,使用if…else所帶來的復(fù)雜和難以維護(hù)。

何時使用: 一個系統(tǒng)有許多許多類,而區(qū)分它們的只是他們直接的行為。

如何解決: 將這些算法封裝成一個一個的類,任意地替換。

關(guān)鍵代碼: 實(shí)現(xiàn)同一個接口。

**優(yōu)點(diǎn): **

1、算法可以自由切換。

2、避免使用多重條件判斷。

3、擴(kuò)展性良好。

缺點(diǎn)

1、策略類會增多。

2、所有策略類都需要對外暴露。

**使用場景: **

1、如果在一個系統(tǒng)里面有許多類,它們之間的區(qū)別僅在于它們的行為,那么使用策略模式可以動態(tài)地讓一個對象在許多行為中選擇一種行為。

2、一個系統(tǒng)需要動態(tài)地在幾種算法中選擇一種。

3、如果一個對象有很多的行為,如果不用恰當(dāng)?shù)哪J剑@些行為就只好使用多重的條件選擇語句來實(shí)現(xiàn)。

5.需要實(shí)現(xiàn)的目標(biāo)

5.1 解耦宿主 Activity

現(xiàn)在宿主Activity中代碼太重了,包含多種支付方式實(shí)現(xiàn),還有列表ui的展示,網(wǎng)絡(luò)請求等。

現(xiàn)在目標(biāo)是將 Activity 中的代碼拆分開來,讓宿主 Activity 變得小而輕。

如果產(chǎn)品說新增一種支付方式,只需要改動很少的代碼,就可以輕而易舉的實(shí)現(xiàn)。

5.2 抽取成獨(dú)立的模塊

因為公司中有可能存在多個項目,支付模塊的分層應(yīng)該處于可復(fù)用的層級,以后很有可能將其封裝成一個獨(dú)立的 mouble,給不同的項目使用。

現(xiàn)在代碼全在 Activity 中,以后若是抽取 mouble 的話,相當(dāng)于整個需求重做。

5.3 組件黑盒

"組件黑盒"這個名詞是我自己的一個定義。大致意思:

將一個 View 或者一個類進(jìn)行高度封裝,盡可能少的暴露public方法給外部使用,自成一體。

業(yè)務(wù)方在使用時,可以直接黑盒使用某個業(yè)務(wù)組件,不必關(guān)心其中的邏輯。

業(yè)務(wù)方只需要一個簡單的操作,例如點(diǎn)擊按鈕調(diào)用方法,然后邏輯都在組件內(nèi)部實(shí)現(xiàn),組件內(nèi)處理外部事件的所有操作,例如:Loading、請求網(wǎng)絡(luò)、成功或者失敗。

業(yè)務(wù)方都不需要知道組件內(nèi)部的操作,做到宿主和組件的隔離。

當(dāng)然這種處理也是要分場景考慮的,其中一個重點(diǎn)就是這個組件是偏業(yè)務(wù)還是偏功能,也就是是否要將業(yè)務(wù)邏輯統(tǒng)一包進(jìn)組件,想清楚這個問題后,才能去開發(fā)一個業(yè)務(wù)組件。

因為添加支付方式是一個偏業(yè)務(wù)的功能,我的設(shè)計思路是:

外部 Activity 點(diǎn)擊添加對應(yīng)的支付方式,將支付方式的枚舉類型和支付方式有關(guān)的參數(shù)通過傳遞,然后不同的策略類組件執(zhí)行自己的添加邏輯,再通過一層回調(diào)將第三方支付的回調(diào)從 Activity 中轉(zhuǎn)接過來,每個策略類內(nèi)部處理自己的回調(diào)操作,具體的策略類自己維護(hù)成功或者失敗的ui。摘自https://xuyisheng.top/author/xuyisheng/

6.具體實(shí)現(xiàn)

6.1 定義頂層策略接口

interface IAddPayPlatform {
    fun addPayPlatform(param: AddCardParameter)
    fun thirdAuthenticationCallback(requestCode: Int?, resultCode: Int?, data: Intent?)
    fun addCardFailed(message: String?)
    fun addCardSuccess()
}

6.2 通用支付參數(shù)類

open class AddCardParameter(val platform: PayPlatform)
class AddStripeParameter(val card: Card, val setPrimaryCard: Boolean, platform: PayPlatform)
    : AddCardParameter(platform = PayPlatform.Stripe)

因為有很多種添加支付方式,不同的支付方式對應(yīng)的參數(shù)都不一樣。

所以先創(chuàng)建一個通用的卡片參數(shù)基類AddCardParameter, 不同的支付方式去實(shí)現(xiàn)不同的具體參數(shù)。這樣的話策略接口就可以只要寫一個添加卡片的方法addPayPlatform(param: AddCardParameter)。

6.3 Loading 的處理

因為我想實(shí)現(xiàn)的是黑盒組件的效果,所有添加卡片的loading也是封裝在每一個策略實(shí)現(xiàn)類里面的。

Loading的出現(xiàn)和消失這里有幾種常見的實(shí)現(xiàn)方式:

• 傳遞BaseActivity的引用,因為我的loading有關(guān)的方法是放在BaseActivity中,這種方式簡單但是會耦合BaseActivity。

• 使用消息事件總線,例如EventBus之類的,這種方式解耦強(qiáng),但是消息事件不好控制,還要添加多余的依賴庫。

• 使用LiveData,在策略的通用接口中添加一個方法返回Loading的LiveData, 讓宿主Activity自己去實(shí)現(xiàn)。

interface IAddPayPlatform {
    // ...
    fun getLoadingLiveData(): LiveData<Boolean>?
}

6.4 提取BaseAddPayStrategy

因為每一個添加卡的策略會存在很多相同的代碼,這里我抽取一個BaseAddPayStrategy來存放模板代碼。

需要實(shí)現(xiàn)黑盒組件的效果,宿主Activity中都不需要去關(guān)注添加支付方式是不是存在網(wǎng)絡(luò)請求這一個過程,所以網(wǎng)絡(luò)請求也分裝在每一個策略實(shí)現(xiàn)類里面。

abstract class BaseAddPayStrategy(val activity: AppCompatActivity, val platform: PayPlatform) : IAddPayPlatform {
  private val loadingLiveData = SingleLiveData<Boolean>()
  protected val startActivityIntentLiveData = SingleLiveData<Intent>()
  override fun getLoadingLiveData(): LiveData<Boolean> = loadingLiveData
  protected fun startLoading() = loadingLiveData.setValue(true)
  protected fun stopLoading() = loadingLiveData.setValue(false)
  private fun reloadWallet() {
      startLoading()
      // 添加卡片完成后,重新刷新錢包數(shù)據(jù)
  }
  override fun addCardSuccess() {
      reloadWallet()
  }
  override fun addCardFailed(message: String?) {
      stopLoading()
      if (isEWalletPlatform(platform)) showAddEWalletFailedView() else showAddPhysicalCardFailedView(message)
  }
   /**
    * 添加實(shí)體卡片失敗展示ui
    */
  private fun showAddPhysicalCardFailedView(message: String?) {
       showSaveErrorDialog(activity, message)
  }
   /**
    * 添加實(shí)體卡片成功展示ui
    */
  private fun showAddPhysicalCardSuccessView() {
      showCreditCardAdded(activity) {
          activity.setResult(Activity.RESULT_OK)
          activity.finish()
      }
  }
  private fun showAddEWalletSucceedView() {
      // 添加電子錢包成功后的執(zhí)行
      activity.setResult(Activity.RESULT_OK)
      activity.finish()
  }
  private fun showAddEWalletFailedView() {
      // 添加電子錢包失敗后的執(zhí)行
  }
  // ---默認(rèn)空實(shí)現(xiàn),有些支付方式不需要這些方法---
  override fun thirdAuthenticationCallback(requestCode: Int?, resultCode: Int?, data: Intent?) = Unit
  override fun getStartActivityIntent(): LiveData<Intent> = startActivityIntentLiveData
}

6.5 具體的策略類實(shí)現(xiàn)

通過傳遞過來的AppCompatActivity引用獲取添加卡片的ViewModel實(shí)例AddPaymentViewModel,然后通過AddPaymentViewModel去調(diào)用網(wǎng)絡(luò)請求查詢添加卡片是否成功。

class AddXXXPayStrategy(activity: AppCompatActivity) : BaseAddPayStrategy(activity, PayPlatform.XXX) {
  protected val addPaymentViewModel: AddPaymentViewModel by lazy {
      ViewModelProvider(activity).get(AddPaymentViewModel::class.java)
  }
  init {
      addPaymentViewModel.eWalletAuthorizeLiveData.observeState(activity) {
          onSuccess { addCardSuccess()}
          onError { addCardFailed(it.detailed) }
      }
  }
  override fun thirdAuthenticationCallback(requestCode: Int?, resultCode: Int?, result: Intent?) {
      val uri: Uri = result?.data ?: return
      if (uri.host == "www.xxx.com") {
          uri.getQueryParameter("transactionId")?.let {
              addPaymentViewModel.confirmEWalletAuthorize(platform.name, it)
          }
      }
  }
  override fun addPayPlatform(param: AddCardParameter) {
      startLoading()
      addPaymentViewModel.addXXXCard(param)
  }
}

7.簡單工廠進(jìn)行優(yōu)化

因為我不想在Activity中去引用每一個具體的策略類,只想引用抽象接口類IAddPayPlatform, 這里通過一個簡單工廠來優(yōu)化。

fun setCurrentPlatform(activity: AppCompatActivity, payPlatform: PayPlatform): IAddPayPlatform? {
    return when (payPlatform) {
        PayPlatform.STRIPE -> AddStripeStrategy(activity)
        PayPlatform.PAYPAL -> AddPayPalStrategy(activity)
        PayPlatform.LINEPAY -> AddLinePayStrategy(activity)
        PayPlatform.GOOGLEPAY -> AddGooglePayStrategy(activity)
        PayPlatform.RAPYD -> AddRapydStrategy(activity)
        else -> null
    }
}

8.再增加一種支付方式

如果再增加一種支付方式,宿主Activity中的代碼都可以不要改動,只需要新建一個新的策略類,實(shí)現(xiàn)頂層策略接口即可。

這樣,不管是刪除還是新增一種支付方式,維護(hù)起來就很容易了。

策略模式的好處就顯而易見了。

以上就是Android多種支付方式的實(shí)現(xiàn)示例的詳細(xì)內(nèi)容,更多關(guān)于Android支付方式的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論