跨桌面端之組件化實(shí)踐
背景介紹
windows千牛功能很豐富,mac千牛什么時(shí)候可以把能力對(duì)齊?
相信所有跨平臺(tái)應(yīng)用,都有遇到過(guò)這樣的窘境。由于平臺(tái)差異的復(fù)雜性,維護(hù)多端產(chǎn)品成本非常高,且常常存在多端體驗(yàn)不一致的問(wèn)題。情況就是這樣,而我們團(tuán)隊(duì)維護(hù)了pc千牛和pc旺旺2款跨端產(chǎn)品,在效能和體驗(yàn)的雙重壓力之下,搭建一個(gè)多端統(tǒng)一的pc應(yīng)用跨平臺(tái)開(kāi)發(fā)框架勢(shì)在必行。
本文主要介紹了千牛PC跨端框架中,我們關(guān)于組件化部分的思考、方案選擇、遇到的一些問(wèn)題和解法。
所謂框架,它既是一個(gè)“框子”,有一定的約束性,也是一個(gè)“架子”,有一定的支撐性。IT語(yǔ)境中的框架,特指為解決一個(gè)開(kāi)放性問(wèn)題而設(shè)計(jì)的具有一定約束性的支撐結(jié)構(gòu)。在此結(jié)構(gòu)上可以根據(jù)具體 問(wèn)題擴(kuò)展、安插更多的組成部分,從而更迅速和方便地構(gòu)建完整的解決問(wèn)題的方案。
為什么要做組件化?
跨端框架為什么選擇做組件化?
框架本身一般不能直接解決某個(gè)具體問(wèn)題,但為解決問(wèn)題的相關(guān)組件提供了一些銜接、組合的基礎(chǔ)能力。
框架的科學(xué)性、易用性,直接決定了研發(fā)效率和產(chǎn)品質(zhì)量。
組件化是用來(lái)解決框架功能擴(kuò)展、復(fù)用的一種非常合適的技術(shù)方案。
而用組件化模式設(shè)計(jì)的一個(gè)應(yīng)用框架,一般具備以下特性:
- 極好的擴(kuò)展性
- 極好的復(fù)用性
- 靈活度高,可以很方便組裝或下線(xiàn)功能
- 修改功能,影響范圍很小
- 非常適合團(tuán)隊(duì)分工協(xié)作
這些優(yōu)點(diǎn),每一項(xiàng)都是我們夢(mèng)寐以求的,所以說(shuō)組件化對(duì)我們幾乎是必然選擇。
組件化是什么?
組件化是指解耦復(fù)雜系統(tǒng)時(shí)將多個(gè)功能模塊拆分、重組的過(guò)程,有多種屬性、狀態(tài)反映其內(nèi)部特性。
舉個(gè)例子,你要造一個(gè)汽車(chē),但是發(fā)現(xiàn)汽車(chē)實(shí)在太復(fù)雜了,很難實(shí)現(xiàn),于是:
- 你把汽車(chē)拆分成了底盤(pán),發(fā)動(dòng)機(jī),變速箱,輪子等模塊,定義好了他們各自的職責(zé)。
- 然后你找來(lái)小伙伴幫忙,先約定好了組件標(biāo)準(zhǔn),再讓每個(gè)人實(shí)現(xiàn)其中一個(gè)獨(dú)立模塊。
- 你還需要一個(gè)控制系統(tǒng),能夠讓這些模塊互相配合,協(xié)同工作。
- 由于大家都按照一個(gè)標(biāo)準(zhǔn)來(lái)開(kāi)發(fā),這些模塊很容易被組裝到一起,進(jìn)行管理和控制。
- 這樣,你們實(shí)現(xiàn)了一個(gè)汽車(chē)。
這里的一個(gè)功能模塊,就是一個(gè)組件,用來(lái)控制組件協(xié)作運(yùn)行的系統(tǒng),就是組件框架。
組件框架需要解決的幾個(gè)問(wèn)題:
- 如何發(fā)現(xiàn)組件
- 如何管理組件的生命周期
- 如何組件間調(diào)用
- 提供的公共基礎(chǔ)能力
怎么選擇組件化方案?
組件化的落地方案很多,我們?cè)趺催x擇適合自己的技術(shù)方案?
業(yè)界的組件化方案很多,例如windows下的com組件,andriod下的ARouter組件,基于消息總線(xiàn)的ths組件,千牛自研的prg::com組件,還有一些基于rpc框架,更寬泛意義上組件化(微服務(wù))。
在我看來(lái),組件化方案沒(méi)有最好的,只有相對(duì)合適的。根據(jù)業(yè)務(wù)場(chǎng)景,選擇一個(gè)滿(mǎn)足當(dāng)前業(yè)務(wù)需要,又能適當(dāng)照顧到未來(lái)發(fā)展需要,好用好維護(hù)的方案就可以。
這里提供一些組件化方案選型一些可參考的維度:
- 發(fā)現(xiàn)機(jī)制
- 通信機(jī)制
- 跨平臺(tái)
- 跨編程語(yǔ)言
- 維護(hù)成本
- 研發(fā)效率
- 編譯依賴(lài)
- 性能
- 穩(wěn)定性
在跨端千牛的場(chǎng)景下,我們的訴求優(yōu)先級(jí)是:
- 首先必須是支持跨平臺(tái)的,
- 其次是良好的可維護(hù)性,長(zhǎng)期來(lái)看,可維護(hù)性對(duì)產(chǎn)品質(zhì)量、效能和研發(fā)體驗(yàn)都影響深遠(yuǎn)。
- 然后是良好的性能和穩(wěn)定性,
- 最后是較好的研發(fā)效能和研發(fā)體驗(yàn)。
這里我們主要對(duì)比了ths組件和prg::com組件方案:
- ths組件:ths方案類(lèi)似于一個(gè)rpc調(diào)用框架,所有調(diào)用以消息的形式在總線(xiàn)上傳遞,其運(yùn)行時(shí)隔離&有中心節(jié)點(diǎn)切面,但其接口可維護(hù)性較差,無(wú)法在編譯期發(fā)現(xiàn)問(wèn)題。ths方案更適合跨團(tuán)隊(duì)場(chǎng)景,或開(kāi)放場(chǎng)景。
- prg::com組件:prg::com組件類(lèi)似于微軟的com組件,但它支持了跨平臺(tái),并對(duì)com接口調(diào)用方式進(jìn)行了優(yōu)化,調(diào)用方便。其接口的可維護(hù)性較佳,編譯時(shí)就可以發(fā)現(xiàn)接口兼容性問(wèn)題,性能也非常不錯(cuò),十分適用于團(tuán)隊(duì)內(nèi)部的組件化場(chǎng)景。
最終我們選用了自研的prg::com作為跨端框架組件化的技術(shù)方案,下面具體介紹一下這個(gè)方案。
跨端組件化實(shí)踐
組件化方案,包含框架能力和組件約束兩部分。
框架設(shè)計(jì)是否科學(xué),組件約束下是否易開(kāi)發(fā)、易使用、易維護(hù),是組件化方案要考量的核心因素。
- 組件框架,提供了組件運(yùn)行的基礎(chǔ)能力,主要包括:組件發(fā)現(xiàn)機(jī)制組件生命管理組件間通信其他公共基礎(chǔ)能力
- 組件約束,定義了組件開(kāi)發(fā)時(shí)需要遵循的標(biāo)準(zhǔn),其主要目的包括了:支持組件在prg框架上運(yùn)行,例如組件都繼承自prg::com對(duì)象,并需要完成I接口注冊(cè)。支持組件跨平臺(tái),例如ui組件需要遵守mvp分層,在替換ui渲染層時(shí),能確保做到業(yè)務(wù)邏輯多端一致。為了便于團(tuán)隊(duì)協(xié)作,例如文件結(jié)構(gòu)、代碼分層、命名規(guī)則等,使用相同范式去開(kāi)發(fā)和使用組件?!?/li>
組件約束是根據(jù)組件的類(lèi)型、具體使用場(chǎng)景等因素,分別進(jìn)行定義的,不同組件的標(biāo)準(zhǔn)并不完全相同。
例如ui組件和非ui組件的標(biāo)準(zhǔn)就有很大的不同。
后面介紹下prg框架,及我們?cè)诟鞣N場(chǎng)景下定義的組件約束條件。
? prg框架
- 組件發(fā)現(xiàn)機(jī)制
prg框架利用模板技術(shù),通過(guò)打包時(shí)掃描dll生成配置、加載dll時(shí)靜態(tài)注冊(cè)組件,實(shí)現(xiàn)了一套組件發(fā)現(xiàn)機(jī)制。
prg框架的組件發(fā)現(xiàn)機(jī)制,依賴(lài)于id注冊(cè),組件對(duì)外只暴露類(lèi)id和I接口,實(shí)現(xiàn)了組件間完全去依賴(lài)。
先來(lái)看一下示意代碼:
// 定義一個(gè)prg::com組件
class IxxxService;
DEFINE_IID(IxxxService, "{4E6A382D-1FDA-49C6-8521-E284DA7B71CC}")
DEFINE_CLSID(xxxService, "{D1A52645-7587-4885-ABFD-323BA62905F5}")
// 創(chuàng)建這個(gè)prg::com組件
scoped_refptr<IxxxService> spInterface;
prg::PrgCOMCreateInstance(c_uuidof(xxxService), spInterface);
//////////////////////////////////////////////////////////////////////////
// implement(不對(duì)外暴露)
class CxxxService
: public prg::CPrgCOMRootObject<prg::CCOMThreadSafeRefPolicy>
, public IxxxService
{
public:
DECLARE_PRGCOM_RUNTIME(CxxxService, c_uuidof(xxxService), "xxxService", "xxxService", prg::GetDependsCLSID())
BEGIN_PRGCOM_MAP(CxxxService)
PRGCOM_INTERFACE_ENTRY(IxxxService)
END_PRGCOM_MAP()
};
IMPLEMENT_PRGCOM_RUNTIME(CxxxService);
它的實(shí)現(xiàn)原理是:
- 打包時(shí),掃描目錄下所有dll,遍歷調(diào)用 GetPrgCOMFactory接口,生成組件配置xml。
- 創(chuàng)建對(duì)象時(shí),通過(guò)xml配置,找到并load對(duì)應(yīng)的dll。
- 加載dll時(shí),會(huì)創(chuàng)建prg::CPrgCOMObjectRuntime<T>靜態(tài)變量g_prgRuntime,并在構(gòu)造時(shí)向PrgCOMFactory注冊(cè)clsid到this的映射關(guān)系。
- 根據(jù)clsid,在PrgCOMFactory中找到對(duì)應(yīng)的g_prgRuntime變量,調(diào)用CreateInstance靜態(tài)方法,由于g_prgRuntime變量是帶了T類(lèi)型信息的,就可以創(chuàng)建出對(duì)應(yīng)的T對(duì)象。
這里利用了c++模版技術(shù)和靜態(tài)注冊(cè)技術(shù),巧妙地完成組件解耦,解決了依賴(lài)問(wèn)題和跨模塊調(diào)用問(wèn)題。
- 組件生命管理
prg組件支持無(wú)感跨模塊創(chuàng)建、使用、釋放對(duì)象,真正做到了一次開(kāi)發(fā),到處使用,開(kāi)箱即用。
prg組件使用scoped_refptr引用計(jì)數(shù)管理內(nèi)存,使用者不需要自行管理內(nèi)存。
prg框架支持跨dll/dylib創(chuàng)建、使用、釋放對(duì)象,對(duì)使用者來(lái)說(shuō)dll/dylib是完全無(wú)感的,指定要?jiǎng)?chuàng)建的對(duì)象類(lèi)型,接口類(lèi)型,實(shí)例名稱(chēng),就可以直接開(kāi)始使用這個(gè)接口了,非常絲滑。
class IxxxService : public prg::IPrgCOMRefCounted
{
public:
base::event<void()> onDataChanged;
public:
virtual bool GetData(const std::string& data) = 0;
}
// 創(chuàng)建prg::com組件新實(shí)例
scoped_refptr<IxxxService> spInterface;
prg::PrgCOMCreateInstance(c_uuidof(xxxService), spInterface);
// 獲取prg::com組件(沒(méi)有則create,prg框架內(nèi)部會(huì)保存一份引用)
scoped_refptr<IxxxService> spInterface;
prg::PrgCOMGetInstance(c_uuidof(xxxService), instanceName, spInterface);
// 判斷prg::com組件實(shí)例是否存在
prg::PrgCOMHasInstance(c_uuidof(xxxService), instanceName, bhave);
// 刪除prg::com組件實(shí)例
prg::PrgCOMDropInstance(c_uuidof(xxxService), instanceName);
我們一般會(huì)將組件獲取封裝成像下面這樣的接口,對(duì)于使用者來(lái)說(shuō),調(diào)接口就像調(diào)用自己的代碼一樣方便。
/// 組件頭文件
inline scoped_refptr<IxxxService> GetIxxxService()
{
scoped_refptr<IxxxService> spInterface;
prg::PrgCOMGetInstance(c_uuidof(UIAppGuideWidget), "", spInterface);
return spInterface;
}
/////////////////////////////////////////////////////////////////////////
// 其他組件直接調(diào)用接口
std::string data;
GetIxxxService()->GetData(data);
- 組件間通信
prg組件的接口調(diào)用和事件訂閱。
接口調(diào)用
prg組件接口調(diào)用與com組件類(lèi)似,區(qū)別在于prg::com做了更好用的封裝,可以直接get到I接口對(duì)象進(jìn)行使用。(當(dāng)然還是支持使用QueryInterface,可以通過(guò)QueryInterface獲得不同類(lèi)型的I接口)
class IxxxService : public prg::IPrgCOMRefCounted
{
public:
base::event<void()> onDataChanged;
public:
virtual bool GetData(const std::string& data) = 0;
}
// 獲取組件
scoped_refptr<IxxxService> spInterface;
prg::PrgCOMGetInstance(c_uuidof(xxxService), instanceName, spInterface);
// 調(diào)用組件方法
spInterface->GetData(callback);
事件訂閱
事件訂閱派發(fā),依賴(lài)base::event實(shí)現(xiàn),是典型的觀察者模式。當(dāng)事件觸發(fā)時(shí),按照注冊(cè)順序挨個(gè)調(diào)用觀察者的base::callback,可以非常容易的完成復(fù)雜流程串聯(lián)。這里的event是實(shí)例級(jí)別的,配合prg的賬號(hào)隔離能力,可以很好的解決多賬號(hào)業(yè)務(wù)的事件派發(fā)問(wèn)題。但目前base::event暫不支持按優(yōu)先級(jí)注冊(cè)派發(fā)。
class IxxxService : public prg::IPrgCOMRefCounted
{
public:
base::event<void()> onDataChanged;
public:
virtual bool GetData(const std::string& data) = 0;
}
// 獲取組件
scoped_refptr<IxxxService> spInterface;
prg::PrgCOMGetInstance(c_uuidof(xxxService), instanceName, spInterface);
// 訂閱組件事件
CBaseEventHelper::RegisterEvent(spInterface->onDataChanged, callback);
// 取消訂閱組件事件
CBaseEventHelper::UnRegisterEvent(spInterface->onDataChanged);
? prg框架的組件約束
prg::com組件要遵循什么約束條件?
不同類(lèi)型的組件,標(biāo)準(zhǔn)是不一樣的,要說(shuō)組件標(biāo)準(zhǔn),首先要對(duì)組件進(jìn)行分類(lèi)。
以阿里旺旺應(yīng)用為例,跨端旺旺包含的組件,大致可以分成以下幾類(lèi):
框架層:
- ali系pc應(yīng)用基礎(chǔ)組件
- 平臺(tái)相關(guān)基礎(chǔ)組件
框架和基礎(chǔ)組件,是阿里系pc應(yīng)用基座,這些組件由prg框架內(nèi)置,從而實(shí)現(xiàn)快速搭建pc跨端應(yīng)用的能力。
應(yīng)用層:
- 旺旺業(yè)務(wù)-非UI組
- 旺旺業(yè)務(wù)-UI組件
應(yīng)用層組件,主要用來(lái)實(shí)現(xiàn)業(yè)務(wù)功能,這部分組件經(jīng)常要進(jìn)行擴(kuò)展和修改,是我們要重點(diǎn)關(guān)注的。
應(yīng)用層組件,根據(jù)其技術(shù)實(shí)現(xiàn),又可以分成ui相關(guān)和ui無(wú)關(guān)兩種,ui組件會(huì)相對(duì)更加復(fù)雜。
(ps:UI組件上采用pv分層,p層負(fù)責(zé)控制界面邏輯,使用純c++實(shí)現(xiàn),view層只負(fù)責(zé)繪制和操作輸入,這樣在最大程度復(fù)用代碼,提高效率的同時(shí),保證業(yè)務(wù)雙端一致。我們的ui組件都遵從這個(gè)標(biāo)準(zhǔn)。我們選用了Qt作為跨端UI框架,我們發(fā)現(xiàn),Qt并不能做到UI功能完全跨端,考慮到后續(xù)替換UI框架或適配新平臺(tái)的可能性,我們把Qt的使用范圍收斂在UI渲染部分,即view層。)
prg組件通用標(biāo)準(zhǔn)
prg::com組件基本標(biāo)準(zhǔn),所有的prg組件都遵守。
每個(gè)prg組件,都以…Service命名,以 I…Service接口的方式對(duì)外暴露,在C…Service里實(shí)現(xiàn)。
Service概念:Service即是prgcom組件,是客戶(hù)端內(nèi)的獨(dú)立業(yè)務(wù)單元,是對(duì)獨(dú)立業(yè)務(wù)能力的抽象。
接口:IxxxService(在biz/interface目錄,IxxxService.h文件)
實(shí)現(xiàn):CxxxService(在biz/xxx/service目錄)
獲取實(shí)例:GetxxxService()
使用方法:
- 所有prg組件對(duì)外提供服務(wù)的方式是統(tǒng)一的。
- 使用者可以通過(guò)GetxxxService()接口獲取到prg組件實(shí)例,然后通過(guò)IxxxService提供接口和事件使用組件。
- 組件內(nèi)部實(shí)現(xiàn)CxxxService不對(duì)外暴露。
非UI組件標(biāo)準(zhǔn)
不包含ui界面的組件,平臺(tái)差異影響較小,內(nèi)部按業(yè)務(wù)需要設(shè)計(jì),遵守prg組件基本標(biāo)準(zhǔn)即可。
- UI組件標(biāo)準(zhǔn)
跨端ui組件的標(biāo)準(zhǔn),主要包括了mvp分層,ui生命周期管理,以及各種場(chǎng)景下的多ui組合等。
ui組件依然遵從prg組件的通用標(biāo)準(zhǔn),也支持prg組件的所有特性。
Service:是一個(gè)prgcom組件對(duì)象,外部使用ui組件時(shí),直接操作service,就像使用非ui組件一樣。
UI:是界面整體,ui里包含presenter、view, 這里ui和view要區(qū)分清楚。
Presenter:是界面的邏輯對(duì)象,p層控制了所有業(yè)務(wù)邏輯,也控制view的輸入輸出。
View:是界面的渲染對(duì)象,只負(fù)責(zé)界面渲染和用戶(hù)操作輸入。
在prg框架下,A組件調(diào)用組件B的UI接口:
ui組件的復(fù)雜性:
- 不同平臺(tái)下的ui機(jī)制不相同,界面風(fēng)格和操作習(xí)慣也不同,如何確保雙端業(yè)務(wù)邏輯一致?
- ui對(duì)象的生命周期一般由ui框架內(nèi)部管理,如何確保ui組件的生命周期管理不出問(wèn)題?
- 如果一個(gè)組件里,包含多個(gè)ui怎么處理?多個(gè)ui之間并列關(guān)系怎么處理,嵌套關(guān)系又怎么處理?
- ui組件的場(chǎng)景太多,光標(biāo)準(zhǔn)定義就很復(fù)雜,如何在實(shí)際項(xiàng)目中落地實(shí)施?
mvp分層結(jié)構(gòu)
為了更好的維護(hù)和復(fù)用ui組件,并滿(mǎn)足跨端訴求,我們的ui組件都采用mvp模式進(jìn)行開(kāi)發(fā)。
ui組件除了遵從prgcom的標(biāo)準(zhǔn)之外,還需遵守額外的約束:
- 每個(gè)UI界面內(nèi)部,分為p-v兩層,其中p層負(fù)責(zé)邏輯控制,v層負(fù)責(zé)輸入輸出。
- 每個(gè)UI界面,開(kāi)放一個(gè)IxxxUI接口,IxxxUI代表UI界面整體,內(nèi)部只包含一個(gè)GetPresenter()方法。
- p層開(kāi)放一個(gè)IxxxPresenter接口,外部調(diào)用IxxxPresenter提供的方法來(lái)操作這個(gè)UI界面。
- p層定義了v層需實(shí)現(xiàn)的輸入輸出接口IxxxUIDelegate,這個(gè)接口由v層代理實(shí)現(xiàn),只在p層可見(jiàn)。
- v層只負(fù)責(zé)實(shí)現(xiàn)渲染和輸入用戶(hù)操作。
這種設(shè)計(jì)的好處,主要在于:
- 所有的邏輯由p定義和控制,p層由c++實(shí)現(xiàn),可以實(shí)現(xiàn)跨多端,mac和windows統(tǒng)一。
- view被收斂在內(nèi)部,僅實(shí)現(xiàn)了輸入輸出接口,非常輕量。view相關(guān)的對(duì)象(如QT對(duì)象)不會(huì)擴(kuò)散。
- 替換view簡(jiǎn)單,只需重新實(shí)現(xiàn)UIDelegate接口。
- 可以通過(guò)實(shí)現(xiàn)UIDelegate接口的mock,在p層做單元測(cè)試。
生命周期管理
ui組件的生命周期比一般組件復(fù)雜,因?yàn)閡i組件有一部分對(duì)象的生命周期是ui框架來(lái)管理的。
買(mǎi)旺跨端框架,ui選型是Qt框架,ui對(duì)象生命周期由Qt內(nèi)核管理,而組件生命周期是prg內(nèi)核管理。
當(dāng)創(chuàng)建ui對(duì)象后,組件保存了ui對(duì)象的指針,以便和ui對(duì)象做業(yè)務(wù)交互,但ui對(duì)象的生命周期是qt內(nèi)部管理的。
因此,需要建立一種機(jī)制,當(dāng)Qt銷(xiāo)毀ui對(duì)象的時(shí)候,需要通知到我們的組件這個(gè)ui對(duì)象已經(jīng)被銷(xiāo)毀了。
創(chuàng)建和調(diào)用流程:
銷(xiāo)毀流程:
各種UI界面的處理
單個(gè)UI界面
多個(gè)平級(jí)UI界面
父子UI界面
多層UI界面嵌套下的接口調(diào)用
由于嵌套層級(jí)太多,每一層都要開(kāi)接口傳遞,會(huì)帶來(lái)大量工作量,因此提供泛化接口傳遞的解決方案。
可參考案例IAliwangwangChatBase.h的實(shí)現(xiàn),完成接口傳遞。
組件代碼自動(dòng)生成?
跨平臺(tái)、標(biāo)準(zhǔn)化、低耦合,往往意味著編碼更加繁瑣,也意味著難以落地。
舉個(gè)例子,假如我在組件A要去操作組件B,顯示一個(gè)對(duì)話(huà)框,我需要寫(xiě)的代碼有:
- IxxBService 組件接口
- CxxBService 組件實(shí)現(xiàn)
- IxxBPresenter P層接口
- CxxBPresenter p層實(shí)現(xiàn)
- IxxBPresenter::IxxBViewDelegate p層定義的ViewDelegate接口
- CxxBView view層實(shí)現(xiàn)
要在6個(gè)對(duì)象里寫(xiě)代碼,這簡(jiǎn)直就是一個(gè)災(zāi)難!?。〉强紤]到長(zhǎng)期的可維護(hù)性、跨平臺(tái),又必須這么做。
于是,我們開(kāi)發(fā)了一個(gè)代碼生成工具,根據(jù)上面各種情況下的ui關(guān)系,可以從模板自動(dòng)生成組件代碼。
由于篇幅限制,這里不具體展開(kāi)。
? 產(chǎn)生的效果
這套跨端組件化方案,已在跨端千牛/跨端旺旺產(chǎn)品中落地,目前雙產(chǎn)品三端已經(jīng)發(fā)布上線(xiàn)。
(目前win千牛功能 > 跨端千牛,跨端千牛的win版本尚未發(fā)布,敬請(qǐng)期待)
- 雙端完全一致的使用體驗(yàn),完全復(fù)用相同業(yè)務(wù)邏輯代碼。
- 雙端開(kāi)發(fā)成本天然降低一半。
- 適合團(tuán)隊(duì)協(xié)作,組件分拆,協(xié)同開(kāi)發(fā)的效率高。
- 組件間完全解耦,可維護(hù)性大大增強(qiáng)。一次開(kāi)發(fā),到處使用,簡(jiǎn)單方便。
- 可用工具自動(dòng)生成組件代碼,只需關(guān)注業(yè)務(wù)邏輯,效率高,風(fēng)格一致。
- 集成了大量集團(tuán)基礎(chǔ)能力,沉淀了pc跨端應(yīng)用組件化框架,提供快速搭建阿里系pc應(yīng)用能力。
再回到我們選擇這個(gè)方案時(shí)的目標(biāo),
- 首先是支持跨平臺(tái),
- 其次是可維護(hù)性、擴(kuò)展性,長(zhǎng)期來(lái)看,可維護(hù)性對(duì)產(chǎn)品質(zhì)量、效能和研發(fā)體驗(yàn)都影響深遠(yuǎn)。
- 然后是良好的性能和穩(wěn)定性,
- 最后是較好的研發(fā)效能和研發(fā)體驗(yàn)。
目前來(lái)看,prg組件框架在前3點(diǎn)上表現(xiàn)出色,在第4點(diǎn)研發(fā)體驗(yàn)上,由于跨多端的嚴(yán)苛要求,ui組件分層較多,開(kāi)發(fā)略顯繁瑣,我們通過(guò)自研組件代碼生成工具,緩解了這一問(wèn)題。
總的來(lái)說(shuō),prg組件跨端框架可以在未來(lái)的3-5年里,很好的支撐起千牛/旺旺,甚至其他阿里系pc應(yīng)用的業(yè)務(wù)。
跨端組件框架的演進(jìn)思考
? 技術(shù)基礎(chǔ)能力完善
框架基礎(chǔ)能力,例如支持事件訂閱優(yōu)先級(jí)、支持組件鏈路/性能監(jiān)控、增加基礎(chǔ)能力組件等。
ui組件單元測(cè)試能力,ui組件都是pv結(jié)構(gòu)的,ui邏輯都在p層,用簡(jiǎn)單的uidelegate即可串聯(lián)ui邏輯,實(shí)現(xiàn)ui單元測(cè)試。
研發(fā)效能和研發(fā)體驗(yàn),完善代碼模板和自動(dòng)化工具 ,實(shí)現(xiàn)接口級(jí)別代碼自動(dòng)生成/補(bǔ)全,進(jìn)一步提升研發(fā)效率和研發(fā)體驗(yàn)。
? 業(yè)務(wù)上可能的嘗試
走向業(yè)務(wù)的組件化
組件化不光是技術(shù)概念,也是業(yè)務(wù)概念。復(fù)用帶來(lái)了低成本和一致性,解耦則帶來(lái)了業(yè)務(wù)的靈活性。
組件在技術(shù)上的靈活復(fù)用,能帶來(lái)的是業(yè)務(wù)上的靈活組合,快速?lài)L試。
例如旺旺系的IM能力,它可以是獨(dú)立的阿里旺旺產(chǎn)品,也可以集成到千牛里。組件就是積木,更多從業(yè)務(wù)角度去思考,提供更多更好用的積木,業(yè)務(wù)就能快速搭建出一個(gè)新大樓。
- 共享、共建pc組件庫(kù)
組件化不局限于團(tuán)隊(duì)內(nèi),大家一起共享、共建的pc業(yè)務(wù)組件庫(kù),才是更大程度發(fā)揮出組件化的價(jià)值。
希望pc業(yè)務(wù)越來(lái)越好!
團(tuán)隊(duì)介紹
我們是大淘寶技術(shù)部行業(yè)與商家技術(shù)跨終端技術(shù)團(tuán)隊(duì),業(yè)務(wù)上負(fù)責(zé)為千萬(wàn)級(jí)商家打造最高效的一站式工作臺(tái)千牛,為淘寶上億商家和消費(fèi)者提供穩(wěn)定高效的端到端消息IM服務(wù);技術(shù)上深耕C++跨終端及PC桌面端技術(shù)(Windows&Mac),為商家,消費(fèi)者提供穩(wěn)定,可靠,高效的客戶(hù)端產(chǎn)品。