1. 程式人生 > >[轉] 前端數據驅動的價值

[轉] 前端數據驅動的價值

理解 獨立 關註 hub 一點 一個 spa 處理模塊 children

數據驅動應該是從flux/redux + react這種模式開始流行的。

他的背後不僅僅是數據驅動這麽簡單,在復雜的系統中,我覺得它解決了一個很關鍵的問題就是模塊間的交互/通信。有很多文章拿他和mvc/mvvm去比較,我個人覺得沒有特別的可比性,因為解決的問題不同。

以往處理模式

一個稍微復雜點的例子:

技術分享圖片

假如有這麽一個頁面,我們按照以往模式開發,首先模塊化開發,拆分成A,B,C 三個模塊,然後每個模塊有自己的子模塊。

如果需求簡單還比較好解決,每個模塊中自己解決自己的邏輯,解耦的非常清晰。父子之間的關系也非常明確。

  1. 例如銷毀C模塊,會自動銷毀它的子模塊C1C101
  2. 模塊間的關系也很清晰,B1
    不會和B2有直接關系,他們之間需要通過B模塊去傳遞。同理,B模塊A模塊也沒有直接關系,他們都需要通過外層頁面去處理關系。

但是假如有這麽一個需求,A2的顯示和B2(用戶交互)以及C101(用戶交互)相關怎麽辦。

按照這種模式,它的解決方案是:

B2如果發生改變,通知B模塊B模塊在通知頁面頁面調用A模塊C模塊C模塊調用C1C1調用C101獲取C101的數據處理,頁面調用A模塊A模塊再調用A2,再結合一下從C101獲取的數據,改變它的展示。

是不是看著很繞,從圖上看是這麽個關系:

技術分享圖片

圖中僅僅顯示了其中一個復雜交互,假如我們再多兩個模塊間關聯的邏輯:

  1. B1B2模塊影響A2
    模塊(圖中黃線)
  2. C1影響B1模塊(圖中白線)

如下圖:

技術分享圖片

3個復雜一點的交互,整個模塊間的通信已經變成蜘蛛網了,重要的是,每一條關系線都需要開發者維護的,不僅影響開發效率,而且不好維護,容易引發bug,假如後期加新需求或者調整需求,開發成本都是比較高的。

可見,對於復雜的交互,或者模塊間關系復雜時,這種依賴父子關系的通信,是一個很大的障礙。

但是我們怎麽辦,拒絕模塊化開發嗎?那樣頁面設計起來耦合度更大,更加不可維護。

首先一點,模塊化開發是一個不可逆的趨勢,然而在這種趨勢下,解決模塊化通信是一個非常重要的點。

模塊間通信其他方案

在那個時候,我考慮最多的就是如何去解決模塊之間的通信,如何讓模塊之間交互更加輕松,模塊之間更加獨立。

方案一:

當時考慮的一個方案是使用一個全局的event(全局的on和fire)。這樣模塊之間就不用依賴父子關系了。模塊和模塊間是可以之間交互的。

但是這樣會有一些弊端:

  1. 事件名稱如何定義,保證不重名
  2. 事件是否會重復的on
  3. 模塊和模塊之間會因為事件產生一些耦合
  4. 當交互特別復雜時,也會比較麻煩,還是上面的例子,B2通知C2改變後,C2還需要通知C101獲取一次數據,來確認改變

整體來看:

優勢: 擺脫了模塊間父子層級關系,可以簡單的跨模塊通信

劣勢: 依然需要維護復雜的模塊間關系,只是可以繞過父子依賴

方案二:

全局共享一個model + component模式。這種其實已經非常趨向與數據驅動了。每個模塊都是共享全局的model,然後每個component都可以被全局獲取到到,裏面的功能屬性可以直接被使用。

其實這種模式已經比較理想,頁面上面的任何component都可以被直接調用到並且使用。

個人覺得缺點就是:
多了一個全局可調用component的功能。如果砍掉他可以實現完成數據驅動,如果模塊調用時,使用多了直接獲取component的功能,還是需要在模塊間維護好和其他模塊間的交互邏輯。

數據驅動

先看一個圖,我感覺可以很好的體現數據驅動

技術分享圖片

提線木偶:他的特點就是每個動作都是,頭,手臂,腳,金箍棒都是由操作的人手決定的,頭和手臂直接沒有任何關系。

數據驅動也可以這麽理解,頁面上面所以的展示都是由數據決定的,和頁面其他地方沒有任何關系。

再來看看上面那個例子如果加上數據驅動的設計思想。

技術分享圖片

頁面之間每個模塊,不用關心父子模塊之間的關系,每個獨立的模塊都是由一個全局的model決定。

回到上面那個麻煩的場景。當B2改變時,它會修改model中對應的數據(效驗C101數據,結合B2的改變,修改A2的數據),然後A2的業務模塊跟進A2的數據改變。

這種設計的核心是每一個模塊的改變,全部都交給model處理。

然後model裏面會和個個模塊一一對應,每個模塊無需關註其他模塊的變化,只需要關註model裏面對應自己數據的變化即可。所以模塊間關系鏈條會顯得非常簡單。

重點在於,當交互邏輯不斷增加時,這個關系鏈條依然不會增加,因為模塊只和model裏面對於的數據相關聯。

當然,這種模式也無法去省略復雜的業務邏輯,只是業務邏輯全部都會聚集在model中。可以理解為頁面上所有的操作都是對數據的操作。然後每個模塊只需要監聽關註的數據改變即可,這個監聽關系就是圖中唯一的一條關系線。

換一個理解,我們將直接的模塊和模塊直接的耦合關系全部轉移到了數據中去體現。而數據的維護是遠遠比模塊更好維護的。

Model如何對應View

還是上面頁面為例子:

model

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
var page = {
a: {
isShow: true,
children: [{
a1: {
isShow: true
}
},
{
a2: {
isShow: true
}
}]
},
b: {
isShow: true,
children: [{
b1: {
isShow: true
}
},
{
b2: {
isShow: true
}
}]
},
c: {
isShow: true,
children: [{
c1: {
isShow: true,
children: [{
c101: {
isShow: true
}
}]
}
}]
}
}

isShow 表示展示的意思。這個狀態對應文章第一個圖片。

技術分享圖片

當數據改變時,例如model發生變化如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
var page = {
a: {
isShow: true,
children: [{
a1: {
isShow: true
}
},
{
a2: {
isShow: false
}
}]
},
b: {
isShow: true,
children: [{
b1: {
isShow: true
}
},
{
b2: {
isShow: false
}
}]
},
c: {
isShow: true,
children: [{
c1: {
isShow: false,
children: [{
c101: {
isShow: true
}
}]
}
}]
}
}

對應下面這樣:

技術分享圖片

換一個理解就是每一種數據狀態對應一種頁面的展示狀態。頁面想展示成什麽樣子,需要數據處理成什麽樣子。數據是這個頁面的核心。

數據驅動開發關註點

第一點數據結構的處理,因為數據決定了整個頁面的展示,數據結構開始的設計非常關鍵,數據結構的可擴展性決定了頁面的可擴展性,如果開始數據模式不好,後期維護也會非常難受。

第二點是處理好模塊和數據中對應的關系。

可以看到數據驅動的難點和關鍵點就是數據結構的設計。而這個也是很考驗開發者能力的。數據結構的好壞直接決定了後期業務開發的質量。

數據驅動和mvc/mvvm的關系

文章開頭說了,從我的角度理解數據驅動這種模式和mvc並沒有什麽競爭關系,在具體的實踐中,每一個模塊可以是一個mvc或者mvvm,模塊的內部處理交給模塊自己,可以是mvc,或者單例也可以。數據驅動主要是處理模塊之間的一種邏輯。

那麽為什麽數據驅動和react這種結合的更加好了?因為react更進一步是講模塊內部也實現一個數據驅動,模塊內部的數據改變了,模塊的狀態會跟著改變。

[轉] 前端數據驅動的價值