在 JavaScript 中,储存资料的方式,长这样。
{
name: 'Chris',
age: 18
}
强型别语言的话,要先宣告「抽象资料型别」
struct User {
char *name;
int age;
};
然後宣告一个实体
struct User chris;
chris.name = "Chris";
chris.age = 18;
这样要变更资料,是直接修改变数本身。像是 JavaScript 操作物件一样的做法。
const chris = {
name: '',
age: 0
}
chris.name = "Chris";
chris.age = 18;
但是,这样会遇到一些问题
const chris = {
first_name: '',
last_name: '',
}
chris.first_name = "Chris";
chris.last_name = "Wang";
如果想要 full name 就要另外写一个逻辑,把它们组合起来。或者写一个 chris.full_name
储存 "Chris Wang"
那麽,会不会遇到资料不同步的问题?
如果只是单纯改变 last_name
需要同步改变 full_name
的内容吗?
抽象资料型别,在物件的体现,就是相关的资料与行为,要放在一起。通常强型别语言,都是放在 class 上面。
class User {
string first_name;
string last_name;
string full_name;
string setFirstName(const string& name) {
first_name = name;
full_name = name + " " + last_name
}
string setLastName(const string& name) {
last_name = name;
full_name = first_name + " " + name
}
};
一样将 full_name
视为资料,并且在设定 first_name
或 last_name
时,同步资料。
另一种做法
class User {
string first_name;
string last_name;
string getFullName() const {
return first_name + " " + last_name;
}
};
将取得全名,视为的行为,里面的实作就是将 first_name
和 last_name
组合起来。
这两种做法都是透过 User 的抽象行为,操作资料。
当然也有针对各别资料设定 getter/setter 的做法。起初这样写会觉得很多此一举,但是後来如果要在 setter 加入资料的定义域,或者要在增加一个 getter 代表资料的另一种表现型式。都是很方便的事情。
後面我就用 javascript 实作
class User {
constructor() {
this.birthday = new Date();
}
setBirthday(year, month, day) {
this.birthday.setYear(year);
this.birthday.setMonth(month -1);
this.birthday.setDate(day);
}
getBirthday () {
return this.birthday;
}
getAge() {
return new Date().getFullYear() - this.birthday.getFullYear();
}
};
有了抽象行为可以将生日与年龄的关系建立起来,并且让资料只有一笔,不会有资料同步的问题。
如果你想要在输入月份超过 12 月,就要抛出例外的话。
就可以随时在 setter 的 method 里面加上限制条件。
class User {
setBirthday(year, month, day) {
// ...
if ((month -1) > 12) throw Error('month > 12');
this.birthday.setMonth(month -1);
// ...
}
};
如果没有先写好 setter ,在想加上条件时,就会比较辛苦的再写一个 function 并且birthday.setMonth(month -1);
搬进去,再将所有原本写 birthday.setMonth(month -1);
替换成 setBirthday()
。
在 vuex 中,如果只有 state
直接存取资料。就像是没有抽象介面的抽象资料型别。
所以我自己的用法,是坚持绝对不要直接存取 state
,并且一定要用 mutation
和 getters
。
其实 state 就是这样短短的。没有什麽特别的
vuex 里面还有一个东西叫 module,我自己就它当作是「系统的抽象资料型别」在使用,像是 User 就是使用者的资料型别,在後端会建立资料表,在前端用 Vue.js 的话,我就会选择在 vuex 建一个 user 的 module。也就是说,将系统要 CRUD 的「名词」找出来,并建立成各种的 module 里面的 state 则是存放资料的地方。
vuex 的里的 module 是对 state 做分群,并且限制 mutation 和 getters 可以取得的 state 的范围,但是mutation 可以透过 commit、getters 可以再呼叫 getters 的方式跨 module 取得其它 module 的 state。
通常系统上需要储存的方式和後端资料表不一样。以 user 为例,要嘛就是显示一个 user 的「列表」要嘛就是显示「一笔」 user 资料。
所以,我有一个极致的用法(但不见得每一次都是这样使用)
在每一个 module 里的 state 都这样规画,其实就可以符合每一个画面的需要了。
export default {
state: {
one: {},
list: []
}
}
这只是一种极致的做法
极致的地方在於,state 里的命名,都只有 one 和 list
当如果有其它的需求,就会另外命名
而且它只适用於 CRUD 的资料。
登入的 token 不适用於这种做法。
最大值与最小值 在一个有n个元素的,未经排序的阵列中,如果我们要找到最小值,我们可以将一个阵列进行排...
安安 过了一周我又来了 首先需要先为自己与同学鼓掌撑过第一周✌️ 第二周开始就是介面地狱 每周第一天...
这是 Roblox 从零开始系列,入门章节的第十三个单元,我们的游戏出现Bug了,那就是死亡後分数还...
基础篇简单了介绍Channel&Goroutine的基本使用方法 接下来就是实际应用的问题了...
10.10 Thorup’s 无向非负整数权重 SSSP 演算法 今天来介绍 Thorup 在 19...