Although MVP is irrelevant to any specific framework or technology, this seriesArticlePlease understand that the problem is explained only by DOTNET-related technologies or frameworks.
. Net prevalence
The emergence of. NET is undoubtedly a revolution. Early development requires the compilation of CGI using C, C ++, Pascal, etc.ProgramThe development of Web applications requires a high technical threshold (of course, I heard from the older generation that the salary was also high) and the use of pure ASP. NET development of web programs, low threshold, or even no need to write anyCodeSimply implementing a simple application (of course, I personally think this application has little value), which brings the gospel to the wide range of web developers, and many people turn to it. net, I remember that at school, I installed a Visual Studio in the form (I remember that:Beta 2), I wrote two lines of code. I remember that I had to manually create a virtual directory and press F5 to open the webpage. At that time, I was excited.
Microsoft has indeed created a simple, easy-to-use and powerful development platform for us. It has saved development time, improved work efficiency, and won the favor of countless developers, but it is easy to use and brings about some small "problems" (other platforms may also have the same problem ).
Webform Problems
Since we are all engaged in program writing code, let's start with a piece of code. Please refer:
{
SqldataadapterAdapter =New Sqldataadapter("Select * From Table1","Server =.; database = dB; uid = sa; Pwd = password");
DatasetDS =New Dataset("Ds1");
Adapter. Fill (DS );
This. Gridview1.datasource = Ds;
This. Gridview1.databind ();
}
The above code is standard ASP. net background code. It has no logic errors and the running results are correct. However, it has a problem. A very serious problem is that we are all people in the blog Park, we are all people with specific development ideas. We are all people with identities (certificates). We must know the "layering" thing. Right, the above Code is on the UI Layer, however, if you do something you shouldn't do (it is clearly a cock, but it's done), it will lead to chaotic responsibilities. It will access business logic and data, the interface display logic is stored in a piece of code, which is not conducive to code reading, maintenance, upgrade, or testing. Of course, if your project is very small.
Of course, the above is only from the perspective of layering, pointing out ASP. net, it does not constrain developers to pay attention to layering when writing programs, Asp. net advantages and other defects are not highlighted here.
MVP Mode
When realizing this problem, it seems that the emergence of a good solution is not far away, castle open-source organization thought of ASP. the MVC model is used in net and monorails is developed. The first Asp.net version of MVC framework should be the MVC model2 model. The MVC model is a good hierarchical model with many variants, among them, model2 is a fairly correct variant, and a large number of developers have manually implemented this model in their own projects. The emergence of Asp.net MVC framework has been thoroughly popularized. net Framework Based on the MVC model idea, a large number of developers began to study ASP. net MVC framework, I remember my best friend is one of them, and it is applied to his open-source project chsns.
MVPs are another variant of the MVC model. MVPs can be applied to WEB projects or winform projects, its convenient Testing Mechanism brings the gospel to large and complex enterprise-level applications. It is a hierarchical diagram of the MVP mode based on my understanding.
You can see that MVP has three layers: Model-presenter-view. below is the sequence diagram.
The Controller layer is responsible for status saving and page flow. Sometimes, controller participation is required as needed.
According to the comprehensive analysis of the above images, the presenter is equivalent to the intermediary. It is responsible for receiving the requests sent by the view, calling the model service interface, and the presenter then reflects the processing results to the view, presenter can not make a strong reference to the view layer, but can reference interfaces, so that any presenter does not depend on any specific view, but depends on the specific interface of the preview, A view interface can be implemented in several ways. Most of the presentation logic is in the presenter layer. It is a specific class with a high testability level. At the same time, presenter has nothing to do with web or win, this increases the testability of MVPs. The specific implementation of the view has a strong reference to the presenter. During the test, we only need to create a mock view and implement the view to implement the iview interface. Then we can test it. Therefore, I think it is more appropriate to use the MVP model for complicated enterprise-level applications.
The view layer is the specific implementation of a series of view conventions (View Interface classes) and views. The view conventions determine the information that can be obtained from the view and the interfaces that can be called to update the view. The following code is developed by me. I am preparing an open-source SNS website written using the MVP architecture for sending and editing diaries.Source code:
/// <Summary>
/// View Interface for sending and editing diaries on the SNS website
/// </Summary>
Public interface isendview
{
/// <Summary>
/// Diary category ID
/// </Summary>
String catid
{
Get;
}
/// <Summary>
/// Diary title
/// </Summary>
String diarytitle
{
Get;
}
/// <Summary>
/// The log Content
/// </Summary>
String content
{
Get;
}
/// <Summary>
/// Friend ID mentioned in the diary, separated by commas
/// </Summary>
String aboutuserids
{
Get;
}
/// <Summary>
/// Whether it is a private diary
/// </Summary>
Bool isprivate
{
Get;
}
/// <Summary>
/// Diary ID
/// </Summary>
String did
{
Get;
}
/// <Summary>
/// Bind the log category, which is an optional log category.
/// </Summary>
/// <Param name = "Infos"> category information list </param>
Void bindcategories (list <diarycategory> Infos );
/// <Summary>
/// Bind the log Content to edit the prepared log
/// </Summary>
/// <Param name = "Diary"> diary entity </param>
Void binddiary (spiderweb. Models. Diary diary );
}
View implementation class for sending and editing Diaries:
Public partial class send: Microsoft. Practices. compositeweb. Web. UI. Page, isendview
{
Private sendpresenter _ presenter;
protected void page_load (Object sender, eventargs e)
{< br> If (! This. ispostback)
{< br> This. _ presenter. onviewinitialized ();
}< br> This. _ presenter. onviewloaded ();
}
[createnew]
Public sendpresenter presenter
{< br> Get
{< br> return this. _ presenter;
}< br> set
{< br> If (value = NULL)
throw new argumentnullexception ("value ");
This. _ presenter = value;
This. _ presenter. view = this;
}
}
Protected void btnsend_click (Object sender, eventargs E)
{
Presenter. onsend ();
}
# Region isendview Member
Public String catid
{
Get {return request. Form [This. ddlcats. uniqueid];}
}
Public String content
{
Get {return this. example_textarea.text ;}
}
Public String aboutuserids
{
Get {return this. selectfriendsusercontrol1.userids ;}
}
Public bool isprivate
{
Get {return chkprivacy. Checked ;}
}
Public void bindcategories (system. Collections. Generic. List <spiderweb. Models. diarycategory> Infos)
{
This. ddlcats. datasource = Infos;
This. ddlcats. databind ();
}
Public String diarytitle
{
Get {return this.txt title. Text ;}
}
Public String did
{
Get {return request ["did"];}
}
Public void binddiary (spiderweb. Models. Diary diary)
{
This.txt title. Text = diary. title;
This. example_textarea.text = diary. content;
This. chkprivacy. Checked = diary. isprivate. value;
This. ddlcats. selectedvalue = diary. catid. value. tostring ();
}
# Endregion
}
The base class of the view implementation class is an ASP. NET page, which implements the isendview interface and provides convenience for the presenter to obtain view information and refresh the view.
Source code of the presenter class:
Public class sendpresenter: presenter <isendview>
{
Private idiarycontroller _ controller;
Idiaryservice _ diaryservice;
Public sendpresenter ([createnew] idiarycontroller, [servicedependency] idiaryservice diaryservice)
{
_ Controller = controller;
_ Diaryservice = diaryservice;
}
Public override void onviewloaded ()
{
}
Public override void onviewinitialized ()
{
// Call the service and initialize the user interface
View. bindcategories (_ diaryservice. getcategories (_ controller. currentuserid ));
If (! String. isnullorempty (view. Did ))
{
Spiderweb. Models. Diary diary = _ diaryservice. getdiarybydid (_ controller. currentuserid, view. Did );
View. binddiary (diary );
}
}
Public void onsend ()
{
// The controller sends the diary and redirects the page.
_ Controller. Send (view. Did, view. catid, view. diarytitle, view. Content, view. isprivate, view. aboutuserids );
}
}
It can be seen from the code that the presenter class communicates with the Controller (idiarycontroller) and model layer (idiaryservice), but all of them are interface dependencies, so it is very convenient to test.
Presenter and the view layer define a mandatory convention, that is, isendview must be implemented, which avoids some errors to some extent, whether during development or runtime. The following is the code of the view implementation class used during the test:
Public class testsenddiary: isendview
{
# Region isendview Member
Public String catid
{
Get {return "001 ";}
}
Public String diarytitle
{
Get {return "Diary title ";}
}
Public String content
{
Get {return "Diary content ";}
}
Public String aboutuserids
{
Get{ return "001,002,003 ";}
}
Public bool isprivate
{
Get {return false ;}
}
Public String did
{
Get {return "001 ";}
}
Public void bindcategories (list <spiderweb. Models. diarycategory> Infos)
{
}
Public void binddiary (spiderweb. Models. Diary diary)
{
Console. writeline (diary. Title );
}
# Endregion
}
The following code is called during a test:
Sendpresenter presenter = new sendpresenter ();
Presenter. view = new testsenddiary ();
// Publish a diary
Presenter. onsend ();
We can perform MVP testing in winform or console applications, which is very convenient. Of course, we can also use the test tool provided by MS for testing.
In short, the MVP mode has an irreplaceable advantage, indicating that the logic can exist independently of the UI platform, and it can also process different views that implement the same protocol. Its convenient testing has brought a lot of convenience to complex enterprise application development. Of course, if your application is very simple, I suggest you do not use MVP because it is a waste of resources.