封装记录

 

封装记录也叫做使用数据类来代替记录  

其实也就是对记录型结构使用进行抽象

 

什么是记录型结构?

“记录型结构是多数编程语言提供的一种常见特性。它们能直观地组织起存在关联的数据,让我可以将数据作为有意义的单元传递,而不仅是一堆数据的拼凑”

摘录来自: 马丁·福勒(Martin Fowler). “重构:改善既有代码的设计(第2版)。”

记录型结构我觉得就是一个对象,其属性具有特定含义。(不对的话,还请在评论区指出)

const person = { name: 'luxi', age: 26 }   // 结构型

const person = {  b: 'xxx'  }  // 不是  

 

为什么需要使用封装记录?

传统封装的好处:

  1. 提高代码的可控性,避免任意修改属性值,造成值不统一。
  2. 提高代码的易用性,减少开放的调用方法,减少调用者的负担。

封装记录的好处?

  1. 只对需要使用的属性,提供了调用方法,提高了代码的易用性。
  2. 有助于字段改名,字段改名后可以在旧字段存取方法里调用新字段的存取方法,实现兼容,然后逐步的修改调用方,直到替换完成。

 

可变数据和不可变数据?

作者在文中提到,对于可变对象更偏爱使用对象类,也就是所谓的封装记录。

 

那什么是可变数据和不可变数据呢?

简单来说就是如果一个变量修改值会导致其在内存中地址的改变,那么它就是一个不可变数据,否则就是一个可变数据。

 

对于可变数据为什么应该使用类?

为了避免可变数据带来的影响, 将属性进行拆分,统一为属性添加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 }

 

posted @ 2020-04-29 00:27  yoyoluxi  阅读(246)  评论(0)    收藏  举报