從MVC到MVP,記一次代碼重構

前言

手底下一直在做一個項目,從交互看起來也沒怎麼複雜,但由於歷史原因,底下有二十多個依賴工程,到目前我也沒有把依賴工程具體的東西搞明白。在代碼裏邊偶爾能看到13年的記錄,也經過了無數人的手。代碼的邏輯結構非常混亂,也許是修修補補太多了吧。哈哈,幾年後如果有人接手是不是也會這麼說我。這次迭代交互和視覺要進行一次大的改版,新的交互改變了整體的框架,所以也就乘此機會,一邊重構,一邊修改新的交互。到目前以進行一個半月,再此過程中感謝我的同事浪平哥的指導。本篇不講MVP的細節,只是簡單的說說這次重構的一些體會,鄙人愚鈍,不當之處,敬請賜教。

認識MVP

發現Android出現的一些新技術會在各種博客、微信公衆號瞬間擴散,在各大網站也會有更新。MVP已經在很久前出現了,有幸有機會能夠在項目中實戰,網上有許多的教程,還有官方的Demo,在此就不做深入分析了,僅談一談自己的理解。

MVC和MVP

MVC是我們之前的開發中一直用的開發模式,這種開發模式結構簡單,開發速度快,代碼量少。但是View和Contrl基本都在Activity中完成,造成項目中的Activity乾的事情太多,邏輯混亂,可讀性差。數據和UI糾結在一起,在迭代過程中不好修改。就像拉着一輛破車跑,實在是讓人舉步維艱。MVP的優勢在於讓數據和UI分離,V層只管UI的顯示操作,M層按照業務劃分,根據不同業務有對應不同的model完成網絡訪問、數據庫讀取等所欲的數據操作。P層是一個協調者的角色,他將從M層拿到數據,並協調分配給不同的UI,完成在界面上指定控件顯示指定的數據。這樣分工更加明確,業務之間耦合少,方便修改。

MVP最簡模型

  • Entity

    public class Monkey(){
        private name;
        set***
        get***
    }
    
  • M層

    public class Model{

    public Monkey getData(){
        Monkey monkey=new Monkey();
        //也許是訪問數據庫或者網絡等複雜的操作
        monkey.setName("code");
        return monkey;
    }
    

    }

  • P層

    public class Presenter{
        private mIView;
        private mModel;
        public Presenter(){
            mModel=new Model();//初始化一個model
        }
        public attachView(IView view){
            mIView=view;
        }
        public string initData(){
            return mModel.getData().getName();
        }
        public void showView(){
            mIView.show();
        }
    }
    
  • V層

    public interface IView{
        void show();
    }
    
    public class TestActivity extends Activity implements IView{
        private TextView mTextview;//UI
        private String mName;//數據
        private Presenter mPresenter;
    
    
        protect void onCreate(){
            mTextView=(TextView)findeById(R.id.xxx);
            mPrsenter=new Presenter();
            mPrsenter.attchView(this);
            mName=mPresenter.initData();
            mPrsennter.showView();
        }
        public void show(){
            mTextView.setText(mName);
        }
    
    }
    

    上述還有許多就沒有表現出來,比如當Activity銷燬的時候,應該調用Presenter的一個destory的方法銷燬P層,同樣的在M層中也要寫一個destory的方法供P層調用進行銷燬操作,這裏一可以避免數據混亂,二也是清除緩存數據,釋放內存。還有比如,我們大部分複雜一點的UI控件的顯示或者隱藏等和數據有關,這個時候我們就要把基礎的數據通過P層交給UI,將與UI相關的數據暴露在UI層中,這UI層中進行判斷等操作。如果需要進行異步加載數據,可以採用回調的方式將數據返回到UI層;

重構之路

原代碼分析

重構前接手項目有一兩個月的時間,緊張的迭代進度並沒有給我許多的時間去熟悉代碼,中間由於項目的迭代計劃出現一些問題,這個空餘的時間給了我熟悉代碼的機會,然而到後邊真正重構的時候才發現做了許多的無用功。

  • 快速熟悉代碼的方法
    • 首先從UI分析,可以用邏輯結構圖畫出來,每個模塊有哪些界面,這些界面對應的Activity,fragment是哪個,以便後邊看一目瞭然;
    • 使用Debug調試,在有操作的等關鍵的地方打好點,一步步調試,看看程序是怎麼跑的;
    • 再爛的代碼都會有他的套路,而且這個套路運用在整個程序各個地方的開發之中,我經歷的項目並不是很多,但是這個問題想想也能確定。所以,如果你對這個套路搞清楚了,這個程序在你的面前就會變得透明的,是一堆骨架。
  • 需要輸出的文檔
    • 功能結構圖,也就是上面說的UI界面對應的Acitivty和Fragment;
    • 數據加載分析文檔,每個軟件必定會牽涉到數據,我這裏的數據加載不是網絡或者數據庫的原始數據,而是程序運行時數據的讀取、傳遞、計算等緩存的數據。我用的是用表格的形式,填寫了某一個實體類,實體類中包含的數據元素以及值。不過後來發現,這裏不要弄的太詳細,這裏邊的數據太複雜了。不要把太多的時間放在這裏,主要的目的在於把數據加載的過程瞭解清楚,重構的時候難免要動這一塊,不過真正動的時候再用Debug調試瞭解詳細信息就好了。

重構中的一些發現

  • 寫好基礎Model業務層

    在前期的準備工作中,分析得出某一些Model層業務是幾乎所有Model層公有的,這個時候我們要將一些公有的業務寫到一個基類裏邊。每個軟件都會有不同的模塊,然後我們可以在不同的模塊也寫一個基類,然後在具體的業務層的model中繼承這個基類就可以了,這樣節省了許多的代碼,也將業務分的更加清晰。

  • 分拆原有工具類方法到Model層

    在MVC模式的開發中,我們避免Activity中的代碼過多,常常將某一些共有的操作放到一個工具類中,比如數據庫的讀取,然後不同的Activity有不同的操作,這些都寫在一個工具類中,我們不好分辨誰是誰的。這些活都是由model層來乾的,我們可以通過Ctrl+G搜索這個工具類的每一個方法被誰調用了,然後分別將這些方法copy到對應的model層去。

  • 除了 if 記得也要寫好 else

    發現以前的代碼裏邊有許多容錯處理,比如常常做的是 if 某某某不等於null,然後才進行什麼操作,但是else就不管了,這樣出了問題好難查,如果我們程序寫的時候就在else 中拋出一個異常或者打一個log說明這種情況什麼爲null,出的什麼問題。這樣bug來了,找到問題也就是分分鐘的事情。爲什麼敢去重構代碼,這是一個高風險的活,因爲我在每個可能存在問題的地方都有Log說明,問題來了也好找。

  • 從不知何處下手到感覺這只是一個套路

    我的同事已經將一個獨立的新模塊完全用MVP模式寫的,爲了學習MVP模式,我這個模塊寫了一個demo,深刻覺得當無從下手的時候一定要讓自己動手。剛進行重構的時候,都不清楚該怎麼寫model,怎麼寫presenter,但是經過一段時間的改造,已經覺得沒有那麼有挑戰性了,我只是將代碼的邏輯結構進行了一些調整,基本寫的是一些框架性的東西,然後將原有的代碼copy進去,實現具體的細節。寫到後邊都覺得自己只是在進行一些體力勞動,也許是項目時間太緊,我沒有時間去優化,寫的過程中也感覺到有些地方還待改進。說的這麼多,主要是想說,重構不難,難在開頭。

  • 不要心急,逐步重構

    畢竟項目還處在迭代的計劃中,產品不可能讓我一直整代碼,所以這是一個逐步完成的工作,也許是我們原代碼實在太散了,得花點時間才動的了。不過此次重構也只是完成了大部分的模塊。所以重構也不是把代碼翻個底朝天,雖然我再做的時候有些地方實在無法忍受,給改造了。但是也得考慮時間已經風險,所以要注意要一步一步的蠶食,別大口吃,最後搞不完留一堆碎渣子。路漫漫其修遠兮,哈哈!

結語

項目的此次重構還有許多不完善的地方需要優化,MVC也好MVP也好,關鍵得讓你的工作變的高效,減少無用功。所以,從長遠出發,如果你的項目目前是一堆陳舊的代碼,是時候重構啦。對於一些項目,從MVC到MVP是一種進步,也是重新梳理程序邏輯的一次機會。重構確實要花一些精力,但是如果你不動他,那麼你永遠就是開着拖拉機跟賽跑,累死也不見效。算了,又水了一篇,哈哈,做爲一隻猿,碼碼字也算是本業啦。希望各位大神賜教。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章