成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

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

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

背景介紹

圖片圖片

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

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

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

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

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

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

明確需求

圖片圖片

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

圖片圖片

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

圖片圖片

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

每個(gè)業(yè)務(wù)都有自己的特殊形態(tài),如大型活動(dòng)態(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)一的問(wèn)題。例如,產(chǎn)品既想要UGC大型活動(dòng)的能力,又想要OGV的多視角功能。

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

  • 從效率角度:

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

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

  • 從質(zhì)量角度:

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

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

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

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

具體方案

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

圖片圖片

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

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

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

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

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

圖片圖片

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

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

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

圖片圖片

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

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

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

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

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

圖片圖片

引入依賴注入

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

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

定義依賴注入容器

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()
    }
}

組件注冊(cè)

// 業(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è)面級(jí)和業(yè)務(wù)級(jí)兩種scope:

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

定義 Scope 管理來(lái)管理模塊的生命周期:

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

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

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

在開(kāi)發(fā)資源和測(cè)試資源不變的情況下,業(yè)務(wù)范圍擴(kuò)大了,我們?cè)撊绾伪U贤掏滤俣群唾|(zhì)量的穩(wěn)定呢?

圖片圖片

我們可以將策略分為三個(gè)階段:

1.開(kāi)發(fā)階段:

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

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

2.測(cè)試階段:

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

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

3.灰度/線上階段:

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

具體實(shí)施方案:

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

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

圖片圖片

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

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

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

2024-02-02 11:03:11

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

2023-08-01 12:51:18

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

2024-01-02 12:05:26

Java并發(fā)編程

2025-02-06 09:22:28

2022-07-08 09:27:48

CSSIFC模型

2024-05-29 07:47:30

SpringJava@Resource

2022-12-06 08:37:43

2024-01-19 08:25:38

死鎖Java通信

2024-02-04 00:00:00

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

2023-07-26 13:11:21

ChatGPT平臺(tái)工具

2023-01-10 08:43:15

定義DDD架構(gòu)

2024-03-06 08:28:16

設(shè)計(jì)模式Java

2022-06-16 07:50:35

數(shù)據(jù)結(jié)構(gòu)鏈表

2022-12-06 07:53:33

MySQL索引B+樹(shù)

2022-07-13 08:16:49

RocketMQRPC日志

2023-10-06 14:49:21

SentinelHystrixtimeout

2023-05-05 06:54:07

MySQL數(shù)據(jù)查詢

2023-01-31 08:02:18

2023-07-30 22:29:51

BDDMockitoAssert測(cè)試

2023-08-26 21:34:28

Spring源碼自定義
點(diǎn)贊
收藏

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

主站蜘蛛池模板: 日韩在线视频网址 | 免费视频二区 | 色婷婷亚洲 | 国产伦精品一区二区三区高清 | 日韩中文字幕 | 亚洲黄色av | 91精品国产综合久久久亚洲 | 亚洲一区二区三区四区五区中文 | 91精品国产777在线观看 | 91porn在线观看 | 亚洲国产精品一区二区第一页 | 日韩在线欧美 | 91精品无人区卡一卡二卡三 | 99久久久无码国产精品 | 天堂综合网久久 | 亚洲一区二区三区在线视频 | 欧美精三区欧美精三区 | 久久精品一区二区 | 国产成人精品一区二三区在线观看 | 日本天堂视频在线观看 | 日韩美香港a一级毛片免费 国产综合av | 国产 欧美 日韩 一区 | 亚洲v日韩v综合v精品v | 国产在线精品一区二区三区 | 欧美日韩国产在线 | 国产成人a亚洲精品 | 精品国产乱码久久久久久蜜退臀 | 午夜寂寞网站 | 国产麻豆一区二区三区 | 国产视频二区在线观看 | 久久一区精品 | 国产精品一区一区三区 | 男女爱爱福利视频 | 日韩在线中文字幕 | 欧美日韩亚洲系列 | 国产久| 亚洲日韩中文字幕一区 | 国产精品99999| 日本一区二区高清不卡 | 日本精品一区二区三区视频 | 一区二区三区四区电影 |