【项目架构】Android MVP 和MVVM框架模式 学习实例Demo之mvp篇

说在前面

------------------------------------------------------------------------------------------------------------

随着移动开发的不断演进,项目开发设计模式也变的越来越新颖,越来越便捷。而各个团队都在追求良好的项目架构,不仅能加快工程的进度,也对后续项目的维护和扩展起来很重要的做用。但是,这样也许就会有人问了,既然架构设计这么重要,那为什么不直接设计出来一种万能的构架,直接用最好的构架不就行了。可是,殊不知项目设计的好坏,并不能完全依赖固化的架构。项目的整个过程,是一个不断演进的过程,需要不断的去调整。因为越好的构架设计,逻辑分层是越清楚,代码耦合度越低,复用性和扩展性更好。然后,这样的设计,并不是项目一开始就能定型的。


现在根据个人经验,给大家主说项目架构思路,若有不同意见,欢迎留言交流:

初期项目,设计要遵循这两点:

一,团队。

二,项目。

团队:根据团队的成员人数和能力去划分。

项目:根据功能的多少和功能的复杂度划分。

小的项目团队,采取最简单的模式。统一协作能加快开发,沟通快捷。

大的项目团队,则需要有一个好的功能模块划分,设计项目中的耦合设计。两三人为一小组进行模块开发。充分发挥小团队高效优势,完成项目。

任何项目,最重要的问题就是delay。若一出问题就是各种不可控制。所以,一个好的项目经理,不仅仅是会设计出好的项目架构,更重要的是根据团队的能力,能按时完全产品上线,保证产品的稳定性。这才算是一个合格的项目经理。项目经理要真正的在团队中说NO。面对老板实时要修改需求说NO,面对团队有困难不敢面对说NO。控制好产品的正确走向,才是做好事情的根本。


好了,闲说扯了一大堆,就不多说了。因为有人问起,所以就随手写点了。但说的再多还是实战的经验才是最重要的。不同的团队需要有不一样的处理方式,这个是没有模式可言。只有你懂得把控,才是掌握全局。给大家的经验之谈,说的不对欢迎交流!!!

-------------------------------------------------------------------------------------------------------------------------

开始正题:

mvc,相应不用多说,写程序的同学都懂,也应该都会用。现在就来说说mvp的设计架构。下面的这只是一个很简单的例子,就是为了让大家更简单清晰的看清流程。方便让那些想学习的同学一看就懂。

不懂mvc、mvp、mvvm的先移步看看这篇文章了:【框架篇】mvc、mvp、mvvm使用关系总结

根据维基百科上关于MVP的词条描述,Presenter作用如下:

Presenter作用于model和view,它从仓库(Model)中获取数据,并格式化后让view进行显示。


先看一个小图助于理解:


记住,团队项目开发,功能分离。降低耦合。都是要注重接口编程。对外统一接口,对内扩展。外部减少代码关联,内部功能清楚。这才是好的要求习惯。


好了,继续;

项目代码结构图(是不是特别的简单):



小项目就是点击按钮,从底层拿到数据,返回!!!特别特别的so easy!!

LoginActivity:登录页面。只需要关注与它关联的LoginPresenter即可。不需要关注底层数据。(当然,若是真实的项目开发,接口是需要统一接口协议和数据模式的!在此就不过多复杂了!)

package net.hd.mvpdemo.activity;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

import net.hd.mvpdemo.R;
import net.hd.mvpdemo.presenter.ICallback;
import net.hd.mvpdemo.presenter.LoginPresenter;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

/**
 * UI逻辑:关注UI操作和结果。操作关联的LoginPresenter及回调接口。
 */
public class LoginActivity extends Activity implements ICallback {
    //顺便让大家学习下butterknife了

    @BindView(R.id.name)
    EditText mNameEt;

    @BindView(R.id.password)
    TextView mPsdTv;

    @BindView(R.id.login_progress)
    View mProgressView;

    private LoginPresenter mPrsenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        ButterKnife.bind(this);
        mPrsenter = new LoginPresenter(this);
    }

    @OnClick(R.id.email_sign_in_button)
    void onSubmit() {
        String obj = mNameEt.getText().toString();
        mPrsenter.operateView(obj);
    }

    /**
     * 向Presenter注册callback,回调接口
     *
     * @param obj
     */
    @Override
    public void callback(String obj) {
        mPsdTv.setText("密码:" + obj);
    }


}


花一丢丢时间写的,比较匆忙,就不管太多美观和优化了。只是为了让大家简单的看明白。


IMvpView 接口,作View数据分发。(真实的项目开发中有用。小项目用着感觉特别扭!但功能多的时候,不同的UI模式可能需要联系,而未免直接相互调用,需要定义统一接口方式,功能隔离的好用处啊!!当然,还有个BaseView,进行重复代码封装,但此小例子,实在写着多多余了!)

package net.hd.mvpdemo.view;

import android.app.Fragment;

import net.hd.mvpdemo.presenter.IMvpPresenter;

import java.util.Objects;

/**
 * Created by dan on 2016/9/2.
 * <p/>
 * 分发接口
 */
public interface IMvpView {

    void operateView(Objects obj);

}

IMvpPresenter:P接口。对View接收操作,注册回调。对Model数据调用,注册回调。简单的实在没话说了!

package net.hd.mvpdemo.presenter;

import net.hd.mvpdemo.view.IMvpView;

import java.util.Objects;

/**
 * Created by dan on 2016/9/2.
 * presenter接口。对View和Model都应该是展示其接口就成
 */
public interface IMvpPresenter {

    void operateModel(String obj, ICallback back);

}

ICallback:回调接口。此项目作为View和Presenter回调接口。但是实际项目中,不会这么简单,不同的功能模块回调接口必然不一。而且我也是用最简单的回调方式。真实的情况是不同功能方式不一。比如有些接口是动态注册监听回调,有些则需要状态监听。这就好比,Android中的listener和broadcast区别。都能回调数据,但应用场景和方法不一样而已。

package net.hd.mvpdemo.presenter;

import java.util.Objects;

/**
 * 可以写一个统一的回调接口。
 * 作用:用于View/presenter。model/presenter之间的回调
 * 这里只是简单实现,理解其思路即可,具体接口定义,则根据实际的业务需求
 * Created by dan on 2016/9/2.
 */
public interface ICallback {

    void callback(String obj);
}

LoginPresenter:View与Presenter打交道的类。进行View中相应数据简单处理。并调用M层。

package net.hd.mvpdemo.presenter;

import net.hd.mvpdemo.model.IMvpModel;
import net.hd.mvpdemo.model.LoginModel;

/**
 * Created by dan on 2016/9/2.
 * <p/>
 * presenter做为连接view与model。进行数据隔离
 * 不同的presenter做不同的数据分发处理
 */
public class LoginPresenter implements IMvpPresenter, IMvpModel, ICallback {
    private IMvpModel model;
    private ICallback viewCallback;

    /**
     * 通过presenter构造方法,创建Model对象,隔离View与Model的联系
     */
    public LoginPresenter(ICallback cb) {
        model = new LoginModel();
        viewCallback = cb;
    }

    public void operateView(String obj){
        operateModel(obj, this);
    }

    @Override
    public void operateModel(String obj, ICallback back) {
        handModel(obj, back);
    }

    /**
     * 通过callback,完成操作回调数据,通过view更新
     */
    @Override
    public void handModel(String obj, ICallback call) {
        model.handModel(obj, call);
    }


    /**
     * model数据处理完,通过viewcallback回调给上层view
     *
     * @param obj
     */
    @Override
    public void callback(String obj) {
        viewCallback.callback(obj);
    }


}

IMvpModel:m层接口。对presenter接口编程,就是得应该这样。对外只展示最简单的接口即可。

package net.hd.mvpdemo.model;

import net.hd.mvpdemo.presenter.ICallback;
import java.util.Objects;

/**
 * model层统一实现接口
 * Created by dan on 2016/9/2.
 */
public interface IMvpModel {

    void handModel(String obj, ICallback back);
}

IBaseModel:封装统一m接口。作用当然就是代码复用了。其实v、p都应该有的。这样减少重复代码。让实现只专注需求功能。而不要让每个人都去写重复的代码。

package net.hd.mvpdemo.model;

import net.hd.mvpdemo.presenter.ICallback;

import java.util.Objects;

/**
 * 基础model,相同的逻辑统一处理
 * 不同的逻辑,再由子类实现
 * Created by dan on 2016/9/2.
 */
public class BaseModel implements IMvpModel  {

    @Override
    public void handModel(String obj,ICallback back) {

    }


}

LoginModel:真正的逻辑处理了。不多解释了!

package net.hd.mvpdemo.model;

import net.hd.mvpdemo.presenter.ICallback;

import java.util.Objects;
import java.util.Random;

/**
 * Created by dan on 2016/9/2.
 */
public class LoginModel extends BaseModel {
    /**
     * 模拟登录
     */
    private void loginAsync(final String obj, final ICallback onCallback) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                int i = new Random().nextInt(1000);

                onCallback.callback(obj + i);
            }
        }).run();
    }

    @Override
    public void handModel(String obj, ICallback back) {
        loginAsync(obj,back);
    }


}

xml其实就是android login的原型,都没改。

 <LinearLayout
            android:id="@+id/email_login_form"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">


                <EditText
                    android:id="@+id/name"
                    android:layout_width="match_parent"
                    android:layout_height="50dp"
                    android:maxLines="1"
                    android:singleLine="true"/>



                <TextView
                    android:id="@+id/password"
                    android:layout_width="match_parent"
                    android:layout_height="40dp"
                    android:maxLines="1"
                    android:text="密码"
                    android:singleLine="true"/>


            <Button
                android:id="@+id/email_sign_in_button"
                style="?android:textAppearanceSmall"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="16dp"
                android:text="@string/action_sign_in"
                android:textStyle="bold"/>

        </LinearLayout>

整个项目,都是以最简单的方式,把逻辑展示清楚就行。已经不能再简单了。但是还是比较难体现设计思想。而且真实的项目情况,也不会这么简单。这只是做为学习之用了。


不知道大家有没有看懂了???

代码还是有空多写写,思路就会清楚了。这只是一个很简单的例子。

有空的时候,再写个mvvm的例子了。


有问题多交流!!!做技术就是先多想,然后再多写,最后就多问了!搞清楚明白了,这才是自己的知识。不然,终究只是个代码搬运工了。


祝大家都能成为大牛。只要你能持之以恒!!!



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值