自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

通用詳情頁的打造,你學(xué)會了嗎?

開發(fā) 前端
作為用戶核心消費(fèi)場景,詳情頁不僅需要承接各種業(yè)務(wù)的轉(zhuǎn)化,還要負(fù)責(zé)展示各業(yè)務(wù)在播放頁的功能??梢哉f,播放頁的代碼復(fù)雜度屬于客戶端最高的代碼之一,這不僅因?yàn)椴シ彭摫旧淼墓δ軓?fù)雜,還因?yàn)樗枰诤洗罅客獠繕I(yè)務(wù)功能。

背景介紹

圖片圖片

大家都知道,詳情頁承載了站內(nèi)的核心流量。它的量級到底有多大呢?

我們來看一下,日均播放次數(shù)數(shù)億次,這么大的流量,其重要程度可想而知。

在這樣一個頁面,每一個功能都是大量業(yè)務(wù)的匯總點(diǎn)。

作為用戶核心消費(fèi)場景,詳情頁不僅需要承接各種業(yè)務(wù)的轉(zhuǎn)化,還要負(fù)責(zé)展示各業(yè)務(wù)在播放頁的功能。

可以說,播放頁的代碼復(fù)雜度屬于客戶端最高的代碼之一,這不僅因?yàn)椴シ彭摫旧淼墓δ軓?fù)雜,還因?yàn)樗枰诤洗罅客獠繕I(yè)務(wù)功能。

復(fù)雜的功能自然會帶來較高的代碼復(fù)雜度,而高代碼復(fù)雜度往往意味著高代碼維護(hù)成本。

明確需求

圖片圖片

我們來看一下沒有做這個項(xiàng)目之前的狀態(tài)。如圖所示,他們分別為三個業(yè)務(wù)團(tuán)隊(duì)各自維護(hù)。頁面間相互獨(dú)立。能力無法復(fù)用。

圖片圖片

通過這個項(xiàng)目,我們要將他們?nèi)诤铣闪艘粋€頁面。產(chǎn)品的訴求就是將他們?nèi)诤蠟橐粋€,來達(dá)到多業(yè)務(wù)形態(tài)統(tǒng)一的目標(biāo)。

圖片圖片

但是,這三個詳情頁并不像產(chǎn)品想象的那么簡單。

每個業(yè)務(wù)都有自己的特殊形態(tài),如大型活動態(tài)、主客態(tài)、播單態(tài)、PUGV/OGV態(tài)等一系列業(yè)務(wù)形態(tài)。

每種形態(tài)都有自己的特殊邏輯,而且這些業(yè)務(wù)形態(tài)間還可以互相切換。

需求分析

為了更好地達(dá)成目標(biāo),我們需要進(jìn)行如下思考:

  • 從業(yè)務(wù)角度:

要解決多業(yè)務(wù)形態(tài)不統(tǒng)一的問題。例如,產(chǎn)品既想要UGC大型活動的能力,又想要OGV的多視角功能。

但這兩個能力在之前分別是兩個業(yè)務(wù)團(tuán)隊(duì)各自開發(fā)的,無法復(fù)用,產(chǎn)品在業(yè)務(wù)選擇上無法兼得。

  • 從效率角度:

要解決迭代方式不統(tǒng)一的問題。例如,進(jìn)度條體驗(yàn)優(yōu)化需求,產(chǎn)品在給UGC團(tuán)隊(duì)提需求的同時,還要復(fù)制一份給OGV團(tuán)隊(duì)。

兩個業(yè)務(wù)方的開發(fā)和測試都需要進(jìn)入這個項(xiàng)目,并且雙方的開發(fā)進(jìn)度和排期可能不一致。如果產(chǎn)品強(qiáng)烈要求同一版本上線,還需要協(xié)調(diào)各方資源。

  • 從質(zhì)量角度:

要解決如何保障穩(wěn)定性的問題。例如,多團(tuán)隊(duì)協(xié)作,之前都是組內(nèi)同事協(xié)作開發(fā),現(xiàn)在融入了兩個新的業(yè)務(wù)團(tuán)隊(duì),我們該如何保障穩(wěn)定性。

  • 從團(tuán)隊(duì)角度:

要解決如何讓新人快速上手的問題。正常情況下,新人想要進(jìn)入開發(fā)必須對這個系統(tǒng)足夠了解后才行。

更何況現(xiàn)在變成了三個業(yè)務(wù)融合的頁面。有沒有一種手段,讓新人無需關(guān)心復(fù)雜的業(yè)務(wù)形態(tài)和業(yè)務(wù)邏輯,只需要關(guān)注自己的需求?

具體方案

針對以上問題,我們可以總結(jié)出通用詳情頁框架必須滿足以上三點(diǎn),分別為:復(fù)用性,靈活性,穩(wěn)定性

圖片圖片

接下來我們繼續(xù)對多業(yè)務(wù)形態(tài)進(jìn)行分析。

首先我們從橫向上進(jìn)行拆解,通過對比,我們可以發(fā)現(xiàn)

多業(yè)務(wù)形態(tài)間其實(shí)有很多的相同模塊。如互動,彈幕發(fā)送框,相關(guān)推薦等。

從縱向上進(jìn)行拆解,我們也可以發(fā)現(xiàn)很多相同模塊,如彈窗管理器,主題組件,轉(zhuǎn)場組件等。

那么從橫向和縱向上我們發(fā)現(xiàn),多種業(yè)務(wù)形態(tài)間其實(shí)有很多可以復(fù)用的能力。

圖片圖片

基于前面的思考,我們設(shè)計(jì)了一套通用詳情頁的框架。將其分為三層:

  1. 業(yè)務(wù)層:將業(yè)務(wù)模塊分為兩類,能夠在多業(yè)務(wù)間復(fù)用的模塊抽象到通用業(yè)務(wù),業(yè)務(wù)獨(dú)有模塊則由各業(yè)務(wù)自行負(fù)責(zé)。
  2. 組件層:抽象出各種通用組件,業(yè)務(wù)方可自由選取和組裝。
  3. 框架層:抽象生命周期管理、數(shù)據(jù)管理等核心邏輯,以此來保證整個詳情頁的穩(wěn)定性。

這樣我們就初步解決了復(fù)用性的問題,但是隨之而來的就是靈活性問題。

圖片圖片

我們以實(shí)際場景為例,相關(guān)推薦模塊在課堂態(tài)不展示,但是在ugc和ogv下需要展示,另外他的點(diǎn)擊事件在ugc和ogv下還會出現(xiàn)差異。

同時相關(guān)推薦模塊還強(qiáng)依賴簡介模塊。因?yàn)楹喗槟K也是一個通用組件,業(yè)務(wù)方可以自由替換。

如果哪天業(yè)務(wù)方替換了了簡介模塊,那相關(guān)推薦模塊將無法正常運(yùn)行。

從相關(guān)推薦這個例子我們可以得出如果想讓業(yè)務(wù)模塊復(fù)用,必須滿足兩個條件。

  1. 支持業(yè)務(wù)異化,即允許業(yè)務(wù)能插入自定義邏輯,否則現(xiàn)在抽象的通用模塊在迭代的過程一定會變成非通用,或者里面摻雜各種if else邏輯來支持異化。
  2. 必須保證模塊間相互獨(dú)立,因?yàn)樗袠I(yè)務(wù)邏輯在此框架下都變成了模塊,模塊是可以由業(yè)務(wù)方自由選擇的。

圖片圖片

引入依賴注入

因此,我們需要在流程和模塊中加入依賴注入的能力,用于業(yè)務(wù)方實(shí)現(xiàn)差異化邏輯。

業(yè)務(wù)方可自行插入自己的業(yè)務(wù)邏輯,并選擇或替換業(yè)務(wù)模塊。來解決模塊間的耦合。

定義依賴注入容器

public class BlocStore {
    typealias StoreLock = RecursiveLock
    typealias StoreTable = [String: BlocTable]
 
    private let lock: StoreLock = StoreLock()
    private lazy var storeTable: StoreTable = [:]
}
 
extension BlocStore {
    public func register<Service>(service: Service.Type = Service.self, to: Bloc.Type) {
        let key = "\(service)"
        lock.lock()
        defer { lock.unlock() }
        serviceTable[key] = to
    }
 
    @discardableResult
    public func optional<Service>(service: Service.Type = Service.self) -> Service? {
        let key = "\(service)"
        lock.lock()
        defer { lock.unlock() }
        let service = resolve(bloc)
        return s
    }
}
 
// Bind and unbind
extension BlocStore {
    public func bindBloc(bloc: Bloc) {
 
    }
 
    public func unbindBloc<T: Bloc>(_ blocType: T.Type) {
 
    }
}
 
// BlocLifeCycle
extension BlocStore {
    func onStart(bloc: Bloc?) {
        bloc?.onStart()
    }
 
    func onPause(bloc: Bloc?) {
        bloc?.onPause()
    }
 
    func onResume(bloc: Bloc?) {
        bloc?.onResume()
    }
 
    func onStop(bloc: Bloc?) {
        bloc?.onStop()
    }
}

組件注冊

// 業(yè)務(wù)方根據(jù)業(yè)務(wù)邏輯可以注入不同的實(shí)現(xiàn)
register(service: XXXProtocol.self, to: ABloc.self) // A業(yè)務(wù)形態(tài)
register(service: XXXProtocol.self, to: BBloc.self) // B業(yè)務(wù)形態(tài)

組件解析

let s: XXXProtocol = store.optional()

引入scope

scope分為頁面級和業(yè)務(wù)級兩種scope:

class VDScope {
    public static let core = "store.core.scope"
    public static let biz = "store.biz.scope"
}

定義 Scope 管理來管理模塊的生命周期:

  • Page scope的生命周期與頁面保持一致,Biz scope與業(yè)務(wù)形態(tài)的生命周期保持一致。
  • 即在頁面形態(tài)發(fā)生變化時,框架層會自動將bizscope下的所有模塊進(jìn)行銷毀。
public class BlocStore {
    typealias ScopeTable = [String: String]
    ...
 
    func bizTypeDidChanged() {
        // 銷毀上一個bizscope下所有模塊
        xxxx
        // 初始化新bizscope下模塊
        xxx
    }
}

這樣,新人進(jìn)入開發(fā)時無需關(guān)注當(dāng)前業(yè)務(wù)形態(tài)或業(yè)務(wù)形態(tài)切換的問題,達(dá)到快速上手的目的。

如何保障吞吐速度和質(zhì)量穩(wěn)定?

在開發(fā)資源和測試資源不變的情況下,業(yè)務(wù)范圍擴(kuò)大了,我們該如何保障吞吐速度和質(zhì)量的穩(wěn)定呢?

圖片圖片

我們可以將策略分為三個階段:

1.開發(fā)階段:

對于核心流程添加全鏈路日志,如果發(fā)現(xiàn)不符合預(yù)期的數(shù)據(jù)則直接拋出異常。

同時進(jìn)行技術(shù)埋點(diǎn)上報。如果是對于核心流程的修改,強(qiáng)制添加AB降級方案。

2.測試階段:

有些bug非常隱蔽,在用戶體驗(yàn)上可能沒有任何差異,但內(nèi)部流程或數(shù)據(jù)可能已經(jīng)發(fā)生異常。

對于類似問題,測試根本無法發(fā)現(xiàn)。導(dǎo)致此類問題流入線上的風(fēng)險。我們可以通過添加監(jiān)控和告警,讓我們及時發(fā)現(xiàn)問題。

3.灰度/線上階段:

我們可以通過添加監(jiān)控和告警,讓我們及時發(fā)現(xiàn)問題。

具體實(shí)施方案:

首先,我們對通用詳情頁里核心流程添加了全鏈路日志,并為日志服務(wù)添加了兩項(xiàng)額外能力:

如果發(fā)現(xiàn)日志類型為Error,內(nèi)部自動觸發(fā)DEBUG彈窗提醒,并上報技術(shù)埋點(diǎn),達(dá)到對線上穩(wěn)定性的監(jiān)控。

圖片圖片

同時,搭建離在線數(shù)據(jù)報表和異常告警,進(jìn)一步保障穩(wěn)定性。

至此,搭建了通用詳情頁從發(fā)現(xiàn)問題到定向拉取再到快速定位的閉環(huán)。

責(zé)任編輯:武曉燕 來源: 嗶哩嗶哩技術(shù)
相關(guān)推薦

2022-07-08 09:27:48

CSSIFC模型

2024-02-02 11:03:11

React數(shù)據(jù)Ref

2025-02-06 09:22:28

2023-01-10 08:43:15

定義DDD架構(gòu)

2024-02-04 00:00:00

Effect數(shù)據(jù)組件

2023-07-26 13:11:21

ChatGPT平臺工具

2024-01-19 08:25:38

死鎖Java通信

2024-01-02 12:05:26

Java并發(fā)編程

2023-08-01 12:51:18

WebGPT機(jī)器學(xué)習(xí)模型

2022-12-06 08:37:43

2024-05-29 07:47:30

SpringJava@Resource

2024-05-06 00:00:00

InnoDBView隔離

2024-08-06 09:47:57

2023-01-30 09:01:54

圖表指南圖形化

2024-07-31 08:39:45

Git命令暫存區(qū)

2023-12-12 08:02:10

2023-10-10 11:04:11

Rust難點(diǎn)內(nèi)存

2022-07-13 08:16:49

RocketMQRPC日志

2023-01-31 08:02:18

2023-05-05 06:54:07

MySQL數(shù)據(jù)查詢
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號