The MVP architecture analysis of Open source project Philm

Source: Internet
Author: User

Objective
Recently, I have been studying Chrisbannes's Open source project Philm, its overall architecture is a set of MVP implementation, because I did not encounter the whole project using the MVP architecture, see more is some code snippets, Here is a discussion of how Philm combines the actual Android problem to achieve an MVP architecture, if there is inaccurate analysis of the place, welcome to point out, we discuss together.
Project Address: Https://github.com/Juneor/philm
Philm Project operation (typical material design style):


1. A brief talk about MVP
In the absence of any mode of development, activity and model layer of the relationship is too close, do all the operation, difficult to maintain, poor scalability. For example, our later requirements may not be from the database to obtain data, but from the network, or there is a version of all the UI to make a big revision, (with the advent of materialdesign, I think this is still possible), if all the logic in the activity, So bloated code, how to modify all the effort, or you have to adapt to multiple sets of UI, such as tablet, maintenance is also very troublesome.

1.2 MVP

MVP is a derivative of MVC, and the MVP model does not allow the view to access model directly, which is the biggest difference between MVP and MVC. There should be only UI logic in view, capturing user input and rendering of views. This puts the other complex logic out of the presenter and puts it in the middle of the box, so there is the MVP. This model is the same as the traditional software engineering idea, which reduces the coupling degree, modularization and more convenient maintenance. Presenter usually interacts with view through a well-defined interface, so when developing, it is necessary to write a test class to implement the interface to simulate the user's various operations to test, without the use of automated test tools. Even without having to rerun the app on your phone every time, the test is more efficient.

Simply put, the complex work in view is pumped into the presenter, reducing coupling, ease of maintenance and testing, and enhanced reusability.

There are usually 4 elements in MVP mode
(1) View: Responsible for drawing UI elements, interacting with the user (activity or fragment);
(2) View Interface:view interface to be implemented, the view interacts with the presenter through the view interface to reduce coupling and facilitate unit testing
(3) Model: Responsible for operation of the business bean.
(4) Presenter: As a link between view and model, it carries most of the complex logic.

The advantages of MVP
1, model and view are completely separated, they interact through the interface, easy to maintain and test.
2. Model can be used more efficiently, as all operations on model are inside presenter.
3, we can use a presener for multiple views, only need to define the view Interface for different view in presenter, the specific view realizes its own view Interface, You can use the model operation in presenter, and so on.

More information and discussion on MVP can be found at the end of the article RELATED links

    1. The implementation of the MVP architecture
      The specific implementation of the MVP is not standard, because a project to consider a lot of factors, you can follow your own habits and needs of the specific implementation. Let's analyze the MVP architecture implemented in Philm.

The overall design of 2.1 philm
Philm used a controller to manage the model, View, and according to the above MVP understanding and the actual work of the controller, this controller is actually equivalent to the above presenter, But this controller is more complex, within the controller, directly define the MVP of the View and presenter interface callback, in addition to the project introduced the concept of State (see below for details), Unified management of the model and business needs of the event, all activity and fragment jump and titlebar and drawer management using a display to achieve.

Class Diagram Relationships:

Basic Call Flowchart:

2.2 Core Concepts
2.2.1 Controller
Control center, simple can be considered MVP in the presenter, but it is more complex. Unified management Interface State initialization and state cleanup, rendering all the UI and adding CallBack, unified scheduling business-related background task thread, subscribe to the event defined in the states, to update the view. And the view Interface of view and presenter are defined uniformly, a controller can define view Interface for multiple view, so the controller can be shared by multiple view.

2.2.2 State
Save the industry beans used by the interface to define the event events used in the business.

Each interface has its own state interface, ApplicationState is responsible for unifying all state interfaces, applicationstate acts as a Communicator for UI and background threads, and enables the distribution of business beans and the distribution of events to be saved.

When using a controller for populate, the business bean is fetched from the state, and if not in state, the controller initiates a background thread to request the data, and after the data is successfully fetched, it is saved to state by State.set () distribution. At the same time, an event notification Controller is post for corresponding processing.

Event types defined in state
Asynchronous request completion notification, data changes, network status changes, loadingprogress display and hide, which is why state was separate out of the reason for it, unified storage model and defined the various states, note The model does not do complex operations, but simple set and get, complex operations are all handled by the controller.

2.2.3 Display
Unified control of TitleBar, drawer, and all activity and fragment jumps, no business logic operations.

    1. Core class Analysis
      3.1 Basecontroller
      3.1.1 Core Approach
      (1) Init ()
      All controller initialization methods, initiated by Mmaincontroller.init () in basephilmactivity, all controllers are controlled uniformly by Mainctroller.
publicfinalvoidinit() {    false"Already inited");    true;    onInited();}

(2) Suspend

publicfinalvoidsuspend() {    true"Not inited");    onSuspended();    false;}

3.2 Baseuicontroller
A unified definition of all UI, events, and interfaces that manage an interface.
Obtain the appropriate controller when used in view (this is activity or fragment), and then call Getcontroller () in Onresume. Attachui (), set callback for view, Then populate, call Getcontroller () in OnPause. Detachui (this) clears all the callback of the UI and the cleanup of other states.

Each controller has its own uicallbacks, and a UI that inherits from Baseuicontroller.ui.

Controller can be shared.
Within the controller, you can also define the corresponding uicallback for different view, because different view may use the same model,state and other events, different view only need to implement the controller defined in the The relevant callback can be. Of course, the uicallback needs to inherit the UI that implements Baseuicontroller.ui, because eventually it will be passed into Baseuicontroller for Setcallbacks (UC).

3.2.1 Important Member variables
MUis: For storing all the UI
Munmodifiableuis:muis copy, but not modifiable
UI interface
The UI for all controller subclasses needs to implement the UI interface, with the ability to callback the controller Attachui for incoming UI settings callback

publicinterface Ui<UC> {    void setCallbacks(UC callbacks);    boolean isModal();}

3.2.2 Important methods
3.2.2.1 Attachui (U UI)
Called in activity or fragment onresume to add callbacks, view rendering, and so on.
Final type, non-replication, only for the controller's implementation class for state management, if more operations are required, you can implement the Onuiattached (UI) method, which is called in Attachui.

public   Synchronized  final  void  attachui  (U UI) {preconditions.checkargument (UI! = null ,  "UI cannot be null" );    Preconditions.checkstate (!muis.contains (UI),  "UI is already attached" );    Muis.add (UI);    Ui.setcallbacks (Createuicallbacks (UI)); if  (Isinited ()) {if  (!ui.ismodal () &&! (        UI instanceof  subui) {Updatedisplaytitle (Getuititle (UI));        } onuiattached (UI);    Populateui (UI); }}

3.2.2.2 Detachui (U UI)
Called in the activity or fragment Onresume, emptying the callback.
Final type, non-reproducible, just to implement the class for state management, ibid. if there are more operations, you can implement the Onuidetached (UI) method.

publicsynchronizedfinalvoiddetachUi(U ui) {    null"ui cannot be null");    "ui is not attached");    onUiDetached(ui);    ui.setCallbacks(null);    mUis.remove(ui);}

3.2.2.3 oninited ()
When each controller is initialized, it is called without explicit invocation, because Maincontroller manages all the controllers in a unified The Onresume in Basephilmactivity is initialized by calling the Maincontroller.init () method uniformly.

protectedvoidonInited() {    if (!mUis.isEmpty()) {        for (U ui : mUis) {            onUiAttached(ui);            populateUi(ui);        }    }}

Each controller's own oninited method does some simple initialization such as registering events.

3.2.2.4 onsuspended ()
Cleans up the callbacks and cancels all registered event unregisterforevents.
It is also managed by the Maincontroller unification in Basephilmactivity's onpause.

@OverrideprotectedvoidonPause() {    mMainController.suspend();    mMainController.setHostCallbacks(null);    mMainController.detachDisplay(mDisplay);    super.onPause();}

3.2.2.5 Populate (UI)
Renders the view.

3.2.2.6 createuicallbacks (U UI)
The abstract type, used by the controller to create its own uicallback, is already called Ui.setcallbacks (Createuicallbacks (UI)) at Attachui (U UI), Set your own UI callback events for all UIs.

3.2.2.7 getId (U UI)
Set an ID for each background thread and event. When rendering is required, iterate through all the UI and Findui to find the target UI and update it.

protectedintgetId(U ui) {    return ui.hashCode();}

3.2.2.8 Findui (final int id)
corresponding to the GetID (U UI), gets the ID of the background thread or event.

3.2.2.9 populateuifromevent
Populateuifromevent (Basestate.uicausedevent event)
When some data is updated, when the view needs to be updated, the method is called, an event is sent, and the Controller is notified of UI updates.

3.3 Maincontroller
3.3.1 oninited ()
Initialize the callback and state of all controllers

@OverrideprotectedvoidonInited() {    super.onInited();    mState.registerForEvents(this);    mUserController.init();    mMovieController.init();    mAboutController.init();}

3.3.2 onsuspended
Clean up the callback and status of all controllers

@OverrideprotectedvoidonSuspended() {    mAboutController.suspend();    mUserController.suspend();    mMovieController.suspend();    mDbHelper.close();    mState.unregisterForEvents(this);    super.onSuspended();}

3.4 basephilmactivity
Initiation of the Maincontroller of the entire project:

3.4.1 Important methods
3.3.1.1 onCreate

mMainController = PhilmApplication.from(thisnew AndroidDisplay(this, mDrawerLayout);

3.4.1.2 Onresume
Initialize all the states

 @Overrideprotected void Onresume() {Super. Onresume ();    Mmaincontroller.attachdisplay (Mdisplay); Mmaincontroller.sethostcallbacks ( This); Mmaincontroller.init ();} Public void Attachdisplay(Display display) {Preconditions.checknotnull (Display,"display is null"); Preconditions.checkstate (getdisplay () = =NULL,"We currently have a display"); Setdisplay (display);}@Overrideprotected void Setdisplay(Display display) {Super. Setdisplay (display);    Mmoviecontroller.setdisplay (display);    Musercontroller.setdisplay (display); Maboutcontroller.setdisplay (display);}

3.4.1.5 OnPause ()
Clear all the states

@OverrideprotectedvoidonPause() {    mMainController.suspend();    mMainController.setHostCallbacks(null);    mMainController.detachDisplay(mDisplay);    super.onPause();}

3.5 Fragment for implementing a specific controller's UI
3.5.1 Onresume
Get to your own controller for initialization

@OverridepublicvoidonResume() {    super.onResume();    getController().attachUi(this);}

3.5.2 OnPause
Get state cleanup to the appropriate controller

@OverridepublicvoidonPause() {    saveListViewPosition();    cancelToast();    getController().detachUi(this);    super.onPause();}

Summarize
The MVP architecture implemented in Philm follows the key principles of MVP: Isolate view and model. Because the entire project is based on this architecture, so consider more comprehensive, such as the unified management of the State, all controller unified management, unified callback management, using the Otto driver event to achieve decoupling between components. When you want your entire project to fully use the MVP architecture, the Philm framework is undoubtedly a very worthwhile implementation, and you can expand it to your own needs.
In addition, Philm also used the latest materialdesign design, some custom view, but also a good learning material.

The MVP architecture analysis of Open source project Philm

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.