用戶行爲驅動開發(UserAction Driven Development)

前提

用戶行爲驅動開發是什麼?
它是一種適用前端的面向用戶行爲的開發思想,是一個用戶行爲的產生到執行,驅動數據的產生,再由數據流驅動渲染的流程。我認爲,前端要完成的工做就是接收用戶行爲,解析用戶行爲,到給用戶一個反饋。在各類用戶行爲造成一個序列後,在以後的開發中能夠獲得不少方便。前端

用戶行爲驅動開發是如何誕生的?
因爲每一個 App 都須要採集數據進行分析,須要進行數據埋點,這些數據每每都是一個用戶行爲加上一些業務數據,若是使用代碼埋點的方式,就會致使 UI 代碼中總要摻雜着一些額外的埋點邏輯,好比一個 button 的 onClick 中有一段獲取業務數據併發送埋點事件的代碼,長此以往,代碼就會變得臃腫不堪。如今雖然有無痕埋點的方案,可是成本太高,小公司去開發不是很現實。
出了上面的問題後,我意識到用戶行爲是一個關鍵點,其實每個須要採集的數據都由一個或幾個用戶行爲拼湊出來的,好比用戶點擊了登陸按鈕,其實就是由兩個 Action 組成,ButtonClickLoginAction。再好比,用戶上拉加載更多數據,其實就是產生了 PullUpToLoadMoreGetXXXDataAction
帶着這樣的思考,我就開始嘗試了面向用戶行爲開發。程序員

其餘說明數據庫

  • 我是 Android 開發,以後的一些例子可能更適用於移動端,但思路上適合各類前端的
  • 觀察者(訂閱\發佈)模式,解耦利器,用戶行爲驅動開發使用了大量的觀察者模式,讓每個部分職責單一明確
  • 本文不講代碼的具體實現,只講思想,以後可能會寫其餘的文章具體講實現

1、UserAction 的類型

如圖,展現的是移動端的一些基本操做,左邊四個是針對列表頁面的操做,分別爲「下拉刷新」「上拉加載更多」「Item 曝光」「Item 點擊」。剩下四個爲「PageView -> 瀏覽頁面」「UseDomainService -> 使用業務服務」「 ButtonClick -> 按鈕點擊」「ComponentShowUp -> 組件展現」。

這裏具體解釋一下「使用業務服務」和「組件展現」json

  • 「使用業務服務」能夠看作是用戶在使用公司的業務,好比每一個公司都會有登陸註冊,再好比公司中特殊的業務,如看視頻或者獲取一組新聞數據等
  • 「組件展現」是指一個控件或組件彈出,好比 Android 中的 Dialog\Toast\PopupWindow 以及自定義的 Window 等

2、UserAction 驅動渲染的過程

首先說說,在一個簡單的列表頁中,UserAction 是怎樣工做的後端

UserAction 驅動渲染

首先不考慮數據是怎麼得到的,只想 UserAction 如何應用在 UI 代碼中,就是圖中的 5 個步驟。 UI 只負責生產對應的 UserAction,而後觀察它,它在執行後會產生對應的結果,UI 只須要使用結果去渲染。緩存

因此 UI 的職責很明確:bash

  • 產生 UserAction
  • 執行 UserAction
  • 接收數據,進行渲染

UI 中的代碼大概就像這樣:併發

//頁面開始顯示一個列表
start() {
     observer = List<xxx> result -> { 
        render(result);
    }
    new GetXXXListAction().execute(observer);
}

//登陸
loginBtn.setOnClickListener(v -> {
    ButtonClickAction btnClickAction = new ButtonClickAction();
    btnClickAction.enqueue();
    
    LoginAction loginAction = new LoginAction();
    loginAction.execute(observer, params);// observer 用於觀察登陸狀態變化,參數爲用戶名密碼
})
複製代碼

3、UseDomainAction 的執行過程

用戶選擇使用咱們的 app,就是在使用咱們提供的業務服務,因此業務邏輯處理是咱們平時開發精力投放最多的一部分,我具體說一下「UseDomainService」是如何工做的。基於模塊化開發,咱們每一個業務應該對一個模塊,因此 action 執行時就是調用咱們的業務模塊的接口,這裏針對業務模塊的異步請求會再次使用觀察者模式或是個 CallBack ,action 觀察業務模塊,而後接收模塊返回的結果,再將結果發給執行 action 的頁面。app

下面是針對數據流向的一個圖,可歸納爲UI -> Action -> Data -> ViewModel -> Render,UI 產生用戶行爲,用戶行爲驅動數據產生,數據驅動 UI 渲染 異步


4、其餘 UserAction 的使用方式

  • 「PageView」:可在 LifecycleManager 的 onActivityResumed 方法中進行建立,而後取到每一個 Activity 的路由 url 或是類名,存放到 PageViewAction 中。若是你有一個 BaseActivity,也可寫在 BaseActivity 的 onResume 方法中
  • 「PullDownToRefresh/PullUpToLoadMore」: 可在列表刷新控件的 callback 中,建立這個 Action,例如繼承 SmartRefreshLayout 而後重寫 refresh 和 loadMore 方法,在裏面加上對應的 Action
  • 「ButtonClick」:和上面👆相似,繼承 Button,在 onClick 中,添加 ButtonClickAction
  • 「ComponentShowUp」:也是繼承基礎控件,而後再 show 的時候添加這個 Action
  • 「ItemImpression」:這個比較特殊,是列表中每一個 item 曝光的行爲,個人作法是在 RecyclerView 的OnChildAttachStateChangeListener 中的 onChildAttached 方法中記錄,而且要綁定一些業務數據

這些 Action 在生成或執行時須要存放到一個列表裏,造成一個序列,下一節會具體介紹。


5、UserActionSequence 用戶行爲序列

如下展現的是從開屏頁,跳轉到登陸頁,而後點了登陸按鈕的一個 UserActionSequence

假如數據須要咱們在登陸按鈕處埋點,咱們只須要從序列中找到對應的 Action 組成事件發到後端便可。固然後端最好也抽象出一些通用事件配合前端,那樣用戶序列的威力就會發揮到極致,基本能夠在 UI 代碼中作到無痕。下一節會簡單說一下用戶序列如何配合埋點系統作到基本無痕的埋點方式。


6、淺談埋點

按職能解釋「EventTracker」的每一部分:

  • 「ProcessedActionBuffer」:
    須要觀察 UserAction 入隊,當有新 Action 入隊時,就將其存到 ProcessedActionBuffer 中,並作一些特殊處理,好比「PageView」 咱們是在 onResume 時生成的,但有時彈 Dialog 再回來的時候又會觸發一次「PageView」(Android Activity 生命週期決定的,其餘平臺可能不會有這種問題),因此須要去重,保證發送沒有冗餘的數據給後端
  • 「EventActionMapper」:
    用於映射 Action 和 Event,其實就是一套行爲和事件的轉換規則(須要先後端配合)
  • 「EventBuffer」:
    存儲轉換過的 Event,有一套本身的策略進行緩存(例如大於100條存入本地數據庫),還有一套策略用於發送(1分鐘輪訓一次 EventBuffer 進行發送)

圖中還畫了 Logger 和 Other 兩個模塊,Logger 能夠根據行爲序列記錄一些日誌,用於分析 Crash 和一些業務的異常,Other 你們就能夠根據本身的腦洞和須要進行設計了,好比 UserActionSequence 是把 UserAction 序列化爲 json 的過程,咱們也能夠把 json 反序列化成對象,而後再交給對應的 UI 去執行,這樣就能夠完成 UI 自動化測試。


7、總結

原來常使用的 MVP 或者最近比較火的 Android Architecture Component 使用的 MVVM,都不能很好的用代碼來表示用戶行爲(代碼可讀性不夠直觀),雖然 Presenter 和 VM 的職能也是用來解釋用戶行爲獲取數據再到驅動渲染,但我以爲對於程序員來講仍是不夠友好。但使用 UserAction 來貫穿整個前端的流程,一切看起來就變得天然了,UI、模塊、數據的職責也都顯得更單一了。

重要的是這樣開發是咱們得到了用戶的操做序列,一切的數據源於用戶。有了它對之後的分析和其餘的開發都會有很大幫助。


本文爲原創文章,如需轉載請註明出處,謝謝!
若有問題可留言討論~

相關文章
相關標籤/搜索