1、模式標準
模式名稱:適配器模式
模式分類:結構型
模式意圖:適配器模式的意圖是將一個類的接口轉換成客戶端期望的另一個接口。適配器模式使原本接口不兼容的類可以一起工作。
結構圖:
適用于:
-
系統需要使用現有的類,而這些類的接口不符合系統的需要。?適配器可以在不修改現有類的情況下提供一個兼容的接口。
-
想要構建一個可重用的類,這個類可以與其他不相關的類或不可預見的類(即那些接口可能不一定兼容的類)協同工作。
-
需要一個統一的輸出接口,而輸入端的類型不可預知。
2、分析與設計?
需要統一輸出接口,在游戲開發中應該也有一些,這里舉的例子是通訊適配。比如一般的網絡請求都是XMLHttpRequest進行的get與post的請求,請求體是json,返回的是自己熟悉的{code:200,msg:"成功",data:{}}格式,但是我用tsrpc這個ts框架后,請求體變成了tsrpc特有的Proto,且返回個格式變為了{isSucc:true,err:null,res:{}},我希望游戲框架里面請求方式是類似xhgame.net.post('/api/userInfo'),無論我們如何換后端,前端都是不用改。
3、開始打造
export abstract class IRequest {abstract get(url: string, reqData: any, callback: Function): voidabstract post(url: string, reqData: any, callback: Function): void
}
export class Http extends IRequest {public get(url: string, reqData: any, callback: Function) {url = xhgame.config.game_host + urlurl += "?";for (var item in reqData) {url += item + "=" + reqData[item] + "&";}var xhr = new XMLHttpRequest();xhr.onreadystatechange = function () {if (xhr.readyState == 4) {if (xhr.status >= 200 && xhr.status < 400) {var response = xhr.responseText;if (response) {var responseJson = JSON.parse(response);callback(responseJson);} else {console.log("返回數據不存在")callback(false);}} else {console.log("請求失敗")callback(false);}}};xhr.open("GET", url, true);xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");xhr.setRequestHeader('Authorization', 'Bearer ' + xhgame.storage.origin_get('token'));xhr.send();}public post(url: string, reqData: any, callback: Function) {url = xhgame.config.game_host + url//1.拼接請求參數var param = "";for (var item in reqData) {param += item + "=" + reqData[item] + "&";}//2.發起請求var xhr = new XMLHttpRequest();xhr.onreadystatechange = function () {if (xhr.readyState == 4) {if (xhr.status >= 200 && xhr.status < 400) {var response = xhr.responseText;if (response) {var responseJson = JSON.parse(response);callback(responseJson);} else {console.log("返回數據不存在")callback(false);}} else {console.log("請求失敗")callback(false);}}};xhr.open("POST", url, true);xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");xhr.setRequestHeader('Authorization', 'Bearer ' + xhgame.storage.origin_get('token'));xhr.send(param);//reqData為字符串形式: "key=value"}
}
import { Http } from "../../../xhgame-framework/net/Http";
import { HttpClient as HttpClient_Miniapp, WsClient as WsClient_Miniapp } from 'tsrpc-miniapp';
import { HttpClient as HttpClient_Browser, WsClient as WsClient_Browser } from 'tsrpc-browser';
import { serviceProto as ServiceProtoGate, ServiceType as ServiceTypeGate } from "../../tsshared/protocols/ServiceProtoGate";import { PREVIEW } from "cc/env";export enum TSPRC_API {GetOpenid = "GetOpenid"
}
// 設計模式6(適配器)
export class TsrpcAdapterHttp extends Http {tsrpc: HttpClient_Miniapp<ServiceTypeGate> | HttpClient_Browser<ServiceTypeGate> = nullconstructor() {super()this.tsrpc = new (PREVIEW ? HttpClient_Browser : HttpClient_Miniapp)(ServiceProtoGate, {server: 'http://127.0.0.1:8010',json: true,logger: console,});}async get(url: TSPRC_API, reqData: any, callback: Function) {let res = await this.tsrpc.callApi(url, reqData)callback(res)}async post(url: TSPRC_API, reqData: any, callback: Function) {let res = await this.tsrpc.callApi(url, reqData)callback(res)}}
4、開始使用?
在用構建器構建游戲時
setNet(): IGameBuilder {//return new Http()this.net = new TsrpcAdapterHttp()return this;}
有了適配器請求方式都統一稱如下方式了
xhgame.net.post(api,data)
完成