前言
??前幾天去參加了一場面試。面試的題目大多很基礎(chǔ),有一道關(guān)于埋點(diǎn)的問題,面試官問我如果不用第三方SDK進(jìn)行埋點(diǎn),自己埋點(diǎn)的話,如何減少埋點(diǎn)對業(yè)務(wù)代碼的入侵。
??當(dāng)時(shí)沒想太多,就說創(chuàng)建一個(gè) BaseView 類,在這個(gè)類中進(jìn)行埋點(diǎn)的操作,然后使需要進(jìn)行埋點(diǎn)操作的 View 繼承這個(gè) Base 類。后來想想,這個(gè)方案其實(shí)存在很多問題,因?yàn)樽屆總€(gè)需要埋點(diǎn)的 View 去繼承 BaseView 類,說明 View 需要自定義,會耗費(fèi)很多的時(shí)間和精力,對于自帶的 Button 等控件的埋點(diǎn),這種方法又無法實(shí)現(xiàn)。所以說,其實(shí)在這個(gè)問題上,我答的不是很好,但可能之前的幾個(gè)問題答得不錯(cuò),面試官也沒說什么,就說行,然后繼續(xù)問下面的問題。
??對于埋點(diǎn),減少業(yè)務(wù)代碼入侵這個(gè)問題,我回來想了想,或許用代理模式來實(shí)現(xiàn),會是一個(gè)很好的選擇。
埋點(diǎn)
??先來說說埋點(diǎn)的概念,埋點(diǎn)就是在用戶使用APP時(shí),對用戶的操作行為進(jìn)行記錄,比如用戶點(diǎn)擊了一個(gè) Button 然后跳轉(zhuǎn)至了哪個(gè)界面,然后在這個(gè)界面上又點(diǎn)擊了哪個(gè)控件,等等等一系列操作進(jìn)行記錄,然后APP將行為記錄傳至后臺,這就是埋點(diǎn)。
??利用這些信息,可以對用戶進(jìn)行數(shù)字畫像,根據(jù)用戶的行為特點(diǎn),針對性地提供功能服務(wù),以及對軟件的優(yōu)化等?,F(xiàn)在市場上已經(jīng)有很多第三方的埋點(diǎn)SDK,比如說友盟的用戶行為數(shù)據(jù)檢測。

??這些第三方SDK,基本上不用對自己的業(yè)務(wù)代碼進(jìn)行改變,就可以進(jìn)行埋點(diǎn)的操作,而如果我們自己來實(shí)現(xiàn)埋點(diǎn)的話,基本上的思路就是,在用戶點(diǎn)擊控件的時(shí)候,對用戶這個(gè)行為進(jìn)行記錄,然后進(jìn)行一些信息處理操作,代碼來實(shí)現(xiàn)就是。
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//埋點(diǎn)操作
actionRecord();
//跳轉(zhuǎn)至另外一個(gè)界面
startActivity(new Intent(mContext,AnotherActivity.class));
}
});
??actionRecord() 里是一些埋點(diǎn)相關(guān)的操作,我們可以看到,這個(gè)操作已經(jīng)入侵到了我們的業(yè)務(wù)代碼中,埋的點(diǎn)如果少還好,如果有大量的點(diǎn)要埋,這種實(shí)現(xiàn)方式后期維護(hù)將變的十分困難,因此需要另外一種方法來實(shí)現(xiàn)。
??我們考慮使用代理模式的方式,因?yàn)槁顸c(diǎn)的操作基本上是對用戶的點(diǎn)擊事件進(jìn)行記錄,所以我們可以創(chuàng)建一個(gè) OnClickListener 的代理。
/**
* Created by chaochaowu on 2018/9/15.
*/
public class OnClickListenerProxy implements View.OnClickListener {
private View.OnClickListener listener;
public OnClickListenerProxy(View.OnClickListener listener) {
this.listener = listener;
}
@Override
public void onClick(View v) {
//埋點(diǎn)操作
actionRecord();
//調(diào)用在業(yè)務(wù)代碼中定義的 onClick 操作
listener.onClick(v);
}
private void actionRecord(){
//一些埋點(diǎn)的操作
}
}
??將埋點(diǎn)相關(guān)的操作全都放入這個(gè)代理類中,在業(yè)務(wù)代碼中,調(diào)用如下。
mButton.setOnClickListener(new OnClickListenerProxy(new View.OnClickListener() {
@Override
public void onClick(View v) {
//跳轉(zhuǎn)至另外一個(gè)界面
startActivity(new Intent(mContext,AnotherActivity.class));
}
}));
??可以發(fā)現(xiàn),業(yè)務(wù)代碼中沒有出現(xiàn)埋點(diǎn)相關(guān)的操作,我們由此減少了埋點(diǎn)操作對業(yè)務(wù)代碼的入侵,埋點(diǎn)的操作交由代理類實(shí)現(xiàn),如果我們需要對埋點(diǎn)操作進(jìn)行修改,只要對代理類中的方法進(jìn)行修改,而不需要去每個(gè)埋點(diǎn)的地方修改。
??以上便是減少埋點(diǎn)對業(yè)務(wù)代碼入侵的一種方式,不過,如果項(xiàng)目真的有埋點(diǎn)的需求,我會優(yōu)先考慮使用第三方(逃。
