安卓常用架构 MVC & MVP & MVVM

一、MVC

1. 简介

M是指业务模型,V是指用户界面,C是控制器

全名 Model View Controller

业务模型Model- 用户视图View- 控制器Controller

2. 解释

  • View层其实就是程序的UI界面,用于向用户展示数据以及接收用户的输入
  • Model层就是JavaBean实体类,用于保存实例数据
  • Controller控制器用于更新UI界面和数据实例

4. 项目结构

建立3个包 beans、views、controllers分别存放对应的模型、视图、控制层

3. 优缺点

  • 缺点:Activity既是C又是V,既有显示UI界面,又有登陆操作。所有的代码都是在MainActivity
// Model
public class User {
    private String name;
    private String email;
    
    // Getters and Setters
}
 
// View
public class UserView {
    public void displayUser(String name, String email) {
        System.out.println("Name: " + name);
        System.out.println("Email: " + email);
    }
}
 
// Controller
public class UserController {
    private User model;
    private UserView view;
    
    public UserController(User model, UserView view) {
        this.model = model;
        this.view = view;
    }
    
    public void updateUser(String name, String email) {
        model.setName(name);
        model.setEmail(email);
    }
    
    public void displayUser() {
        String name = model.getName();
        String email = model.getEmail();
        view.displayUser(name, email);
    }
}
 
// Usage
public static void main(String[] args) {
    User user = new User();
    user.setName("John");
    user.setEmail("john@example.com");
    
    UserView userView = new UserView();
    UserController userController = new UserController(user, userView);
    
    // Update user information
    userController.updateUser("Jane", "jane@example.com");
    
    // Display user information
    userController.displayUser();
}
java

二、MVP

1. 简介

M是指业务模型,V是指用户界面,P是逻辑层(ModelView之间的桥梁)

全名 Model View Presenter

业务模型Model- 用户视图View- 逻辑层Presenter

2. 解释

Activity中的UI逻辑抽象成View接口,把业务逻辑抽象成Presenter接口,Model类还是原来的Model

  • 分离视图逻辑和业务逻辑,降低耦合
  • Activity只处理生命周期的任务,代码简洁
  • 视图逻辑和业务逻辑抽象到了ViewPresenter中,提高阅读性
  • Presenter被抽象成接口,可以有多种具体的实现
  • 业务逻辑在Presenter中,避免后台线程引用Activity导致内存泄漏

3.项目结构

建立3个包 beans、views、presenters分别存放对应的模型、视图、控制层

4. 优缺点

  • Presenter更新UI需要在主线程
  • Presenter更新UI无法确保UI是否已经被销毁

5. 项目示例

  • IArticlePresenterCallback.java
package cool.hyz.xujiayi.callbacks;

import cool.hyz.xujiayi.beans.Article;

/**
 * Created by Lib on 2022/4/20
 * Best Wishes !
 */

public interface IArticlePresenterCallback {
    /**
     * 数据加载完成
     * @param article Article
     */
    void onArticleInfoLoaded(Article article);

    /**
     * 网络不佳
     */
    void onNetworkError();

    /**
     * 数据为空
     */
    void onEmpty();
}
java
  • IArticlePresenter.java
package cool.hyz.xujiayi.services.interfaces;

import java.io.IOException;

import cool.hyz.xujiayi.callbacks.IArticlePresenterCallback;

/**
 * Created by Lib on 2022/4/20
 * Best Wishes !
 */

public interface IArticlePresenter {

    /**
     * 获取Article信息
     * @param id id
     * @throws IOException IOException
     */
    void getArticleInfo(String id) throws IOException;


    /**
     * 注册Presenter
     * @param callback IArticlePresenterCallback
     */
    void registerCallback(IArticlePresenterCallback callback);

    /**
     * 取消注册Presenter
     * @param callback IArticlePresenterCallback
     */
    void unRegisterCallback(IArticlePresenterCallback callback);

}
java
  • ArticlePresenter.java
package cool.hyz.xujiayi.services;

import com.google.gson.Gson;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import cool.hyz.xujiayi.beans.Article;
import cool.hyz.xujiayi.callbacks.IArticlePresenterCallback;
import cool.hyz.xujiayi.services.interfaces.IArticlePresenter;
import cool.hyz.xujiayi.utils.Constance;
import cool.hyz.xujiayi.utils.HttpRequest;

/**
 * Created by Lib on 2022/4/20
 * Best Wishes !
 */

public class ArticlePresenter implements IArticlePresenter {

    private IArticlePresenterCallback mCallback;
    private static final List<IArticlePresenterCallback> sCallback = new ArrayList<>();
    HttpRequest request = new HttpRequest();

    @Override
    public void getArticleInfo(String id) {
        new Thread(() -> {
            Article article = null;
            try {
                article = new Gson().fromJson(request.GET(Constance.API.ARTICLE_DETAIL+id), Article.class);
            } catch (IOException e) {
                e.printStackTrace();
            }
            mCallback.onArticleInfoLoaded(article);
        }).start();
    }
    
    @Override
    public void registerCallback(IArticlePresenterCallback callback) {
        if (callback != null && !sCallback.contains(callback)) {
            mCallback = callback;
            sCallback.add(mCallback);
        }
    }

    @Override
    public  void unRegisterCallback(IArticlePresenterCallback callback) {
        if (callback != null && sCallback.contains(callback)) {
            sCallback.remove(callback);
        }
    }
}
java
  • ArticleActivity.java
package cool.hyz.xujiayi;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.Nullable;
import com.squareup.picasso.Picasso;

import cool.hyz.xujiayi.bases.BaseApplication;
import cool.hyz.xujiayi.beans.Article;
import cool.hyz.xujiayi.beans.ArticleDetailBean;
import cool.hyz.xujiayi.beans.CommentListBean;
import cool.hyz.xujiayi.callbacks.IArticlePresenterCallback;
import cool.hyz.xujiayi.services.ArticlePresenter;

/**
 * Created by Lib on 2022/4/21
 * Best Wishes !
 */
public class ArticleActivity extends Activity implements IArticlePresenterCallback {

    public static final String TAG = "ArticleActivity";
    private ArticlePresenter mPresenter;

    private ImageView mCover;
    private TextView mTitle;
    private TextView mCreateTime;
    private TextView mUpdateTime;
    private TextView mCategory;
    private String mId;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.page_article);
        initView();
        initPresenter();
        initData();
    }

    private void initView() {
        mTitle = findViewById(R.id.article_title);
        mCover = findViewById(R.id.article_cover);

        mCreateTime = findViewById(R.id.article_create_time);
        mUpdateTime = findViewById(R.id.article_update_time);
        mCategory = findViewById(R.id.article_category);
    }

    private void initPresenter() {
        mPresenter = new ArticlePresenter();
        //注册Presenter
        mPresenter.registerCallback(this);
    }

    private void initData() {
        Intent intent = getIntent();
        mId = intent.getStringExtra("id");
        //Presenter请求数据
        mPresenter.getArticleInfo(mId);
    }

    @Override
    public void onArticleInfoLoaded(Article article) {
        //更新UI
        BaseApplication.getHandler().post(() -> {
            Picasso.with(this).load(article.getArticleCover().startsWith("//") ? "https:" + article.getArticleCover() : article.getArticleCover()).into(mCover);

            mCreateTime.setText(article.getCreateTime().substring(0, 10));
            mUpdateTime.setText(article.getUpdateTime() != null ? article.getUpdateTime().substring(0, 10) : article.getCreateTime().substring(0, 10));
            mCategory.setText(article.getCategoryName());
            String articleTitle = article.getArticleTitle();
            mTitle.setText(articleTitle);
        });
    }

    @Override
    public void onNetworkError() {
        //更新UI
    }

    @Override
    public void onEmpty() {
        //更新UI
    }
}
java

三、MVVM

1. 简介

M是指业务模型,V是指用户界面,VM是逻辑层

全名 Model View ViewModel

业务模型Model- 用户视图View- 应用程序逻辑控制器ViewModel

2. 解释

Activity中的UI逻辑抽象成View接口,把业务逻辑抽象成Presenter接口,Model类还是原来的Model

  • 分离视图逻辑和业务逻辑,降低耦合
  • Activity只处理生命周期的任务,代码简洁
  • 视图逻辑和业务逻辑抽象到了ViewPresenter中,提高阅读性
  • Presenter被抽象成接口,可以有多种具体的实现
  • 业务逻辑在Presenter中,避免后台线程引用Activity导致内存泄漏

3.项目结构

建立4个包 beans、views、models、repositories分别存放对应的模型、视图、控制层、存储层

4. 优缺点

  • Presenter更新UI需要在主线程
  • Presenter更新UI无法确保UI是否已经被销毁

5. 示例

// Model
public class User {
    private String name;
    private String email;
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getEmail() {
        return email;
    }
 
    public void setEmail(String email) {
        this.email = email;
    }
}
 
// View
public class MainActivity extends AppCompatActivity {
    private EditText nameEditText;
    private EditText emailEditText;
    private Button saveButton;
    private UserViewModel viewModel;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        // Initialize views
        nameEditText = findViewById(R.id.nameEditText);
        emailEditText = findViewById(R.id.emailEditText);
        saveButton = findViewById(R.id.saveButton);
 
        // Initialize view model
        viewModel = new ViewModelProvider(this).get(UserViewModel.class);
 
        // Set observer on user live data
        viewModel.getUserLiveData().observe(this, new Observer<User>() {
            @Override
            public void onChanged(User user) {
                nameEditText.setText(user.getName());
                emailEditText.setText(user.getEmail());
            }
        });
 
        // Set click listener on save button
        saveButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String name = nameEditText.getText().toString();
                String email = emailEditText.getText().toString();
                viewModel.updateUser(name, email);
            }
        });
    }
}
 
// ViewModel
public class UserViewModel extends ViewModel {
    private MutableLiveData<User> userLiveData = new MutableLiveData<>();
    private User user = new User();
 
    public UserViewModel() {
        userLiveData.setValue(user);
    }
 
    public LiveData<User> getUserLiveData() {
        return userLiveData;
    }
 
    public void updateUser(String name, String email) {
        user.setName(name);
        user.setEmail(email);
        userLiveData.setValue(user);
    }
}
java
打赏
  • 微信
  • 支付宝
评论
来发评论吧~
···

歌手: