主頁 > 移動端開發 > iOS 微信、支付寶、銀聯支付組件的進一步設計

iOS 微信、支付寶、銀聯支付組件的進一步設計

2023-06-24 08:14:13 移動端開發

原文地址:https://zhanglei.blog.csdn.net/article/details/121376500

前言

有段時間沒寫技術文章了,一是因為作業太忙,再者因為本人文筆實在一般,最近終于閑下來,本著分享的目的將一些組件設計上的心得與大家分享,
本篇文章是基于原有一篇關于支付文章的進一步優化設計,所以在閱讀本篇文章前還是建議先移步到那篇文章,
文章地址: 微信、支付寶、銀聯、Paypal 支付組件封裝

描述

在封裝支付介面時,需要面臨各支付平臺不同SDK集成的問題,有的支付第三方平臺只通過sdk組件就可完成支付,像支付寶,但大部分的支付第三方平臺需要先去呼叫服務端API介面獲取支付需要的資訊,拿到這些支付資訊后,再去呼叫sdk組件完成支付,這類第三方有銀聯(需要獲取tn交易流水號),微信(需要獲取prepayData)等,

為了以后的支付功能復用,想要設計一個支付組件,該組件整合并統一了這些第三方支付sdk的介面,以便給客戶端快速集成,在設計支付組件的程序中就遇到上面提到的問題, 如何解決某些第三方需要請求一些資料后,再進行支付的問題 ? 試想一下如果將這些請求hardcode到組件中,顯然能滿足當前的功能,局限性也非常明顯,只能適用當前的支付業務, 此時的支付組件會和網路組件藕合,不利于擴展及復用,

設計

如何解藕? 如何能讓這些需要請求API的第三方不污染組件? 解藕的思想就是“抽離變化,并封裝”, 我們需要把不穩定的部分抽離出來,使其獨自變化,不影響穩定的部分, 找到了方向, 如何抽離? 這里我們可以使用面向協議的編程的思想,將請求API的行為進行抽象,
偽代碼:

//抽像一個協議, 協議定義一個獲取支付資訊的方法,呼叫介面是異步操作,所以回傳的資料使用block回傳

@protocol PayDataPrepareProtocol <NSObject>

@required
- (void)getPayData:(void(^)(id result, NSError *error))block;

@end

微信支付偽代碼:

@interface WXPayPrepareData : NSObject <PayDataPrepareProtocol>
@property (nonatomic,strong) NSDictionary *requestParams;

@end

@implementation WXPayPrepareData

- (void)getPayData:(void(^)(id result, NSError *error))block {
    //根據請求引數,使用網路層組件呼叫API,并回傳預支付資訊
    block(result,nil);
}

@end

銀聯支付偽代碼:

@interface UnionPayPrepareData : NSObject <PayDataPrepareProtocol>
@property (nonatomic,strong) NSDictionary *requestParams;
@end

@implementation UnionPayPrepareData

- (void)getPayData:(void(^)(id result, NSError *error))block {
    //根據請求引數,使用網路層組件呼叫API,并回傳預支付資訊
    block(result,nil);
}
@end

如何能將支付型別與預支付實作類之間建立聯系呢?我們需要設計一個配置類來管理這種支付型別與預支付實作類的對應關系 ,

支付配置的偽代碼:

typedef NS_Enum(NSInteger, PayType) {
    PayTypeForAlipay,    //支付寶支付
    PayTypeForWXPay,    //微信支付
    PayTypeForUPPay,    //銀聯支付
} 


@interface PayConfig: NSObject

//單例物件
+ (instancetype)config;

//添加獲取預支付資訊對應的策略類, 沒有傳遞實體物件,避免未使用而造成的記憶體浪費
- (void)appendPrepayDataStrategy:(Class)strategyClass withPayType:(PayType)payType;

//判斷是否存在指定型別對應的實作策略
- (BOOL)containsPrepayDataStrategyWithPayType:(PayType)payType;

//根據支付的列舉型別,獲取預支付資訊處理物件
- (id<PayDataPrepareProtocol>)getPrepayDataStrategyWithPayType:(PayType)payType;
@end


@interface PayConfig ()
@property (nonatomic,strong) NSMutableDictionary *strategyMap;
@end

@implementation PayConfig

//單例物件
+ (instancetype)config {
    static PayConfig *_instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (!_instance) {
           _instance = [[PayConfig alloc] init]; 
        }
    });
    return _instance;
}

//添加獲取預支付資訊對應的策略類, 沒有傳遞實體物件,避免未使用而造成的記憶體浪費
- (void)appendPrepayDataStrategy:(Class)strategyClass withPayType:(PayType)payType {
    if (!strategyClass) {
        return;
    }

    //判斷是否實作了協議
    if (![strategyClass conformsToProtocol:@protocol(PayDataPrepareProtocol)]) {
        return;
    }
    
    NSString *payTypeKey = [Utils convertPayTypeToString:payType]; //將列舉轉成字串
    [self.strategyMap setObject:strategyClass forKey:payTypeKey];

}

//判斷是否存在指定型別對應的實作策略
- (BOOL)containsPrepayDataStrategyWithPayType:(PayType)payType {
    NSString *payTypeKey = [Utils convertPayTypeToString:payType]; //將列舉轉成字串
    return  !self.strategyMap[payTypeKey];
}

//根據支付的列舉型別,獲取預支付資訊處理物件
- (id<PayDataPrepareProtocol>)getPrepayDataStrategyWithPayType:(PayType)payType {

    if (![self containsPrepayDataStrategyWithPayType:payType]) {
        return nil;
    }

    NSString *payTypeKey = [Utils convertPayTypeToString:payType]; //將列舉轉成字串
    Class cls = self.strategyMap[payTypeKey];

    return [[cls alloc] init]; //在需要時才回傳創建的物件
}

//懶加載,需要時創建
- (NSMutableDictionary *)strategyMap {
    if (!_strategyMap) {
        _strategyMap = @{}.mutableCopy;
    }
    return _strategyMap;
}
@end

通過上面的支付配置(單例)物件,我們將以支付型別為key, 以對應的獲取預支付資訊的類為value, 使用字典來管理, 將配置類設計成單例,這樣就可以在支付組件中訪問,并使用其中的配置資訊,

支付組件的偽代碼:

#import "PayConfig.h"

@interface PayManager :NSObject 

//呼叫預支付資訊API介面,用到的請求引數
@property (nonatomic,strong) NSDictionary *requestParams;

//支付第三方型別
@property (nonatomic,assign) PayType payType;

//開始支付
- (void)startPay;
@end


@implementation PayManager 


//開始支付
- (void)startPay {
    
    //1. 根據支付型別,判斷支付配置中是否有需要請求服務API的處理類
    if ([[PayConfig config] containsPrepayDataStrategyWithPayType:self.payType]) {
        id strategy = [[PayConfig config] getPrepayDataStrategyWithPayType:self.payType];
        
        //利用KVC向請求API介面的策略類傳遞請求引數
        [strategy setValue:self.requestParams forKey:@“requestParams”];
        
        //準備好請求資料后,開始呼叫介面API獲取所需要的預支付資訊
        [strategy getPayData:^(id result, NSError *error ) {
            //拿到需要的預支付資訊后,再調起第三方支付組件
            
        }];
    
    }else {
        // 調起第三方支付組件
    }

}
@end

總結

通過我們的進一步設計,支付組件已完全不依賴于網路組件來完成對預支付資訊的獲取,而且擴展性更強了, 如果以后有新的支付第三方加入進來,且需要獲取預支付資訊的, 我們只需要實作PayDataPrepareProtocol 協議, 并將其加入到 PayConfig 中就可以了, 通過少量的修改我們就可以完成擴展,也遵循了“開閉原則( 對擴展開放,對修改關閉)” ,

完整的支付組件代碼請前往:RZPayManager
在README.md檔案中有該組件的使用詳解,如果喜歡,點關注支持一下,

后記

如果本文對你有一點幫助的話,歡迎收藏、點贊,感謝,文中如有不對之處,也歡迎大家在評論區指出,共勉,

本文來自博客園,作者:reyzhang,轉載請注明原文鏈接:https://www.cnblogs.com/reyzhang/p/17498798.html

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/555851.html

標籤:其他

上一篇:iOS 微信、支付寶、銀聯支付組件的進一步設計

下一篇:返回列表

標籤雲
其他(161518) Python(38244) JavaScript(25513) Java(18251) C(15238) 區塊鏈(8271) C#(7972) AI(7469) 爪哇(7425) MySQL(7265) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5875) 数组(5741) R(5409) Linux(5347) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4606) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2437) ASP.NET(2404) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) .NET技术(1984) HtmlCss(1971) 功能(1967) Web開發(1951) C++(1942) python-3.x(1918) 弹簧靴(1913) xml(1889) PostgreSQL(1881) .NETCore(1863) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • iOS 微信、支付寶、銀聯支付組件的進一步設計

    原文地址:https://zhanglei.blog.csdn.net/article/details/121376500 ## 前言 有段時間沒寫技術文章了,一是因為作業太忙,再者因為本人文筆實在一般。最近終于閑下來,本著分享的目的將一些組件設計上的心得與大家分享。 本篇文章是基于原有一篇關于支付 ......

    uj5u.com 2023-06-24 08:14:13 more
  • iOS 微信、支付寶、銀聯支付組件的進一步設計

    原文地址:https://zhanglei.blog.csdn.net/article/details/121376500 ## 前言 有段時間沒寫技術文章了,一是因為作業太忙,再者因為本人文筆實在一般。最近終于閑下來,本著分享的目的將一些組件設計上的心得與大家分享。 本篇文章是基于原有一篇關于支付 ......

    uj5u.com 2023-06-24 08:14:00 more
  • Flutter狀態管理新的實踐

    宣告式UI其實并不是近幾年的新技術,但是近幾年宣告式UI框架非常的火熱。單說移動端,跨平臺方案有:RN、Flutter。iOS原生有:SwiftUI。android原生有:compose。可以看到宣告式UI是以后的前端發展趨勢。而狀態管理是宣告式UI框架的重要組成部分。 ......

    uj5u.com 2023-06-21 08:53:40 more
  • Android Studio中SQLite的使用,主要介紹sqlite插入和讀出圖片(View

    sqlite簡介 本人最近在寫一個小的安卓專案,開發app程序中用到了安卓自帶的sqlite。本文主要對sqlite圖片操作進行介紹,其他存入文本之類的操作和普通資料庫一樣,眾所周知,sqlite是一款輕型的資料庫,以下先簡單介紹一下sqlite,為后續做鋪墊,有了解的大佬可以跳過此部分: SQLi ......

    uj5u.com 2023-06-20 09:33:03 more
  • Android程式員成長之路

    # 一、Android程式員需要具備的素養 1. 應該熱愛學習Android知識 2. 具備基本的自學能力和解決問題的能力 3. 具備實踐能力 # 二、Android程式員最終需要熟練掌握的語言 1. Java(基本) 2. C/C++(進階) 3. Kotlin(基本) 4. Python(可選) ......

    uj5u.com 2023-06-20 09:32:56 more
  • Airtest影像識別測驗工具原理解讀&最佳實踐

    Airtest是一個跨平臺的、基于影像識別的UI自動化測驗框架,適用于游戲和App,支持平臺有Windows、Android和iOS。Airtest框架基于一種圖形腳本語言Sikuli,參考該框架后,不再需要一行行的寫代碼,通過截取按鈕或輸入框的圖片,用圖片組成測驗場景,這種方式學習成本低,簡單易上... ......

    uj5u.com 2023-06-20 09:32:51 more
  • Android Studio中SQLite的使用,主要介紹sqlite插入和讀出圖片(View

    sqlite簡介 本人最近在寫一個小的安卓專案,開發app程序中用到了安卓自帶的sqlite。本文主要對sqlite圖片操作進行介紹,其他存入文本之類的操作和普通資料庫一樣,眾所周知,sqlite是一款輕型的資料庫,以下先簡單介紹一下sqlite,為后續做鋪墊,有了解的大佬可以跳過此部分: SQLi ......

    uj5u.com 2023-06-20 09:32:29 more
  • Android程式員成長之路

    # 一、Android程式員需要具備的素養 1. 應該熱愛學習Android知識 2. 具備基本的自學能力和解決問題的能力 3. 具備實踐能力 # 二、Android程式員最終需要熟練掌握的語言 1. Java(基本) 2. C/C++(進階) 3. Kotlin(基本) 4. Python(可選) ......

    uj5u.com 2023-06-20 09:32:23 more
  • Airtest影像識別測驗工具原理解讀&最佳實踐

    Airtest是一個跨平臺的、基于影像識別的UI自動化測驗框架,適用于游戲和App,支持平臺有Windows、Android和iOS。Airtest框架基于一種圖形腳本語言Sikuli,參考該框架后,不再需要一行行的寫代碼,通過截取按鈕或輸入框的圖片,用圖片組成測驗場景,這種方式學習成本低,簡單易上... ......

    uj5u.com 2023-06-20 09:32:16 more
  • Android-NDK開發——基本概念

    在Android開發中,有時候出于安全,性能,代碼共用的考慮,需要使用C/C++撰寫的庫。雖然在現代化工具鏈的支持下,這個作業的難度已經大大降低,但是畢竟萬事開頭難,初學者往往還是會遇到很多不可預測的問題。本篇就是基于此背景下寫的一份簡陋指南,希望能對剛開始撰寫C/C++庫的讀者有所幫助。同時為了盡 ......

    uj5u.com 2023-06-18 08:09:33 more