设计框架 MVC MVP MVVM

MVC MVP MVVM

MVC

在这里插入图片描述

MVC是什么?
视图层(View)
对应于xml布局文件和java代码动态view部分
控制层(Controller)
MVC中Android的控制层是由Activity来承担的,负责视图的显示,控制逻辑。
模型层(Model)
针对业务模型,建立的数据结构和相关的类,它主要负责网络请求,数据库处理,I/O的操作。

MVC特点
具有一定的分层,model彻底解耦,controller和view并没有解耦;
层与层之间的交互尽量使用回调或者去使用消息机制去完成。
易于理解,开发速度快,可维护性高。

MVP

在这里插入图片描述
MVP是什么?
Presenter类似于MVC中的Model,主要负责业务逻辑的实现。
Contract 契约类用于定义同一个界面的view的接口和presenter的具体实现。

MVP特点
通过引入接口Contract.View,让相应的视图组件如Activity,Fragment去实现Contract.View,实现了视图层的独立;
通过中间层Preseter实现了Model和View的完全解耦。
更容易单元测试。
随着业务逻辑的增加,一个页面可能会非常复杂,UI的改变是非常多,会有非常多的case,这样就会造成View的接口会很庞大。

MVP缺点
P层定义的接口过多,导致P,V层代码过于冗余;
P层和V层的交互频繁,则无法实现高复用低耦合效果;
P层操作M层的耗时操作,可能引起V层的ANR。

MVP应用示例

// contract类
public interface AuthContract {

    interface View {
        /**
         * 连接成功设置ip显示
         */
        void setIpAddress(String ipAddress);
    }
}

// p层;m层即是NetUtil
public class BasePresenter<T> implements LifecycleObserver {
    protected T mView;

    public BasePresenter(T view) {
        this.mView = view;
    }
    
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    protected void release() {
        mView = null;
    }
}
public class AuthPresenter extends BasePresenter<AuthContract.View>{
    public AuthPresenter(AuthContract.View view) {
        super(view);
    }
    
    @Override
    public void onNetworkConnected() {
        NetUtil netUtil = NetUtil.getInstance((Context) mView);
        netUtil.NetUtil_SetNetView(new NetView() {
            @Override
            public void Event_EthConnectMode(int mode, Boolean connect, NetInfo netInfo) {
                if (connect && netInfo != null && !TextUtils.isEmpty(netInfo.getIpaddr())) {
                    mView.setIpAddress(netInfo.getIpaddr());
                    checkDNS();
                }
            }
        });
        netUtil.getEthConnectMode();
    }
}

// v层
public class MainActivity extends BaseActivity implements AuthContract.View {
    /**
     * 连接成功设置ip显示
     */
    @Override
    public void setIpAddress(String ipAddress) {
        mIpAddress = ipAddress;
        mTvAuthStatus.setText(TextUtils.isEmpty(ipAddress) ? getString(R.string.network_no_ip) :
                MessageFormat.format(getString(R.string.network_ip_address), ipAddress));
    }
    ...
}

MVVM

在这里插入图片描述
MVVM是什么?
MVVM通过双向绑定的机制,实现数据和UI内容,只要想改其中一方,另一方都能够及时更新的一种设计理念,这样就省去了很多在View层中写很多case的情况,只需要改变数据就行。
View和ViewModel通过Binding进行关联,他们之前的关联处理通过DataBinding完成。

MVVM特点
解决了MVC和MVP的不足,controlle和view没有解耦;view接口过于庞大。
由于数据和视图的双向绑定,导致出现问题时不太好定位来源,有可能数据问题导致,也有可能业务逻辑中对视图属性的修改导致。
视图状态较多,viewmodel的构建和维护成本都较高。

MVVM实现
view层
通过DataBindingUtil可以动态生成一个ViewDataBinding的子类,类名以layout文件名大写加Binding组成

ActivitySampleMvvmBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_sample_mvvm);

在layout中需要我们配置,每个控件绑定的实体对象,以layout进行包裹,data中配置变量名和类型,通过@{}或@={}的方式进行引用,其中@={}的方式表示双向绑定。

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data >
        <variable
            name="user"
            type="com.androfarmer.mvvm.model.SampleModel.UserInfo">
        </variable>
    </data>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@={user.name}"
        />
    <TextView
        android:id="@+id/tv_age"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@={user.age+``}"
        />

</LinearLayout>
</layout>

model:为了实现双向绑定还需要对数据实体类做处理,继承BaseObservable,对读写方法做@Bindable和notifyPropertyChanged处理。

public static class UserInfo  extends BaseObservable
    {
        private int age;
        private String name;

        @Bindable
        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
            notifyPropertyChanged(BR.age);
        }

        @Bindable
        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
            notifyPropertyChanged(BR.name);
        }
    }

viewModel层

public abstract class BaseViewModel<T extends ViewDataBinding>{
    public T mViewDataBinding;
    public BaseViewModel(T viewDataBinding)
    {
        this.mViewDataBinding=viewDataBinding;
    }

    public void onDestroy() {
        mViewDataBinding.unbind();
    }
}

public class SampleViewModel extends BaseViewModel<ActivitySampleMvvmBinding> {

    public SampleViewModel(ActivitySampleMvvmBinding viewDataBinding) {
        super(viewDataBinding);
    }

    public void getUserInfo(String uid, Callback1<SampleModel.UserInfo> callback)
    {
        //从网络或缓存获取信息
        SampleModel.UserInfo userInfo=new SampleModel.UserInfo();
        userInfo.setName("tom");
        userInfo.setAge(18);
        callback.onCallBack(userInfo);
    }
}

ViewMode层主要处理业务逻辑和获取数据,mViewDataBinding是通过View层传递过来。

 private SampleViewModel mSampleViewModel;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivitySampleMvvmBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_sample_mvvm);
        mSampleViewModel=new SampleViewModel(binding);
        setDataToView();
    }
    
    private void setDataToView()
    {
        mSampleViewModel.getUserInfo("uid", new Callback1<SampleModel.UserInfo>() {
            @Override
            public void onCallBack(SampleModel.UserInfo userInfo) {
                mSampleViewModel.mViewDataBinding.setUser(userInfo);
            }
        });
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值