MVC
Android の初期開発アーキテクチャである MVC は、res が V を表し、アクティビティがコントローラー層を表し、モデル層がデータ要求を完了し、操作を更新し、アクティビティがビュー バインディングを完了し、ビジネス ロジックの書き込みとビューを更新します。このモードは一方向です。コードは階層化されていますが、それらの間の結合は依然として非常に高く、C 層は多くのことを実行するため、時間の経過とともに肥大化します。
コード:
ビューモデル
static class StudentModel{
private String name;
private int age;
public StudentModel(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
ビューレイヤー
static class StudentView{
public void PrintStudentData(String name ,int age){
System.out.println("Student name:"+name+" age:"+age);
}
}
コントローラ
static class StudentController{
StudentModel model;
StudentView view;
public StudentController(StudentModel model, StudentView view) {
this.model = model;
this.view = view;
}
public void setStudentName(String name){
model.setName(name);
}
public String getStudentName(){
return model.getName();
}
public void setStudentAge(int age){
model.setAge(age);
}
public Integer getStudentAge(){
return model.getAge();
}
public void updateView(StudentView view){
view.PrintStudentData(model.getName(),model.getAge());
}
}
完全なコード
package com.example.lib;
public class MvcTest {
public static void main(String[] args) {
StudentModel student = getStudentDataBase();
StudentView view = new StudentView();
StudentController controller = new StudentController(student,view);
controller.updateView(view);
controller.setStudentName("lisi");
controller.updateView(view);
}
public static StudentModel getStudentDataBase(){
return new StudentModel("zhangsan",18);
}
static class StudentModel{
private String name;
private int age;
public StudentModel(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
static class StudentView{
public void PrintStudentData(String name ,int age){
System.out.println("Student name:"+name+" age:"+age);
}
}
static class StudentController{
StudentModel model;
StudentView view;
public StudentController(StudentModel model, StudentView view) {
this.model = model;
this.view = view;
}
public void setStudentName(String name){
model.setName(name);
}
public String getStudentName(){
return model.getName();
}
public void setStudentAge(int age){
model.setAge(age);
}
public Integer getStudentAge(){
return model.getAge();
}
public void updateView(StudentView view){
view.PrintStudentData(model.getName(),model.getAge());
}
}
}
MVP
そこで MVP モードが登場しました. このアーキテクチャ モードは Android モバイル端末の開発で比較的一般的です. Activity と res は V 層として統合され, Model 層は引き続きデータの要求と更新を完了します. 新しいクラス Presenter が作成されますこれにより、アクティビティごとのビジネスロジックの管理が容易になるという利点があり、データ取得後はインターフェイスのコールバックを通じてView層が更新され、双方向の通信が実現されます。欠点は、Presenter クラスを実装する必要があり、インターフェイスを開発する必要があるため、単純なビジネス ロジックにとっては面倒であり、P レイヤーは依然として比較的肥大化していることです。
コードの実装 (ログイン トランザクションを例として取り上げます):
ビューモデル層
MVC の ViewModel と比較した MVP の違いは、ViewModel が双方向通信を実現するために追加の IUser インターフェイスを実装していることです。
interface IUser{
void login(String name,String password,OnLoginListener listener);
}
interface OnLoginListener{
void loginFail();
void loginSuccess(User user);
}
static class UserModel implements IUser{
@Override
public void login(String name, String password, OnLoginListener listener) {
//模拟一下登录
if(name.equals("admin")&&password.equals("123456")){
User user = new User();
user.setUsername(name);
user.setPassword(password);
listener.loginSuccess(user);
}else{
listener.loginFail();
}
}
}
ビューレイヤー:
Android 開発では、MVP アーキテクチャ パターンで、ビュー層はアクティビティとリソースを参照します。同様に、P 層との双方向通信を実現するために、IUserLogin インターフェイスも実装されています。
static class UserView implements IUserLogin{
@Override
public void showLoading() {
System.out.println("正在登录...");
}
@Override
public void hideLoading() {
System.out.println("登录完成,获取结果");
}
@Override
public void loginFail() {
System.out.println("登录失败");
}
@Override
public void loginSuccess(User user) {
System.out.println("username:"+ user.getUsername()+" 登陆成功");
}
}
interface IUserLogin{
void showLoading();
void hideLoading();
void loginFail();
void loginSuccess(User user);
}
プレゼンター層
static class UserPresenter {
private final UserModel userModel;
private final UserView userView;
private final User user;
public UserPresenter(UserView userView) {
this.userModel = new UserModel();
this.userView = userView;
user = new User("admin","123456");
}
void login(){
userView.showLoading();
userModel.login(user.getUsername(), user.getPassword(), new OnLoginListener() {
@Override
public void loginFail() {
userView.hideLoading();
userView.loginFail();
}
@Override
public void loginSuccess(User user) {
userView.hideLoading();
userView.loginSuccess(user);
}
});
}
}
完全なコードは次のとおりです。
package com.example.lib;
public class MvpTest {
public static void main(String[] args) {
UserView loginView = new UserView();
UserPresenter presenter = new UserPresenter(loginView);
presenter.login();
}
static class User{
String username;
String password;
public User() {
}
public User(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;
}
}
interface IUser{
void login(String name,String password,OnLoginListener listener);
}
interface OnLoginListener{
void loginFail();
void loginSuccess(User user);
}
static class UserModel implements IUser{
@Override
public void login(String name, String password, OnLoginListener listener) {
//模拟一下登录
if(name.equals("admin")&&password.equals("123456")){
User user = new User();
user.setUsername(name);
user.setPassword(password);
listener.loginSuccess(user);
}else{
listener.loginFail();
}
}
}
static class UserView implements IUserLogin{
@Override
public void showLoading() {
System.out.println("正在登录...");
}
@Override
public void hideLoading() {
System.out.println("登录完成,获取结果");
}
@Override
public void loginFail() {
System.out.println("登录失败");
}
@Override
public void loginSuccess(User user) {
System.out.println("username:"+ user.getUsername()+" 登陆成功");
}
}
interface IUserLogin{
void showLoading();
void hideLoading();
void loginFail();
void loginSuccess(User user);
}
static class UserPresenter {
private final UserModel userModel;
private final UserView userView;
private final User user;
public UserPresenter(UserView userView) {
this.userModel = new UserModel();
this.userView = userView;
user = new User("admin","123456");
}
void login(){
userView.showLoading();
userModel.login(user.getUsername(), user.getPassword(), new OnLoginListener() {
@Override
public void loginFail() {
userView.hideLoading();
userView.loginFail();
}
@Override
public void loginSuccess(User user) {
userView.hideLoading();
userView.loginSuccess(user);
}
});
}
}
}
MVVM
その後に MVVM があります。同様に、Activity と res は引き続き V レイヤーとして使用されます。Model レイヤーはデータと更新を要求し、ViewModel レイヤーが表示されます。このクラスの役割は、データをバインドし、View レイヤーをデータで駆動することです同様に、ビュー レイヤが変更されると、モデル レイヤも更新されるため、M と V の間の双方向のバインディングが実現されます。最も一般的に使用されているのは、2015 年に Google が発表した Jetpack コンポーネントである DataBinding です。これはビュー バインディングを必要とせず、null ポインターなどの多くの煩雑なビジネス ロジックを回避します。
コードの実装: 少しだけ、JetPack によって提供されるデータバインディングを使用します。
要約すると、
MVC、MVP、MVVM の出現はすべて、ビューを階層化し、コード構造とロジックを明確にし、同時にクラスの単一責任を実現し、結合度を減らすことを目的としています。 。しかし同時に、アーキテクチャ設計モードを選択する際には、ビジネスの種類に応じて煩雑な設計を避けることも考慮する必要があります。