Skip to content

数据兼容性问题解决

统计信息:字数 2676 阅读6分钟

最近经常遇到新老数据兼容性的问题:某个数据或者字段,存储在服务器上,版本迭代后,数据类型变化,前端需要兼容已有的数据类型。

例如一个用户对象:

例如第一版中,包括了姓名(字符串),年龄(数字),性别(布尔值)

let user1 = {
  version: 1,
  name: 'Michael',
  age: 20,
  isFemale: true,
};

第二版中

产品改了需求,针对国外用户,姓名改成了姓,名两个字段

性别改成了字符串,有的用户选择不显示性别

let user2 = {
  version: 2,
  first_name: 'Michael',
  last_name: 'An',
  age: 20,
  gender: 'male' or 'female' or ''
}

第三版中,增加了地址(字符串)

let user3 = {
  version: 3,
  first_name: 'Michael',
  last_name: 'An',
  age: 20,
  address: 'Beijing',
  gender: 'male',
}

第四版中,可能有多个住址,地址字段改成数组

let use4 = {
  version: 4,
  first_name: 'Michael',
  last_name: 'An',
  age: 20,
  address: ['Beijing', 'Shanghai'],
  gender: 'male' or 'female',
}

后端返回的数据中,有这些情况,那么前端使用时,需要兼容这多个版本的数据。

可以添加 version 字段,数据预处理代码如下:

const preprocess = function(user) {
  if (typeof user !== 'object') {
    console.log('用户无效');
    return null;
  }
  if (user.version === 1) {
    const { age } = user;
    return {
      version: 4,
      first_name: user.name,
      last_name: '',
      age,
      address: [],
      gender: user.isFemale ? 'female' : 'male',
    };
  }
  else if (user.version === 2) {
    const { first_name, last_name, age, gender } = user;
    return {
      version: 4,
      first_name,
      last_name,
      age,
      address: [],
      gender,
    }
  }
  else if (user.version === 3) {
    const { first_name, last_name, age, gender, address } = user;
    return {
      version: 4,
      first_name,
      last_name,
      age,
      address: [address],
      gender,
    }
  }
  else if (user.version === 4) {
    return user;
  }
}

如果未来新增其他属性,那么根据新属性继续兼容。

也可以写一个 model user 类处理属性,优化代码,代码如下。

class User {
  constructor(obj) {
    this.version = obj.version || 4;
    this.first_name = obj.first_name || '';
    this.last_name = obj.last_name || '';
    this.age = obj.age || 0;
    this.address = obj.address || [];
    this.gender = obj.gender || '';
  }
}

最好的解决办法,还是在初期设计考虑各种情况,考虑后续的兼容性。


Last update: November 9, 2024