Deep and Simple-MVP Model

Because of the use of MVP in the company's architecture model, I feel I am not familiar with it, so I decided to do this and summarize it for you.

Introduction of MVP Model

MVP is called Model View Presenter.
MVP can effectively reduce the complexity of View, avoid business logic being crammed into View, and prevent the code of View from becoming cumbersome. MVP mode can decouple View and Model, at the same time, it brings good scalability and testability, and ensures the system's cleanliness and flexibility.
For simple applications, MVP is a bit troublesome. Various interfaces and concepts make the whole application full of scattered interfaces. But for more complex applications, MVP is a good architecture model, which can organize application structure very well.

MVP mode can separate display layer and logic layer, which communicate through interface to reduce coupling. Idealized MVP implements the same logical code with different display interfaces, because they do not depend on specificity, but on abstraction.
In fact, the separation of View layer and Model layer is also a great improvement compared with MVC mode. We know that in Android, we need to change View through asynchrony. MVP mode cuts off the connection between View and Model, and connects them through asynchrony. This separation works well.
For a scalable and stable application, we need to define separate layers, mainly UI layer, business logic layer and data layer. After all, we don't know what logic to add in the future, retrieving data from local databases? Or from a remote server? Will our UI and database be replaced? For example, as the product upgrades, our UI may be redesigned. If the UI changes, then because the business logic is coupled in the View, the UI changes cause us to modify the new View control. At this time, you need to extract the specific business logic from the original View. This will be a very torturous and error-prone thing, and eventually you have to extract the business logic. Leave.
MVP is not a standardized model, it has many ways of implementation, we can also modify the implementation of MVP according to our own needs and the way we think is right, it can change with the complexity of Presenter. This is the right direction as long as we ensure that we decouple View and Model through Presenter, reduce type complexity, and that each module can be tested and changed independently.

II. Three Roles of MVP Model

1.Presenter --- Interactive middleman
Presenter serves as a bridge between View and Model. It retrieves data from Model layer and returns it to View layer, which makes no coupling between View and Model and separates business logic from View role.
2.View - User Interface
View is usually an Activity, Fragment, or a View control that contains a Presenter member variable. Usually View needs to implement a logical interface to transfer the operation on View to Presenter for implementation. Finally, Presenter calls the View logical interface to return the result to the View element.
3.Model - Access to Data
For a structured APP, the Model role is primarily to provide access to data. Presenter needs to store and retrieve data through the Model layer, which is like a data warehouse. To be more straightforward, Model encapsulates the role of database DAO or network data acquisition, or a collection of two data acquisition methods.

3. Examples of MVP

With so many concepts, here we apply our MVP model with a simple login business logic.

3.1
First, let's look at the overall structure.

The bean layer represents the model layer
The presenter layer represents the interaction between the data and the View layer.
The view layer is the view layer.
IUserBiz is an interface, and UserBiz is the implementation class of this interface.

3.2
First look at the model layer
This class is relatively simple, that is, defining some variables and methods.

public class User {
    private String usename;
    private String password;

    public String getUsename() {
        return usename;
    }
    public void setUsename(String usename) {
        this.usename = usename;
    }
    public String getPassword() {
        return password;
    }

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

Then look at IUserbiz and its implementation class IUserBiz, simulate login operation, etc. The login operation is finished, and there is a callback interface to notify the login status is completed.

public interface IUserBiz {
    public void login(String username,String password,OnLoginListener loginListener);
}
public class UserBiz implements IUserBiz {
    @Override
    public void login(final String username, final String password, final OnLoginListener loginListener) {
        //Analog Subthread Time-consuming Operation
       Thread thread=new Thread(new Runnable() {
           @Override
           public void run() {
               try{
                   Thread.sleep(2000);
               }catch (InterruptedException e){
                   e.printStackTrace();
               }
               //Simulated landing success
               if("aaa".equals(username)&&"123".equals(password)){
                   User user=new User();
                   user.setUsename(username);
                   user.setPassword(password);
                   //Callback interface
                   loginListener.loginsuccess(user);
               }else {
                   loginListener.loginFailed();
               }
           }
       });
       thread.start();
    }
}

Then look at the View layer. There are many ways to rewrite it. Design the interface according to your own experience and rigorous thinking.

public interface IUserLoginView {
    String getUsername();
    String getPassword();
    void clearUserName();
    void clearPassword();
    void showLoading();
    void hideLoading();
    void toMainActivity(User user);
    void showFailedError();
}

Let's continue to look at the implementation class, our activity, where we implemented the method we just defined because we used the MVP design pattern and used our interface to make our code look very clear.

public class UserLoginActivity extends AppCompatActivity implements IUserLoginView {
...........
 @Override
    public String getUsername() {
        return etUsername.getText().toString();
    }

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

    @Override
    public void clearUserName() {
          etUsername.setText("");
    }

    @Override
    public void clearPassword() {
          etPassword.setText("");
    }

    @Override
    public void showLoading() {
        mPbLoading.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideLoading() {
       mPbLoading.setVisibility(View.GONE);
    }

    @Override
    public void toMainActivity(User user) {
        Toast.makeText(this,user.getUsename()+"login success,to MainActivity",Toast.LENGTH_LONG).show();
    }

    @Override
    public void showFailedError() {
      Toast.makeText(this,"login failed",Toast.LENGTH_LONG).show();
    }
}
.....
}

Finally, look at our Presenter, which represents the bridge of data and view interaction. The method is relatively simple. It contains specific interaction operations, and the logic is very clear.

public class UserLoginPresenter {
...
   public void login(){
        userLoginView.showLoading();
        //Implementation interface
        userBiz.login(userLoginView.getUsername(), userLoginView.getPassword(), new OnLoginListener() {
            @Override
            public void loginsuccess(final User user) {
                //Need to be executed in UI threads
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                   userLoginView.toMainActivity(user);
                   userLoginView.hideLoading();
                    }
                });
            }

            @Override
            public void loginFailed() {
                //Need to be executed in UI threads
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    userLoginView.showFailedError();
                    userLoginView.hideLoading();
                }
            });
            }
        });
    }
    }

Source Connection:
demo portal

Keywords: Database Android Fragment network

Added by cleartango on Mon, 20 May 2019 04:43:46 +0300