開發框架學習篇之MVP

今天學習開發框架MVP,對比於MVC ,

優點:activity,fragment,代碼變得簡潔優美,不像在MVC中,一個activity,fragment少則300,500行,多則幾千行代碼,便於後期維護。view層不再直接和model接觸了,相應的邏輯(比如網絡請求,數據運算)都交給 presenter,model層來做,view只負責界面繪製。方便寫單元測試。

缺點:從MVC轉至MVP學習有一定成本,對於小型項目,完全沒有這個必要,MVC就足夠了。舉個簡單例子,如果要編寫一個演示dmeo從assets文件中取數據並顯示出來,這樣的需求,在MVC中1~2個java文件(很多時候activity扮演的是V、C)就搞定了,MVP卻需要3個文件。

下面直接上代碼吧


這是我的工程目錄V層將通過 activity和 fragment兩個來展示,下面分別介紹

public class CalculateTwoNumbers {
    public int n1, n2;

    public int addResult() {
        return n1 + n2;
    }

    public int subtractResult() {
        return n1 - n2;
    }

    public int multiplyResult() {
        return n1 * n2;
    }

    public double divideResult() {
        return n1 / n2;
    }
}
這是一個計算四則運算的model,這裏我沒有用到 set/get 方法,是因爲性能的原因(某大神建議在有內聯的場景下android中直接訪問變量比通過set/get方法訪問變量效率高些)。這樣的代碼結構很容易編寫測試用例的,代碼如下:

public class CalculateTwoNumbersTest extends TestCase {
    CalculateTwoNumbers calculateTwoNumbers = new CalculateTwoNumbers();
    public void testAddResult() throws Exception {
        calculateTwoNumbers.n1 = 4;
        calculateTwoNumbers.n2 = 8;
        assertEquals(12,calculateTwoNumbers.addResult());
    }

    public void testSubtractResult() throws Exception {
        calculateTwoNumbers.n1 = 4;
        calculateTwoNumbers.n2 = 8;
        assertEquals(-4,calculateTwoNumbers.subtractResult());
    }

    public void testMultiplyResult() throws Exception {
        calculateTwoNumbers.n1 = 4;
        calculateTwoNumbers.n2 = 8;
        assertEquals(32,calculateTwoNumbers.multiplyResult());
    }

    public void testDivideResult() throws Exception {
        calculateTwoNumbers.n1 = 14;
        calculateTwoNumbers.n2 = 8;
        assertEquals(1.0,calculateTwoNumbers.divideResult());
    }
}
說完了model層,接着我們看看presenter層代碼

public interface ICalculate {
    void mathAdd(int n1, int n2);

    void mathSubtract(int n1, int n2);

    void mathMultiply(int n1, int n2);

    void mathDivide(int n1, int n2);

    void clear();
}
public class CalculatePresenter implements ICalculate {
    private IResult iResult;
    private CalculateTwoNumbers calculateTwoNumbers;

    public CalculatePresenter(IResult iResult) {
        this.iResult = iResult;
        calculateTwoNumbers = new CalculateTwoNumbers();
    }

    public void initUser(int n1, int n2) {
        calculateTwoNumbers.n1 = n1;
        calculateTwoNumbers.n2 = n2;
        mathAdd(n1, n2);
        mathSubtract(n1, n2);
        mathMultiply(n1, n2);
        mathDivide(n1, n2);
    }

    @Override
    public void mathAdd(int n1, int n2) {
        if (iResult != null) {
            iResult.showAdd(calculateTwoNumbers.addResult());
        }
    }

    @Override
    public void mathSubtract(int n1, int n2) {
        if (iResult != null) {
            iResult.showSubtract(calculateTwoNumbers.subtractResult());
        }
    }

    @Override
    public void mathMultiply(int n1, int n2) {
        if (iResult != null) {
            iResult.showMultiply(calculateTwoNumbers.multiplyResult());
        }
    }

    @Override
    public void mathDivide(int n1, int n2) {
        if (iResult != null) {
            iResult.showDivide(calculateTwoNumbers.divideResult());
        }
    }

    @Override
    public void clear() {
        if (iResult != null) {
            iResult = null;
        }
    }
}
CalculatePresenter負責將model運算的結果傳遞給view層,即本工程中的 MVPActivity,MVPFragment。

在activity和fragment中顯示數據

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.mvp_view_result);
    ButterKnife.bind(this);
    calculatePresenter = new CalculatePresenter(this);
}

@OnClick({R.id.btn_calculate})
void calculate() {
    if (TextUtils.isEmpty(etNumber1.getText().toString().trim()) || TextUtils.isEmpty(etNumber2.getText().toString().trim())) {
        showToastShort("please input numbers");
        return;
    }
    if (calculatePresenter != null) {
        calculatePresenter.initUser(Integer.valueOf(etNumber1.getText().toString().trim()), Integer.valueOf(etNumber2.getText().toString().trim()));
    }
}

@Override
protected void onDestroy() {
    calculatePresenter.clear();
    ButterKnife.unbind(this);
    super.onDestroy();
}

@Override
public void showAdd(int result) {
    LogUtils.d("add: " + result);
    showToastShort("add: " + result);
    tvAdd.setText("add: " + result);
}

@Override
public void showSubtract(int result) {
    LogUtils.d("subtract: " + result);
    showToastShort("subtract: " + result);
    tvSubtract.setText("subtract: " + result);
}

@Override
public void showMultiply(int result) {
    LogUtils.d("multiply: " + result);
    showToastShort("multiply: " + result);
    tvMultiply.setText("multiply: " + result);
}

@Override
public void showDivide(double result) {
    LogUtils.d("divide: " + result);
    showToastShort("divide: " + result);
    tvDivide.setText("divide: " + result);
}
這裏要注意的是在activity中調用CalculatePresenter clear()方法解除綁定,和fragment中調用該方法解除綁定時有點小區別,MVPFragment中因爲存在綁定的按鈕點擊事件,在銷燬fragment時要解除綁定的 點擊事件,不然會造成內存泄漏。

完整代碼地址

點擊打開鏈接

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