开发框架学习篇之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时要解除绑定的 点击事件,不然会造成内存泄漏。

完整代码地址

点击打开链接

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