本系列文章集合:從 MVP學(xué)習(xí)代碼封裝 (1) - 綜述
說在開始
看過上一篇文章的萌新們搪柑,應(yīng)該都熟悉了基本的代碼套路,上一篇文章中 基于 :base接口 - abs 基類 - 實現(xiàn)類的封裝套路索烹,這個不管放到哪里工碾,我們寫框架都基本是這個樣子,這是用來搭建框架的基本架構(gòu)的百姓,但是呢渊额,我們寫自己的框架畢竟是對某一類 / 一些功能的封裝,如何規(guī)劃好一個框架中功能呢垒拢,我們可是要實現(xiàn)易閱讀旬迹,易修改,易擴展的功能代碼的求类,況且要是需要實現(xiàn)的功能多的話奔垦,如何做好那可是個麻煩事啊。
通過本篇呢尸疆,我想讓給萌新們提供一個思路:使用模板設(shè)計模式椿猎,把單個功能抽象成一個模板接口,然后做具體邏輯實現(xiàn)仓技,由框架控制層創(chuàng)建/持有某個功能的具體實現(xiàn)鸵贬,既可以做到合理劃分功能到單一類,在框架控制層中也很容易做某個功能的實現(xiàn)類替換脖捻,代碼解耦了阔逼,也方便擴展替換了,而且最重要的是容易閱讀了地沮,修改起來方便很多的嗜浮,不會到頭來自己看不懂自己的代碼了羡亩。
所以說不論是框架封裝,但是最簡單的膽碼封裝危融,處處都體現(xiàn)出設(shè)計模式的思想應(yīng)用在里面畏铆,學(xué)好設(shè)計模式是我們的必須要做到的,我都認為設(shè)計模式是 java 基礎(chǔ)中的必會技能了吉殃。不熟悉的萌新們抓緊時間啦辞居,我也是最近才開始學(xué)習(xí)的,不足之處大家多留言啊蛋勺,歡迎打臉瓦灶。
話接上文
先來看看新的 UML 類圖,不得不承認我畫 UML 的水平實在是太 low 了抱完,另外我畫的就是個示意圖贼陶,類,接口里面方法沒寫全巧娱,詳細去看代碼:
- 模板代碼抽象的都是可變的部分碉怔,留下固定的部分。這里我們需要抽象出的模板代碼是針對 V 層生命周期中可以的部分禁添,具體我們需要針對 3中 View 類型:
- activity
- fragment
- view
這3種 view 類型撮胧,都有各自不同的生命周期函數(shù),所以我們需要抽象出3個模板接口:
- ILifecycleProxy 根接口老翘,用來指定泛型的
- interface IActivityLifecycleProxy extends ILifecycleProxy
- interface IFragmentLifecycleProxy extends ILifecycleProxy
- interface ICustomeViewLifecycleProxy extends ILifecycleProxy
具體的我們先抽象一個根接口 ILifecycleProxy 趴樱,這樣方面我們使用泛型,然后用具體的類型去替換酪捡。3個具體的接口分別對應(yīng)3種 view 類型
- 我們在 BasePersenter 這個 P 層的abs 基類中叁征,我們添加聲明周期類型的泛型,用 ILifecycleProxy 這個聲明周期根接口這個類型逛薇。
public abstract class BasePersenter<V extends IBaseView, L extends ILifecycleProxy>
- 我思考過后呢捺疼,決定把抽象出來的可變的view 中生命周期的代碼由 P 層對象來實現(xiàn),在 MVP 架構(gòu)中 P 層對象就是相當(dāng)于最外層的控制對象的永罚。然后根據(jù) View 類型的不同啤呼, P 層需要實現(xiàn)不同的生命周期接口,鑒于生命周期接口差別的巨大和合理的設(shè)計呢袱,我在這里根據(jù) View 類型一一對應(yīng)生成多個 P 層 abs 基類來適應(yīng) View 類型官扣。
大家注意泛型的使用,不同的 Persenter 類型在繼承 BasePersenter 時羞福,指定了不同的對應(yīng)的 view 類型的生命周期接口惕蹄,然后 Persenter 實現(xiàn)了這個生命周期接口。我們在具體的 Persenter 對象中的對應(yīng)生命周期方法中寫自己的邏輯即可,這里我的代碼也是演示性質(zhì)的卖陵,實際上是由缺漏的遭顶,大家根據(jù)實際需求去修改吧,生命周期函數(shù)太多了泪蔫。
- BaseActivityPersenter
public class BaseActivityPersenter<V extends BaseActivity> extends BasePersenter<V, IActivityLifecycleProxy> implements IActivityLifecycleProxy
- BaseFragmentPersenter
public class BaseFragmentPersenter<V extends BaseFragment> extends BasePersenter<V, IFragmentLifecycleProxy> implements IFragmentLifecycleProxy
- BaseCustomeViewPersenter
public class BaseCustomeViewPersenter<V extends BaseCustomeView> extends BasePersenter<V,ICustomeViewLifecycleProxy> implements ICustomeViewLifecycleProxy
- 在 V 層 abs 基類中棒旗,合適的地方初始化這個生命周期函數(shù)接口對象出來,然后在需要的生命周期函數(shù)中去執(zhí)行這個生命周期函數(shù)模版對象的相應(yīng)方法撩荣,我以Activity具個例子铣揉,更多的去看demo
public abstract class BaseActivity<V extends BaseActivity, P extends BaseActivityPersenter<V>> extends AppCompatActivity implements IBaseView {
private P mBasePersenter;
protected abstract P createPersenter();
private IActivityLifecycleProxy lifecycleProxy;
public P getPersenter() {
return mBasePersenter;
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBasePersenter = createPersenter();
mBasePersenter.attachView((V) this);
lifecycleProxy = getPersenter().createlLifecycleProxy();
// lifecycleProxy = (IActivityLifecycleProxy) Proxy.newProxyInstance(lifecycleProxy.getClass().getClassLoader(), lifecycleProxy.getClass().getInterfaces(), new NotNullnvocationHandler(lifecycleProxy));
lifecycleProxy.onCreate(savedInstanceState);
}
@Override
protected void onPause() {
lifecycleProxy.onPause();
super.onPause();
}
@Override
protected void onResume() {
lifecycleProxy.onResume();
super.onResume();
}
@Override
protected void onStop() {
lifecycleProxy.onStop();
super.onStop();
}
@Override
protected void onStart() {
lifecycleProxy.onStart();
super.onStart();
}
@Override
protected void onRestart() {
lifecycleProxy.onStart();
super.onRestart();
}
@Override
protected void onNewIntent(Intent intent) {
lifecycleProxy.onNewIntent(intent);
super.onNewIntent(intent);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
lifecycleProxy.onSaveInstanceState(outState);
super.onSaveInstanceState(outState);
}
@Override
public void onBackPressed() {
if (lifecycleProxy.onBackPressed()) {
return;
}
super.onBackPressed();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
lifecycleProxy.onRequestPermissionsResult(requestCode, permissions, grantResults);
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
lifecycleProxy.onActivityResult(requestCode, resultCode, data);
super.onActivityResult(requestCode, resultCode, data);
}
@Override
protected void onDestroy() {
lifecycleProxy.onDestroy();
if (mBasePersenter != null) {
mBasePersenter.detachView();
}
super.onDestroy();
}
}
這里我想說一下,我想用動態(tài)代理處理一下 IActivityLifecycleProxy 這個屬性餐曹,應(yīng)對這個對象意外為 null 時的情況老速,但是不知道為啥就是報錯,報類型轉(zhuǎn)換錯誤
最后
基本上代碼的思路就是這些了凸主,寫完之后,我又掠了掠了思路额湘,的確是對自己的代碼封裝水平提神很有幫助卿吐,程序員這一行真的是用大量的思考和練習(xí)時間堆積出來的。
具體來說代碼很簡單锋华,雖然看起來很簡單嗡官,但是在寫的時候可是報了不少錯啊,主要是聲明周期太多了毯焕,需要考慮在合適的點初始化代碼啊衍腥。
另外在思考時,我考慮 MVP 架構(gòu)是更應(yīng)該說是一種代碼書寫規(guī)范纳猫,一個 V 的就應(yīng)該對應(yīng)一個 P婆咸,P 在不同的 V 之間復(fù)用,這個是不切實際的芜辕,也是不符合設(shè)計規(guī)范的尚骄,不同的 V 之間實際是由大量差異的,對應(yīng) V 來說侵续,他的 P 就是專屬與自己的倔丈,這在 MVP 的設(shè)計來說就是這樣的。若是不同的 V 的 P 之間有相同的代碼邏輯状蜗,那也是把系相同的邏輯代碼再封裝成工具對象需五,而不是去思考如何復(fù)用 P 。所提體現(xiàn)在這里的是在具體的 V層對象時轧坎,傳入的 V 的泛型就是自己的類型宏邮,具體例子
public class NewsActivity extends BaseActivity<NewsActivity, NewsActivityPersenter> implements INewsView
NewsActivity 中,之前 V 的泛型使用的具體的 INewsView 這個業(yè)務(wù)接口,這個業(yè)務(wù)接口是繼承的 V 層根接口 IBaseView的蜀铲,現(xiàn)在我們直接傳自己就可以边琉,因為對于 P 來說,我只需要針對一個類型 V 的就行记劝,沒機會在 V 直接復(fù)用变姨,在實際使用中 V,可以會實現(xiàn)大量業(yè)務(wù)接口厌丑,這樣做我們在 P 層寫具體業(yè)務(wù)邏輯時會省略 V 對象在不同業(yè)務(wù)接口之間來回強轉(zhuǎn)類型定欧。
代碼部分是demo 中 step2_1 這部分。
最后是項目地址: BW-MVPDemo