Android MVC MVP MVVM简单例子

目录

1. MVC MVP MVVM 间的区别

1.1 MVC(Model-View-Controller)

1.2 MVP(Model-View-Presenter)

1.3 MVVM(Model-View-ViewModel)

2. 例子Demo

2.1 MVC

2.2 MVP

2.3 MVVM


1. MVC MVP MVVM 间的区别

三者的区别如下图所示:

1.1 MVC(Model-View-Controller)

  • Model:代表我们的数据模型,管理数据状态。
  • View:视图,即呈现给用户的UI,比如我们的layout.xml文件及Activity。
  • Controller:控制者,负责处理用户与app之间的交互,包含业务逻辑。所以是Model与View的中介,比如我们的Activity/Fragment。

缺点:如上图所示,View与Model之间还存在依赖关系,Controller很‘重’很复杂。在Android中Activity即是View又是Controller,所以会很复杂。

1.2 MVP(Model-View-Presenter)

  • Model:代表我们的数据模型,管理数据状态。
  • View:视图,即呈现给用户的UI,并且负责与客户进行交互。比如我们的XML/Activity/Fragment。
  • Presenter:主持者,Presenter通过View接收用户的输入,然后在Model的帮助下处理用户的数据并将结果传递回View。Presenter通过接口与View进行通信。接口在presenter类中定义,它传递所需的数据。Activity/Fragment 及其他View视图组件实现此接口获得他们想要的数据并呈现数据。

优点:将View与Model解耦,方便进行单元测试。

缺点:虽然是MVC模式的演变,但Presenter依旧很‘重’很复杂。

1.3 MVVM(Model-View-ViewModel)

  • Model:代表我们的数据模型,管理数据状态。
  • View:视图,即呈现给用户的UI,并且负责与客户进行交互。比如我们的XML/Activity/Fragment。
  • ViewModel:如上图所示,ViewModel与Presenter的区别,在MVVM中,View引用持有ViewModel,但ViewModel得不到任何关于View的信息。所以View与ViewModel之间存在着一对多的关系,一个View可以持有多个ViewModel

是MVP模式的一个优化。

2. 例子Demo

分别用MVC MVP MVVM设计模式来实现一个用户登入的功能:如下:
 

,简单的用户登入功能​​​

2.1 MVC

Controller层:

public class MvcLoginActivity extends AppCompatActivity {
    private EditText userNameEt;
    private EditText passwordEt;
    private User user;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_mvc_login);

        user = new User();
        userNameEt = findViewById(R.id.user_name_et);
        passwordEt = findViewById(R.id.password_et);
        Button loginBtn = findViewById(R.id.login_btn);

        loginBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                login(userNameEt.getText().toString(), passwordEt.getText().toString());
            }
        });
    }

    private void login(String userName, String password) {
        if (userName.equals("jere") && password.equals("123")) {
            user.setUserName(userName);
            user.setPassword(password);
            Toast.makeText(MvcLoginActivity.this,
                    userName + " Login Successful",
                    Toast.LENGTH_SHORT)
                    .show();
        } else {
            Toast.makeText(MvcLoginActivity.this,
                    "Login Failed",
                    Toast.LENGTH_SHORT)
                    .show();
        }
    }
}

2.2 MVP

Model层:

public interface IUserBiz {
    boolean login(String userName, String password);
}
/**
 * User业务逻辑实现
 */
public class UserBiz implements IUserBiz {

    @Override
    public boolean login(String userName, String password) {

        if (userName.equals("jere") && password.equals("123")) {
            User user = new User();
            user.setUserName(userName);
            user.setPassword(password);
            return true;
        }
        return false;
    }
}

Presenter层:

public class LoginPresenter{
    private UserBiz userBiz;
    private IMvpLoginView iMvpLoginView;

    public LoginPresenter(IMvpLoginView iMvpLoginView) {
        this.iMvpLoginView = iMvpLoginView;
        this.userBiz = new UserBiz();
    }

    public void login() {
        String userName = iMvpLoginView.getUserName();
        String password = iMvpLoginView.getPassword();
        boolean isLoginSuccessful = userBiz.login(userName, password);
        iMvpLoginView.onLoginResult(isLoginSuccessful);
    }


}

View层:

public interface IMvpLoginView {
    String getUserName();

    String getPassword();

    void onLoginResult(Boolean isLoginSuccess);
}
public class MvpLoginActivity extends AppCompatActivity implements IMvpLoginView{
    private EditText userNameEt;
    private EditText passwordEt;
    private LoginPresenter loginPresenter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_mvp_login);

        userNameEt = findViewById(R.id.user_name_et);
        passwordEt = findViewById(R.id.password_et);
        Button loginBtn = findViewById(R.id.login_btn);

        loginPresenter = new LoginPresenter(this);
        loginBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                loginPresenter.login();
            }
        });
    }

    @Override
    public String getUserName() {
        return userNameEt.getText().toString();
    }

    @Override
    public String getPassword() {
        return passwordEt.getText().toString();
    }

    @Override
    public void onLoginResult(Boolean isLoginSuccess) {
        if (isLoginSuccess) {
            Toast.makeText(MvpLoginActivity.this,
                    getUserName() + " Login Successful",
                    Toast.LENGTH_SHORT)
                    .show();
        } else {
            Toast.makeText(MvpLoginActivity.this,
                    "Login Failed",
                    Toast.LENGTH_SHORT).show();
        }
    }
}

2.3 MVVM

ViewModel层:

public class LoginViewModel extends ViewModel {
    private User user;
    private MutableLiveData<Boolean> isLoginSuccessfulLD;

    public LoginViewModel() {
        this.isLoginSuccessfulLD = new MutableLiveData<>();
        user = new User();
    }

    public MutableLiveData<Boolean> getIsLoginSuccessfulLD() {
        return isLoginSuccessfulLD;
    }

    public void setIsLoginSuccessfulLD(boolean isLoginSuccessful) {
        isLoginSuccessfulLD.postValue(isLoginSuccessful);
    }

    public void login(String userName, String password) {
        if (userName.equals("jere") && password.equals("123")) {
            user.setUserName(userName);
            user.setPassword(password);
            setIsLoginSuccessfulLD(true);
        } else {
            setIsLoginSuccessfulLD(false);
        }
    }

    public String getUserName() {
        return user.getUserName();
    }
}

View层:

public class MvvmLoginActivity extends AppCompatActivity {
    private LoginViewModel loginVM;
    private EditText userNameEt;
    private EditText passwordEt;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_mvvm_login);

        userNameEt = findViewById(R.id.user_name_et);
        passwordEt = findViewById(R.id.password_et);
        Button loginBtn = findViewById(R.id.login_btn);
        loginBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                loginVM.login(userNameEt.getText().toString(), passwordEt.getText().toString());
            }
        });

        loginVM = ViewModelProviders.of(this).get(LoginViewModel.class);
        loginVM.getIsLoginSuccessfulLD().observe(this, loginObserver);
    }

    private Observer<Boolean> loginObserver = new Observer<Boolean>() {
        @Override
        public void onChanged(@Nullable Boolean isLoginSuccessFul) {
            if (isLoginSuccessFul) {
                Toast.makeText(MvvmLoginActivity.this,
                        loginVM.getUserName() + " Login Successful",
                        Toast.LENGTH_SHORT)
                        .show();
            } else {
                Toast.makeText(MvvmLoginActivity.this,
                        "Login Failed",
                        Toast.LENGTH_SHORT)
                        .show();
            }
        }
    };
}

 

点击这里查看文章中的源代码

 

参考文献:

如何构建Android MVVM 应用框架 - 美团技术团队
 

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值