Android 从MVP说起

来源:互联网 发布:淘宝店被永久封了 攻略 编辑:程序博客网 时间:2024/06/07 02:58

软件设计模式

我们先来定义什么是好的软件架构:

  1. 软件架构上具有明确的分工,各个模块的功能职责平衡分配,且明确。
  2. 可测试性,通常良好的软件架构都具备良好的可测试性。
  3. 良好的易用性,维护成本低。

为什么需要模块分工?

良好的模块分工,可以大大简化我们对代码的理解难度。虽然通过大量的开发工作,可以训练我们的大脑去分析越来越复杂的逻辑,但是人总有极限,而且简单的逻辑更容易理解、不容易出错,所以,遵循单一职责原则,将复杂的业务逻辑分解。

为什么需要良好的可测试性?

对于深知单元测试好处的开发者来说,这并不是一个问题。单元测试可以大大地减少程序运行时才能发现的问题,这通常可以节省「奔溃收集、用户反馈」->「Bug修复」->「新版本发布」->「用户安装新版本」这个耗时长达一周以上的过程。所以,程序的可测试性对于程序的稳定性是异常重要的。

为什么需要良好的易用性?

毋庸置疑,最好的代码是还没被写出来的代码。因此,越少的代码,意味着越少的 bugs。这也意味着尽量以最少的代码实现相同的功能,并非意味着这个开发者懒惰。

Model–View–Presenter (MVP)

MVP is a user interface architectural pattern engineered to facilitate automated unit testing and improve the separation of concerns in presentation logic
MVP是一种用户界面架构模式,旨在促进自动化单元测试,改善界面与逻辑相剥离
https://www.wikiwand.com/en/Model–view–presenter

MVP

  • View(视图层): 用户界面,通常将Activity或Fragment作为View层。

  • Model(数据层): 负责对数据存取、逻辑处理。例:对数据库的读写,网络请求等。

  • Presenter:连接View层与Model层的桥梁并对业务逻辑进行处理。Presenter从Model层获得所需要的数据,处理后交由View层进行显示。这样通过Presenter将View与Model进行隔离,使得View和Model之间不存在耦合,同时也将业务逻辑从View中抽离。

以接口规范实现

Interface-based programming, also known as interface-based architecture, is an architectural pattern for implementing modular programming at the component level in an object-oriented programming language which does not have a module system. An example of such a language is Java
面向接口编程(也称为基于接口的架构)是用于在不具有模块系统的面向对象编程语言中在组件级实现模块化编程的架构模式。 这样的编程语言例子就是Java。
https://www.wikiwand.com/en/Interface-based_programming

面向接口编程将应用定义为组件的集合,其中组件之间的接口(API)调用只能通过抽象接口进行,而不是具体的类。 类的实例一般通过使用诸如Factory模式(依赖注入↑)的技术通过其他接口获得。

/** * Description: 结算页接口 * Created by cchao on 2017/6/5. */public interface CheckOutContract {    interface View extends BaseCommonView {        void onUpdateAddress(Address addressListBean);        void onUpdatePackage(List<CheckOutBean.PackageBean> packageBean, CheckOutBean checkOutBean);        void onUpdatePaymentMethod(CheckOutBean.PaymentsBean payments);        void onUpdateTotal(List<CheckOutBean.SummaryTotalBean> summaryTotal);        void onUpdateDiscount(CheckOutBean.DiscountsBean discountsBean);        void onUpdateGift(CheckOutBean checkOutBean);        void toggleStripeDialog(boolean b);    }    interface Presenter extends BasePresenter<View> {        void placeOrder(String payMethod);        void setPpToken(String token);        void useCashReduction();        void useCoupon(String coupon);        void usePoint(int points);        void changeShipCode(String packageKey, String shipment_pam);        void updateView(String checkOutBean);        void toChooseAddress(boolean continueBuy, boolean addNew);    }}

以测试驱动开发(TDD)

TDD是测试驱动开发(Test-Driven Development)的英文简称,是敏捷开发中的一项核心实践和技术,也是一种设计方法论。TDD的原理是在开发功能代码之前,先编写单元测试用例代码,测试代码确定需要编写什么产品代码。
https://baike.baidu.com/item/TDD/9064369

单元测试

单元测试(Unit Testing)是针对程序模块(软件设计的最小单位)来进行正确性检验的测试工作。面向对象编程,最小单元就是方法。
通常来说,程式设计师每修改一次程式就会进行最少一次单元测试,在编写程式的过程中前后很可能要进行多次单元测试,以证实程式达到软件规格书要求的工作目标,没有程序错误;
单元测试通常由软件开发人员编写,用于确保他们所写的代码符合软件需求和遵循开发目标。它的实施方式可以是手动的,或者是做成构建自动化(jenkins)的一部分。

  • 对软件质量的提升 (因为有测试)
  • 方便重构 (思路贼清晰,改了代码再跑一次测试就知道有没有影响了)
  • 节约时间 (无需启动模拟器或真机)
  • 提升代码设计

测试金字塔(Testing pyramid)

例:

  1. 我怀疑后端传给我的数据有问题,恰好这是个好进入的页面(例如结算页),这时在mvp及单元测试框架的加持下,我可以方便的调起retrofit去做API测试,而不需要启动模拟器进入那个页面。

  2. 我写完了新的需求,但是beta环境贼慢(甚至后端的代码都没写),我通过Mockito可以方便的模拟出后端数据,供界面(Activity、Fragment)响应。

坑:

  • 静态是不可mock的,
  • 网络请求需同步处理(RxJava)

样例

这里写图片描述

自动化测试

每一次上传版本,都会要求测试人员走一遍(甚至多次)支付流程(甚至有多个支付方式),确保App能正常的支付结算。


对于重复的操作,我们会习惯于对他进行抽取封装。如果能通过自动化对他进行测试,就能解放劳动力,节约成本。

参考link:

  • https://github.com/googlesamples/android-architecture
    这是google 基于MVP 及 MVVM做的项目教程样例 链接
  • https://developer.android.com/training/testing/index.html
    这是android官网给的测试培训教程
  • https://github.com/google/dagger
    这是dagger2
原创粉丝点击