一个简单的存档版本管理器

对于上线的游戏,用户数据变动是个相对头疼的问题,我这里花了一小会儿时间做了一个简单的用户数据管理器。
此工具会将用户数据通过每个版本的适配器升级至最新版本,保证线上数据安全:

export interface IVersionAdapter {
    version: string;
    adapt(data: any): any;
}

export class VersionManager {
    private static _instance: VersionManager;
    public static get instance(): VersionManager {
        if (!this._instance) {
            this._instance = new VersionManager();
        }
        return this._instance;
    }

    private _adapters: { [key: string]: IVersionAdapter } = {};

    /**
     * 注册版本适配器
     * @param adapter 
     */
    public register(adapter: IVersionAdapter) {
        this._adapters[adapter.version] = adapter;
    }

    /**
     * 适配数据
     * @param data  数据
     * @param version 数据版本
     * @returns 
     */
    public adaptPipeline(data: any, version: string): any {
        let adapters = this.getNextAdapters(version);
        for (let i = 0; i < adapters.length; i++) {
            const adapter = adapters[i];
            data = adapter.adapt(data);
        }
        return data;
    }

    private compareVersion(v1: string, v2: string): number {
        let ret = 0;
        let v1s = v1.split(".");
        let v2s = v2.split(".");
        let len = Math.max(v1s.length, v2s.length);
        for (let i = 0; i < len; i++) {
            let v1n = parseInt(v1s[i]) || 0;
            let v2n = parseInt(v2s[i]) || 0;
            if (v1n > v2n) {
                ret = 1;
                break;
            } else if (v1n < v2n) {
                ret = -1;
                break;
            }
        }
        return ret;
    }

    private getNextAdapters(version: string): IVersionAdapter[] {
        let ret: IVersionAdapter[] = [];
        for (const key in this._adapters) {
            if (this._adapters.hasOwnProperty(key)) {
                const adapter = this._adapters[key];
                if (this.compareVersion(adapter.version, version) > 0) {
                    ret.push(adapter);
                }
            }
        }
        ret.sort((a, b) => {
            return this.compareVersion(a.version, b.version);
        });
        return ret;
    }
}

使用方法是在需要修改数据的版本新增一个数据适配器,将上一个版本升级至当前版本,当跨越了好几个版本时,会逐步升级至最新版本:

class Version110 {
    name = "1.1.0";
    /**
     * 1.1.0 
     * 1. value字段修改为value1
     * 2. value2字段修改为数组
     * @param data 
     * @returns 
     */
    adapt(data: any): any {
        data.value1 = data.value;
        delete data.value;

        data.value2 = [data.value2];
        return data;
    }
}

class Version120 {
    name = "1.2.0";

    /**
     * 1.2.0
     * 1. 删除value2字段
     * @param data 
     * @returns 
     */
    adapt(data: any): any {
        delete data.value2;
        return data;
    }
}

// 注册版本适配器
VersionManager.instance.register(new Version110());
VersionManager.instance.register(new Version120());

// 适配数据
VersionManager.instance.adaptPipeline(data, "1.0.0");

最终数据会被升级到1.2.0,升级完毕!!!

这里只是提供一种思路或者方法,代码未验证过,请自行测试!

VersionManager (github 地址)

5赞

太强了 mark

哦哦哦哦哦哦哦哦,老哥这个好!!!思路好