current position:Home>Android architecture MVC MVP MVVM + instance

Android architecture MVC MVP MVVM + instance

2022-01-27 03:43:57 Android Shuai times

This is my participation 8 The fourth of the yuegengwen challenge 8 God , Check out the activity details :8 Yuegengwen challenge

Preface

MVC,MVP and MVVM These are three commonly used software architectures , The purpose of these three architectures is to separate , Avoid piling up too much logic in one class .

stay Android in ,Activity There is already UI Related processing logic , And data acquisition logic , Which leads to Activity The logic is complex, not single and difficult to maintain .

For a better maintenance and expansion of an application , We need to distinguish the relevant levels well , Otherwise, when the data acquisition method is changed from database to network acquisition in the future , We need to modify the whole Activity. Architecture makes View And data are independent of each other , We divide the application into three different levels , So we can test the relevant levels separately , Using architecture can transform most logic from Activity Remove , Easy to unit test .

MVC What is it? ?

MVC It's a model (Model)- View (View)- controller (Controller) Abbreviation , Using a business logic 、 data 、 The interface displays the separated method organization code . Actually Android Studio The pattern of creating a project is a simplified mvc Pattern .

Android Medium MVC meaning

  • Model: Entity class ( Data acquisition 、 Storage 、 Data state changes ).
  • View: Layout file
  • Controller:Activity( Processing data 、 Business and UI).

working principle

  • 1.View Accept user interaction requests .
  • 2.View Forward the request to Controller.
  • 3.Controller operation Model Update the data .
  • 4. After the data update ,Model notice View Data changes .
  • 5.View Display the updated data .

MVC The shortcomings of

With the increasing complexity of the interface and its logic ,Activity The responsibilities of class are increasing , So that it becomes huge and bloated .

In order to solve MVC The shortcomings of ,MVP The framework is proposed .

MVP What is it?

MVP yes MVC An evolutionary version of the architecture , The full name is Model-View-Presenter. take MVC Medium V and C Combine to produce MVP Medium V, Introduce new partners Presenter.

Android Medium MVP meaning

  • Model: Entity class ( Data acquisition 、 Storage 、 Data state changes ).
  • View: Layout file +Activity.
  • Presenter: The mediation , Be responsible for the completion of View And Model The interaction and business logic between .

working principle

  • 1.View Receive user interaction requests
  • 2.View Forward the request to Presenter(V call P Interface )
  • 3.Presenter operation Model Update the data (P call M Interface )
  • 4.Model notice Presenter Data changes (M call P Interface )
  • 5.Presenter to update View data (P Execution interface ,V Corresponding callback )

MVP The advantages of

  • 1. Complex logical processing is placed in Presenter To deal with , Less Activity The bloated .
  • 2. decoupling .Model Layer and View The layers are completely separated , modify V Layers do not affect M layer , Reduced coupling .
  • 3. You can put a Presenter For multiple views , It doesn't need to change Presenter The logic of .
  • 4.Presenter Layer and View The interaction between layers is carried out through interfaces , Easy to unit test .

MVP The shortcomings of

Difficult to maintain .Presenter In addition to business logic , And a lot of View->Model,Model->View Manual synchronization logic of , cause Presenter It's bulky , It will be difficult to maintain .

MVVM What is it?

yes Model-View-ViewModel Abbreviation .MVVM And MVP The structure of is still very similar , Namely take Presenter Upgrade to ViewModel. stay MVVM in ,View Layer and the Model Layers are carried out. Two way binding ( namely Data Binding), therefore Model The change of data will be shown in View On , vice versa .ViewModel It is used to deal with... According to the specific situation View or Model The change of .

Android Medium MVVM meaning

  • Model: Entity class ( Data acquisition 、 Storage 、 Data state changes ).
  • View: Layout file +Activity.
  • ViewModel: Correlation layer , take Model and View Binding ,Model or View When changes , Refresh each other in real time .

working principle

  • 1.View Receive user interaction requests
  • 2.View Forward the request to ViewModel
  • 3.ViewModel operation Model Data update
  • 4.Model Update the data , notice ViewModel Data changes
  • 5.ViewModel to update View data

View/Model The change of , Just change one side , The other party can update to

MVVM The advantages of

  • 1. Improve maintainability .Data Binding It can realize two-way interaction , The coupling between the view and the control layer is further reduced , More complete separation , At the same time, it reduces Activity The pressure of the .
  • 2. Simplify testing . Because the synchronization logic is handed over to Binder It's done ,View follow Model Change at the same time , So just make sure Model The correctness of the ,View That's right . Greatly reduce the need for View Synchronous update test .
  • 3.ViewModle Easy to unit test .

MVVM The shortcomings of

  • 1. For simple projects , Use MVVM A little overqualified .
  • 2. For big projects , Data binding can lead to high memory overhead , Affect performance .
  • 3.ViewModel and View The binding of , Make page exception tracking inconvenient . It could be View error , It could be ViewModel There is something wrong with the business logic of , It could be Model Error in data of .

MVP and MVC The biggest difference

stay MVP in View Not directly used Model, The communication between them is through Presenter To carry out , All the interactions take place in Presenter Inside , And in the MVC in View Directly from Model Instead of reading data through Controller.

How to select a frame

It was supposed to write an applicable scenario for each pattern , Finally, think that everyone has their own understanding , Don't be bound by others .

In a word : What suits you is the best !

example

Just such an interface, let's pass MVC、MVP、MVVM Build them separately .

MVC example

The code structure

1. stay layout Create a layout file

    <!-- Reduced Edition -->
    <LinearLayout ...>
        <EditText android:id="@+id/et_account" .../>
    </LinearLayout>
    <LinearLayout ...>
        <EditText android:id="@+id/et_password" .../>
    </LinearLayout>
    <Button android:id="@+id/btn_login" .../>
    <Button android:id="@+id/btn_back" .../>
 Copy code 

2. Entity class (User)

public class User {
    private String name;
    private String password;
    public User() {}
    //set or get ...
    public User(String name, String password) {
        this.name = name;
        this.password = password;
    }
}
 Copy code 

3.MVCLoginActivity

// User click event 
mvcBinding.mcvLogin.btnLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                user.setName(mvcBinding.mcvLogin.etAccount.getText().toString());
                user.setPassword(mvcBinding.mcvLogin.etPassword.getText().toString());
                login(user);
            }
});
// Logical processing 
private void login(User user){
        if(!user.getName().isEmpty()&&!user.getPassword().isEmpty()){
            if(user.getName().equals("scc001")&&user.getPassword().equals("111111"))
            {
                Toast.makeText(this," Login successful ",Toast.LENGTH_SHORT).show();
            }else{
                Toast.makeText(this," Login failed ",Toast.LENGTH_SHORT).show();
            }
        }else {
            Toast.makeText(this," Login failed ",Toast.LENGTH_SHORT).show();
        }
    }
 Copy code 

MVP example

The code structure

1.Model layer

Entity class bean, Same as MVC Medium User class , Don't post code, waste everyone's time .

Model The business logic to be executed by the layer

/** *  function : Interface , Express Model The business logic to be executed by the layer  */
public interface LoginModel {
    //User Entity class ;OnLoginFinishedListener presenter Return result of business logic 
    void login(User user, OnLoginFinishedListener listener);
}
 Copy code 

Implementation class ( Realization LoginModel Interface )

/** *  function : Realization Model Layer logic  */
public class LoginModelImpl implements LoginModel {
    // The first 4 Step : Verify account password 
    @Override
    public void login(User user, OnLoginFinishedListener listener) {
        if(user.getName().isEmpty()||!user.getName().equals("scc001")){
            // The first 5 Step :Model Callback inside the layer Presenter layer listener
            listener.onUserNameError();
        }else if(user.getPassword().isEmpty()||!user.getPassword().equals("111111")){
            // The first 5 Step :Model Callback inside the layer Presenter layer listener
            listener.onPasswordError();
        }else {
            // The first 5 Step :Model Callback inside the layer Presenter layer listener
            listener.onSuccess();
        }
    }
}
 Copy code 

2.Presenter layer

When Model The layer gets the requested result , Callback Presenter layer , Give Way Presenter Layer calls View Layer interface method .

/** *  function : When Model The layer gets the requested result , Callback Presenter layer , Give Way Presenter Layer calls View Layer interface method . */
public interface OnLoginFinishedListener {
    void onUserNameError();

    void onPasswordError();

    void onSuccess();
}
 Copy code 

Complete login verification , And destroy the current View.

/** *  function : Logon Presenter The interface of , The implementation class for LoginPresenterImpl, *  Complete login verification , And destroy the current View. */
public interface LoginPresenter {
    // Complete login verification 
    void verifyData(User user);
    // Destroy current View
    void onDestroy();
}
 Copy code 

Presenter Implementation class , introduce LoginModel(model) and LoginView(view) References to

/** *  function : Implementation class , introduce  LoginModel(model) and LoginView(view) References to  */
public class LoginPresenterImpl implements OnLoginFinishedListener, LoginPresenter {
    //View Layer interface 
    private LoginView loginView;
    //Model Layer interface 
    private LoginModel loginModel;

    public LoginPresenterImpl(LoginView loginView) {
        this.loginView = loginView;
        this.loginModel = new LoginModelImpl();
    }
    // The first 6 Step : adopt OnLoginFinishedListener The verification result is returned to Presenter layer 
    @Override
    public void onUserNameError() {
        if (loginView != null) {
            // The first 7 Step : adopt loginView Back to View layer 
            loginView.setUserNameError();
            loginView.hideProgress();
        }

    }
    // The first 6 Step : adopt OnLoginFinishedListener The verification result is returned to Presenter layer 
    @Override
    public void onPasswordError() {
        if (loginView != null) {
            // The first 7 Step : adopt loginView Back to View layer 
            loginView.setPasswordError();
            loginView.hideProgress();
        }
    }
    // The first 6 Step : adopt OnLoginFinishedListener The verification result is returned to Presenter layer 
    @Override
    public void onSuccess() {
        if (loginView != null) {
            // The first 7 Step : adopt loginView Back to View layer 
            loginView.success();
            loginView.hideProgress();
        }
    }


    @Override
    public void verifyData(User user) {
        if (loginView != null) {
            loginView.showProgress();
        }
        // The first 3 Step : call model layer LoginModel Interface login() Method 
        loginModel.login(user,this);
    }

    @Override
    public void onDestroy() {
        loginView = null;
    }
}
 Copy code 

3.View layer

The layout file is the same as MVC Medium View layer , Don't post code, waste everyone's time .

Presenter And View Interaction is through interfaces .

/** *  function :Presenter And View Interaction is through interfaces . *  The definition of methods in the interface is based on Activity The controls that need to be displayed for user interaction are determined . */
public interface LoginView {
    //login It's a time-consuming operation , Loading ( It's usually used ProgressBar)
    void showProgress();
    // Loading complete 
    void hideProgress();
    //login If the account fails, give a prompt 
    void setUserNameError();
    //login If the password fails, give a prompt 
    void setPasswordError();
    //login success 
    void success();
}

 Copy code 

MVPLoginActivity

/** *  function : Need to achieve LoginView Interface . */
public class MVPLoginActivity extends AppCompatActivity implements LoginView {
    LoginPresenterImpl loginPresenterImpl;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        ...
        // Create a Presenter object 
        loginPresenterImpl = new LoginPresenterImpl(MVPLoginActivity.this);
        // The first 1 Step : The user clicks login 
        mvpBinding.mvpLogin.btnLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                User user = new User();
                user.setName(mvpBinding.mvpLogin.etAccount.getText().toString());
                user.setPassword(mvpBinding.mvpLogin.etPassword.getText().toString());
                // The first 2 Step : call Presenter Verification method in interface 
                loginPresenterImpl.verifyData(user);
            }
        });
    }

    @Override
    public void showProgress() {
        // Loading 
    }

    @Override
    public void hideProgress() {
        // Loading complete 
    }

    @Override
    public void setUserNameError() {
        // The first 7 Step : adopt loginView Back to View layer 
        // Wrong account number 
        Toast.makeText(this," Login failed ",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void setPasswordError() {
        // The first 7 Step : adopt loginView Back to View layer 
        // Wrong password 
        Toast.makeText(this," Login failed ",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void success() {
        // The first 7 Step : adopt loginView Back to View layer 
        Toast.makeText(this," Login successful ",Toast.LENGTH_SHORT).show();
        // Login successful 
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        loginPresenterImpl.onDestroy();
    }
}
 Copy code 

MVVM example

1.Model layer

Entity class bean, Same as MVC Medium User class , Don't post code, waste everyone's time .

2.ViewModel layer

ViewModel class , Inherited from ViewModel

public class LoginViewModel extends ViewModel {
    public ViewDataBinding binding;
    public LoginViewModel(ViewDataBinding binding){
        this.binding = binding;
    }
    public void getUser(String userName, String password, Callback callback) {
        // Logical processing 
        User user = new User();
        user.setPassword("111111");
        if(userName.isEmpty()||!userName.equals("scc001")){
            user.setName("scc005");
        }else if(password.isEmpty()||!password.equals("111111")){
            user.setName("scc004");
        }else {
            user.setName("scc003");
        }
        callback.onCallBack(user);
    }
}
 Copy code 

ViewModel And View Interaction

/** *  function :ViewModel And View Interaction . */
public interface Callback<T> {
    void onCallBack(T t);
}
 Copy code 

3.View layer

First look at the layout file , The layout file uses DataBinding.

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <!-- Create a new variable name for the introduced class , It is convenient to use below -->
        <variable name="user" type="com.scc.architecture.mvvm.model.User" />
    </data>
    <!-- Abridged edition -->
    <LinearLayout ...>
        <LinearLayout ...>
            <EditText android:id="@+id/et_account" ... android:text="@={user.name}" />
        </LinearLayout>

        <LinearLayout ...>
            <EditText android:id="@+id/et_password" ... android:text="@={user.password}" />
        </LinearLayout>

        <Button android:id="@+id/btn_login" .../>
    </LinearLayout>
</layout>
 Copy code 

Originally Button Click event also want to use databinding To do , Later I thought this was MVP The pattern ignores this knowledge point , If you are interested, you can do it yourself ,databinding It's still fun .

MVVMLoginActivity

public class MVVMLoginActivity extends AppCompatActivity {
    private LoginViewModel loginVM;
    ActivityMvvmBinding mvvmBinding;
    private EditText et_account,et_password;
    private Button btn_login,btn_back;
    private TextView tv_title;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mvvmBinding = DataBindingUtil.setContentView(this, R.layout.activity_mvvm);
        et_account =findViewById(R.id.et_account);
        et_password =findViewById(R.id.et_password);
        btn_login = findViewById(R.id.btn_login);
        tv_title = findViewById(R.id.tv_title);
        tv_title.setText("MVVM");

        loginVM = new LoginViewModel(mvvmBinding);
        User user = new User( "scc001", "111111");
        mvvmBinding.setUser(user);// Set up et_account:scc001|et_password:111111
        // The first 1 Step : The user clicks login 
        btn_login.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                login(et_account.getText().toString(),et_password.getText().toString());
            }
        });
    }
    private void login(String name,String password) {
        loginVM.getUser(name,password, new Callback<User>() {
            @Override
            public void onCallBack(User user) {
                mvvmBinding.setUser(user);// Sync settings control 
            }
        });
    }
}

 Copy code 

Write here MVC、MCP、MVVM And examples are basically finished , But I feel I don't understand very well , It's better to have a big man to give advice . Last , I hope it can be used for reference .

Instance portal

copyright notice
author[Android Shuai times],Please bring the original link to reprint, thank you.
https://en.cdmana.com/2022/01/202201270343552816.html

Random recommended