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、开始打造
TypeScript
export abstract class IRequest {
abstract get(url: string, reqData: any, callback: Function): void
abstract post(url: string, reqData: any, callback: Function): void
}
TypeScript
export class Http extends IRequest {
public get(url: string, reqData: any, callback: Function) {
url = xhgame.config.game_host + url
url += "?";
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"
}
}
TypeScript
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> = null
constructor() {
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、开始使用
在用构建器构建游戏时
TypeScript
setNet(): IGameBuilder {
//return new Http()
this.net = new TsrpcAdapterHttp()
return this;
}
有了适配器请求方式都统一称如下方式了
TypeScript
xhgame.net.post(api,data)
完成