封装记录
封装记录也叫做使用数据类来代替记录
其实也就是对记录型结构使用类进行抽象
什么是记录型结构?
“记录型结构是多数编程语言提供的一种常见特性。它们能直观地组织起存在关联的数据,让我可以将数据作为有意义的单元传递,而不仅是一堆数据的拼凑”
摘录来自: 马丁·福勒(Martin Fowler). “重构:改善既有代码的设计(第2版)。”
记录型结构我觉得就是一个对象,其属性具有特定含义。(不对的话,还请在评论区指出)
const person = { name: 'luxi', age: 26 } // 结构型
const person = { b: 'xxx' } // 不是
为什么需要使用封装记录?
传统封装的好处:
- 提高代码的可控性,避免任意修改属性值,造成值不统一。
- 提高代码的易用性,减少开放的调用方法,减少调用者的负担。
封装记录的好处?
- 只对需要使用的属性,提供了调用方法,提高了代码的易用性。
- 有助于字段改名,字段改名后可以在旧字段存取方法里调用新字段的存取方法,实现兼容,然后逐步的修改调用方,直到替换完成。
可变数据和不可变数据?
作者在文中提到,对于可变对象更偏爱使用对象类,也就是所谓的封装记录。
那什么是可变数据和不可变数据呢?
简单来说就是如果一个变量修改值会导致其在内存中地址的改变,那么它就是一个不可变数据,否则就是一个可变数据。
对于可变数据为什么应该使用类?
为了避免可变数据带来的影响, 将属性进行拆分,统一为属性添加get, set方法,如果属性也是可变数据,那就存在问题。
那如果我将可变数据改为不可变数据,是不是就可以不用类进行封装了呢?
是的,应为使用类其实也就是为了解决可变数据带来的问题。
例1:
重构前:
1 const organization = {name: "Acme Gooseberries", country: "GB"}; 2 3 // 直接使用 4 result += `<h1>${organization.name}</h1>`; 5 organization.name = newName;
重构后:
1 class Organization { 2 constructor(data) { 3 this.name = data.name 4 this.country = data.country 5 } 6 7 set name(aString) { 8 this.name = aString 9 } 10 11 get name() { 12 return this.name 13 } 14 15 set country(aCountryCode) { 16 this.country = aCountryCode 17 } 18 19 get country() { 20 return this.country 21 } 22 }
例2:
重构前:
1 const customerData = { 2 "1920": { 3 name: "martin", 4 id: "1920", 5 usages: { 6 "2016": { 7 "1": 50, 8 "2": 55, 9 // remaining months of the year 10 }, 11 "2015": { 12 "1": 70, 13 "2": 63, 14 // remaining months of the year 15 } 16 } 17 } 18 } 19 20 // 更新 21 customerData[customerID].usages[year][month] = amount; 22 23 // 读取 24 function compareUsage (customerID, laterYear, month) { 25 const later = customerData[customerID].usages[laterYear][month]; 26 const earlier = customerData[customerID].usages[laterYear - 1][month]; 27 return {laterAmount: later, change: later - earlier}; 28 }
重构后:
1 class customerData { 2 constructor(data) { 3 this._data = data 4 } 5 6 get rawData() { 7 return _.cloneDeep(this._data); 8 } 9 10 setUsage(customerID, year, month, amount) { 11 this._data[customerID].usages[year][month] = amount; 12 } 13 } 14 15 function getCustomerData() {return customerData;} 16 function getRawDataOfCustomers() {return customerData.rowData;} 17 function setRawDataOfCustomers(arg) {customerData = new CustomerData(arg);} 18 19 // 获取 20 function compareUsage (customerID, laterYear, month) { 21 const later = getCustomerData().rawData[customerID].usages[laterYear][month]; 22 const earlier = getCustomerData().rawData[customerID].usages[laterYear - 1][month]; 23 return {laterAmount: later, change: later - earlier}; 24 }

浙公网安备 33010602011771号