Android 超越官方 MVC架构 MVP架构 MVVM架构 一网打尽;

MVC简介

MVC全名是Model View Controller,如图,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。

其中M层处理数据,业务逻辑等;V层处理界面的显示结果;C层起到桥梁的作用,来控制V层和M层通信以此来达到分离视图显示和业务逻辑层。

 

 

 

缺点:

 

Activity既是controller层,又是view层,导致Activity臃肿,不好维护

 

场景分析:

 

1.大家想过这样会有什么问题吗?显然是有的,不然为什么会有MVP和MVVM的诞生呢,是吧。问题就在于xml作为view层,控制能力实在太弱了,你想去动态的改变一个页面的背景,或者动态的隐藏/显示一个按钮,这些都没办法在xml中做,只能把代码写在activity中,造成了activity既是controller层,又是view层的这样一个窘境。大家回想一下自己写的代码,如果是一个逻辑很复杂的页面,activity或者fragment是不是动辄上千行呢?这样不仅写起来麻烦,维护起来更是噩梦。

 

2.以前用volley,现在切换成Afinal框架实现网络请求,你怎么解决问题?MVC不好搞定,一般修改不仅破坏了以前的代码,而且还不利于维护, 考虑到以后代码的扩展和维护性,我们选择设计接口的方式来解决着一个问题就是MVP

 

代码示例:就是我们常常写的,这里不贴了

 

什么是MVP?

 

 

 

 

 

 

从图中就可以看出,最明显的差别就是view层和model层不再相互可知从图中就可以看出,最明显的差别就是view层和model层不再相互可知,完全的解耦,取而代之的presenter层充当了桥梁的作用

 

 

MVP则是使用P截断了M与V之间的联系,降低了复杂程度,指责结构简单明了;

因此,Activity及从MVC中的Controller中解放出来了,这会Activity主要做显示View的作用和用户交互。每个Activity可以根据自己显示View的不同实现View视图接口IUserView。

          MVP模式的优点:

  • 在MVP中,Activity的代码不臃肿;
  • 在MVP中,Model(IUserModel的实现类)的改动不会影响Activity(View),两者也互不干涉,而在MVC中会;
  • 在MVP中,IUserView这个接口可以实现方便地对Presenter的测试;
  • 在MVP中,UserPresenter可以用于多个视图,但是在MVC中的Activity就不行。
  • 明显可以发现Mvp模式下的代码量相对来说确实增加了很多,但是逻辑相对的更加清晰,所以我觉得Mvp模式 不是很适合小型的项目,小型项目整一堆类出来确实不是很好的事情,但是如果是一个较大型的项目还是可以选 用这种架构来做开发,毕竟逻辑清晰,维护起来也比较方便。
  •  

    MVP缺点:

    MVP的问题在于,由于我们使用了接口的方式去连接view层和presenter层,这样就导致了一个问题,如果你有一个逻辑很复杂的页面,你的接口会有很多,十几二十个都不足为奇。想象一个app中有很多个这样复杂的页面,维护接口的成本就会非常的大。

  •  

    private EditText usernameEdit,passwrodEdit;
    
    private Button loginButton;
    
    ProgressDialog pd;
    
    
    /***
     * 采用MVP编程
     * @param savedInstanceState
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        pd = new ProgressDialog(this);
    
        usernameEdit = (EditText) findViewById(R.id.et_username);
        passwrodEdit = (EditText) findViewById(R.id.et_password);
        loginButton = (Button) findViewById(R.id.bt_login);
    
        loginButton.setOnClickListener(this);
    
        //初始化
        loginPresenter = new LoginPersenter(this);
    
    }
    LoginPersenter loginPresenter;
    
    @Override
    public void onClick(View v) {
        loginPresenter.Login(usernameEdit.getText().toString(),passwrodEdit.getText().toString());
    }
    
    @Override
    public void showProgress() {
        pd.show();
    }
    
    @Override
    public void hideProgress() {
        pd.cancel();
    }
    
    @Override
    public void setPasswordError() {
        passwrodEdit.setError("passwrod error");
    }
    
    @Override
    public String getUsername() {
        return usernameEdit.getText().toString();
    }
    
    @Override
    public String getPassword() {
        return passwrodEdit.getText().toString();
    }
    
    @Override
    public void loginSuccess() {
        Toast.makeText(this, "login success", Toast.LENGTH_SHORT).show();
    }

     

  •  

    public class LoginPersenter implements ILoginPresenter{
    
        private ILoginView loginView;
        private UserModel mUser;
    
    
        public LoginPersenter(ILoginView loginView) {
            this.loginView = loginView;
            initUser();
        }
    
        private void initUser(){
            mUser = new UserModel(loginView.getUsername(),loginView.getPassword());
        }
    
        @Override
        public void Login(String username, String password) {
            loginView.showProgress();
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    loginView.hideProgress();
                    int code = mUser.checkUserValidity(loginView.getUsername(), loginView.getPassword());
                    if (code == -1) {
                        loginView.setPasswordError();
                    } else if (code == 0) {
                        loginView.loginSuccess();
                    }
                }
            },2000);
        }
    public interface ILoginPresenter {
    
        void Login(String username, String password);
    }
    
    public interface ILoginView {
    
        void showProgress();
    
        void hideProgress();
    
        void setPasswordError();
    
        String getUsername();
    
        String getPassword();
    
        void loginSuccess();
    
    }
    public class UserModel {
    
        private String username;
        private String password;
    
        public UserModel(String username, String password) {
            this.username = username;
            this.password = password;
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public int checkUserValidity(String username, String password) {
            if (username == null || password == null ||
                    username.isEmpty() ||
                    password.isEmpty()) {
                return -1;
            }
            return 0;
        }

     

  • 总结:多了接口,和Presenter的model和view封装

  •  

 

 

   MVVM

MVVM是Model-View-ViewModel的简写。

 

 

了解MVVM+data binding的开发模式。

 

 

至于MVVM基本上和MVP一模一样,感觉只是名字替换了一下。他的关键技术就是今天的主题(Data Binding)。View的变化可以自动的反应在ViewModel,ViewModel的数据变化也会自动反应到View上。这样开发者就不用处理接收事件和View更新的工作,框架已经帮你做好了。

 

 

 

 

最近很火最主要的原因就是谷歌推出了data binding这个框架,可以轻松的实现MVVM。我个人觉得是Android往后发展的趋势,毕竟谷歌都推出了Datebinding,而使用Datebinding也就可以不用去使用bufferknife了

 

Data Binding的开发者贴心得为我们准备了一系列的ObservableField,包括: ObservableBooleanObservableByteObservableCharObservableShortObservableIntObservableLongObservableFloat,ObservableDouble, 以及 ObservableParcelable

 

 

原理和流程

环境要求 Data Binding对使用的环境还是有一定要求的(这货有点挑) Android Studio版本在1.3以上 gradle的版本要在1.5.0-alpha1以上

 

  • ####创建对象 创建一个User类

 

 

public class UserModel {

    private String username;
    private String password;

    public UserModel(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public int checkUserValidity(String username, String password) {
        if (username == null || password == null ||
                username.isEmpty() ||
                password.isEmpty()) {
            return -1;
        }
        return 0;
    }

 

 

 

 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:id="@+id/container"

    android:orientation="vertical"


    android:fitsSystemWindows="true">

    <data>
        <import type="com.example.gavin.databindingtest.User"/>
        <variable
            name="user"
            type="User" />
    </data>

   <EditText
       android:id="@+id/et_username"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

 

 

 

 

xml中的代码需要导入包

vm用到xml中的,需要声明

 

 

 
public class ImageUtil { /**  * 使用ImageLoader显示图片  * @param imageView  * @param url  */  @BindingAdapter({"image"}) public static void imageLoader(ImageView imageView, String url) { ImageLoader.getInstance().displayImage(url, imageView);  } /**  * 使用ImageLoader显示图片  * @param view  * @param b  */  @BindingAdapter({"isVisibleOrGone"}) public static void isVisibleOrGone(View view, boolean b) { int visiable;  if (b) { visiable = View.VISIBLE;  } else { visiable = View.GONE;  } view.setVisibility(visiable);  }

public class ImageUtil { /** * 使用ImageLoader显示图片 * @param imageView * @param url */ @BindingAdapter({"bind:image"}) public static void imageLoader(ImageView imageView, String url) { ImageLoader.getInstance().displayImage(url, imageView);

 

 

public class User extends BaseObservable {
    private String firstName;
    private String lastName;
    public boolean isStudent = true;

    public User(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
    @Bindable
    public String getFirstName() {
        return this.firstName;
    }
    @Bindable
    public String getLastName() {
        return this.lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
        notifyPropertyChanged(BR.lastName);
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
        notifyPropertyChanged(BR.firstName);
    }
}
public static String mName = "MM";
private ActivityMainBinding binding;
private User user;
private User2 mUser2;
List<User2> data = new ArrayList<>();
MyAdapter adapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
    user = new User("Micheal", "Jack");
    binding.setUser(user);
    binding.setHandle(new MyHandler());
    mUser2 = new User2();
    mUser2.firstName.set("Mr");
    mUser2.lastName.set("Bean");
    mUser2.age.set(5);
    mUser2.isStudent.set(false);
    binding.setUser2(mUser2);
    ImageLoaderConfiguration configuration = ImageLoaderConfiguration.createDefault(this);
    ImageLoader.getInstance().init(configuration);
    binding.setImageUrl("http://115.159.198.162:3000/posts/57355a92d9ca741017a28375/1467250338739.jpg");
<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:image = "@{imageUrl}"/>

 

 

 

 

DataBindingUtil和
BaseObservable是databing自带的

看到View和VM紧紧的联系在了一起

 

 

 

 

大总结:

  • MVC:(VIew-Model-Controller) 早期将VIew、Model、Controller代码块进行划分,使得程序大部分分离,降低耦合。
  • MVP:(VIew-Model-Presenter)由于MVC中View和Model之间的依赖太强,导致Activity中的代码过于臃肿。为了他们可以绝对独立的存在,慢慢演化出了MVP。在MVP中View并不直接使用Model,它们之间的通信是通过 Presenter (MVC中的Controller)来进行的。
  • MVVM:必须先学会DataBinding(Model–View–ViewModel) MVVM可以算是MVP的升级版,将 Presenter 改名为 ViewModel。关键在于View和Model的双向绑定,当View有用户输入后,ViewModel通知Model更新数据,同理Model数据更新后,ViewModel通知View更新。
  •  

 

ASdemo的下载地址:点击打开链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值