数据兼容性问题解决
最近经常遇到新老数据兼容性的问题:某个数据或者字段,存储在服务器上,版本迭代后,数据类型变化,前端需要兼容已有的数据类型。
例如一个用户对象:
例如第一版中,包括了姓名(字符串),年龄(数字),性别(布尔值)
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 || '';
}
}
最好的解决办法,还是在初期设计考虑各种情况,考虑后续的兼容性。