Login or Sign Up to become a member!
LessThanDot Sit Logo

LessThanDot

All Blogs

Less Than Dot is a community of passionate IT professionals and enthusiasts dedicated to sharing technical knowledge, experience, and assistance. Inside you will find reference materials, interesting technical discussions, and expert tips and commentary. Once you register for an account you will have immediate access to the forums and all past articles and commentaries.

LTD Social Sitings

Lessthandot twitter Lessthandot Linkedin Lessthandot friendfeed Lessthandot facebook Lessthandot rss

Note: Watch for social icons on posts by your favorite authors to follow their postings on these and other social sites.

Your profile

    Search

    XML Feeds

    Google Ads

    Tags: passive view

    comments

    Model-View-Presenter is an architecture pattern that defines a structure for behavior and logic at the UI level. M-V-P separates the logic of the presentation, such as interacting with back-end services and the business layer, from the mechanics of displaying buttons and interface components.

    I often build small projects to help understand and grow my skills as a developer, architect, and all-around technologist (as may be apparent from the wide range of topics I post on). Today I worked with a combination of Visio and Visual Studio to build a sample project to play with the Passive View concept and to help grow my own understanding of the concept. This post will cover the Visio side of my learning-curve.

    You can read more about Model View Presenter at Wikipedia and MSDN. Perhaps the best information can be found on Martin Fowler's site, where he has separate write-ups on Passive View and Supervising Controller.

    Note: I know some people were waiting for another Virtual Lab entry this week, and here I am writing about Architecture instead. Don't worry, the virtual lab series will continue, I just felt like doing a write-up while I was playing this past weekend.

    Passive View

    Passive View is a subset of the Model-View-Presenter pattern. In Passive View, the interface is responsible for handling interface-specific logic, such as figuring out how to put a value in a textbox or react to events from button clicks, but all actions and logic outside of the raw UI are sent to the Presenter to execute or manage. The Presenter is responsible for calling business methods in the Business model and updating the data that is available in the View.

    Basic Model-View-Presenter diagram
    Basic Model-View-Presenter Diagram

    From the outside in, the architecture for Passive View looks something like this:

    • UI - The User Interface reflects what is going on beneath it by implementing one or more View interfaces
    • Presenter - The Presenter receives interactions from the UI or Model and updates the Views it is attached to
    • Model - The model is a facade or black box in our diagram, behind which is a business logic layer and data layer

    In a flat architecture we would collect data from the interface, perhaps do some business and data validation, and then save it directly to a database using stored procedures or inline SQL. Defining a data access layer (or data model like entity framework) allows our application to operate on cohesive, defined objects that are meaningful to the application and stored and retrieved consistently. Defining a business logic layer allows us to centralize business rules that operate on entities in our application in a manner that is consistent with the business and internally consistent in the application, minimizing the risk that occurs when making changes to the business flow. Separating the logic of populating inputs and responding to button presses on the UI from the information being communicated to the end user and conceptual responses to their input allows the system to interact with the user consistently across any number of interfaces into the same application.

    The definition of each level increases our ability to automate testing and supports greater Separation of Concerns.

    Implementing a Sample Project

    My learning exercise has been the the creation of an ASP.Net search page that allows an end user (customer) to search for finished products from the AdventureWorks sample database. The architecture and design decisions were done as an exercise in Visio using simple shapes and layouts.

    My example application has several functional and non-functional requirements:

    1. Functional - Display product number, name, list price, and available quantity in tabular format
    2. Functional - Provide a basic search input and button to search product names
    3. Non-Functional - Implement an M-V-P pattern - Obviously the purpose of this whole exercise
    4. Non-Functional - Use a simple model stack that can be easily replaced with a Service-Oriented one at a later time
    5. Non-Functional - Build with the idea that we will later create a Silverlight or WPF front-end
    6. Non-Functional - Make pretty pictures for article

    My unwritten, final requirement was to finish the whole thing in half a day, though luckily I didn't define whether I intended that to mean 4 hours or 12.

    Initial Architecture

    To start I created a diagram of the application architecture:

    More extensive M-V-P Diagram
    More Extensive Model-View-Presenter Diagram

    The purple layer is my presentation layer, which reflects the View. The blue layer is my Presenter layer which contains the logic for interacting between the end user and interface as well as a definition, or contract, of the information available in the View. The Green is the Model (or is behind the model, depending on your viewpoint) and exposes business functions and data entities for the Presenter to interact with.

    Class Layout

    Once the high level diagram was completed, I could approach the task of creating some base classes and interfaces to use in implementing the project.

    • Model.IModel - Generic Model Interface to expose business calls to Presenters
    • Presenter.IView - Generic View Interface that all Presenters can interact with and all screens implement
    • Presenter.BasePresenter - Generic Presenter class that all Presenters will implement

    To keep the project to a single morning but also allow the ability to come back and build a more architecturally sound solution, I implemented the Model in a very basic fashion that was referenced locally by the Presenter project and makes direct calls to SQL Server using ADO and parametrized, inline SQL. This buys me the benefits of having a well-defined Model (via the interface) but allows me concentrate my time and effort on the learning part of the project (ie, the M-V-P interaction and structure). Defining the model interface also leaves me open to come back and replace it with better separated code and the ability to create a model that acts as a facade to a service stack, instead of local DLLs.

    • Model.BasicModel.Model - Basic implementation of a model that will interact with AdventureWorks on SQL Server
    • Model.Entities.Product - A Product Entity that can be communicated between an IModel instance and Presenter
    • Presenter.ProductSearchPresenter - A Presenter to manage product search interface
    • Presenter.IProductSearchView - A view of the data involved in a product search
    • ProductSearch.aspx - A web page that implements the IProductSearchView and interacts with the ProductSearchPresenter

    My final Visio diagram ended up looking like this:

    Example Application Diagram
    Diagram of Example Application

    In this case the left side represents basic components (bases classes and interfaces) that are used to define common structure or contracts on the right side.

    The Code

    For the purposes of the example project, my view has properties for Search Text, a Search Count (number of results), Results (a generic list of the Product entity), and a boolean indicating whether there are results to display. My Web Form implements these properties, tying them to elements on the screen.

    1. public partial class WebForm1 : System.Web.UI.Page, Presenter.Views.IProductSearchView {
    2.  
    3.         Presenter.ProductSearchPresenter _presenter;
    4.  
    5.         protected void Page_Load(object sender, EventArgs e) {
    6.             btnSearch.Click += new EventHandler(btnSearch_Click);
    7.             rptProducts.ItemDataBound += new RepeaterItemEventHandler(rptProducts_ItemDataBound);
    8.             _presenter = new Presenter.ProductSearchPresenter(new Model.LocalModel.BasicModel(System.Configuration.ConfigurationManager.ConnectionStrings["AdventureWorks"].ConnectionString), this);
    9.         }
    10.        
    11.         void btnSearch_Click(object sender, EventArgs e) {
    12.             this._presenter.ExecuteProductSearch();
    13.         }
    14.  
    15.         string Presenter.Views.IProductSearchView.SearchText {
    16.             get { return tbSearch.Text; }
    17.             set { tbSearch.Text = value; }
    18.         }
    19.  
    20.         int Presenter.Views.IProductSearchView.ResultCount {
    21.             set { lblResultCount.Text = value.ToString(); }
    22.         }
    23.  
    24.         List<Model.Entities.Product> Presenter.Views.IProductSearchView.SearchResults {
    25.             set {
    26.                 if (value != null && value.Count > 0) {
    27.                     rptProducts.DataSource = value;
    28.                     rptProducts.DataBind();
    29.                 }
    30.             }
    31.         }
    32.  
    33.         bool Presenter.Views.IProductSearchView.DisplayResults {
    34.             set { tblResults.Visible = value; }
    35.         }
    36. ...

    As the presenter populates properties in the view, the information is automatically reflected on the page. The actual logic of how the business functions are called and populate those properties are neatly packaged up in the Presenter and View interface and very little logic occurs in the actual web form.

    1. public class ProductSearchPresenter : BasePresenter {
    2.  
    3.         protected Views.IProductSearchView _view;
    4.  
    5.         public ProductSearchPresenter(Model.IModel model, Views.IProductSearchView view) : base(model) {
    6.             this._view = view;
    7.             this._view.ResultCount = 0;
    8.             this._view.DisplayResults = false;
    9.         }
    10.  
    11.         public void ExecuteProductSearch() {
    12.             List<Model.Entities.Product> results;
    13.             results = this._model.SearchProduct(this._view.SearchText);
    14.             if (results.Count > 0) {
    15.                 this._view.ResultCount = results.Count;
    16.                 this._view.DisplayResults = true;
    17.                 this._view.SearchResults = results;
    18.             }
    19.             else {
    20.                 this._view.ResultCount = 0;
    21.                 this._view.DisplayResults = false;
    22.                 this._view.SearchResults = null;
    23.             }
    24.         }
    25.     }

    To create a unit test, we define a simple view that implements the view interface, execute the presenter logic, and verify the properties are populated the way we would expect when the same presenter calls are made from the interface.

    Extending the Architecture Further

    Extending the application to display product search in a different manner would only require the addition of a new interface that also implements the Product Search View. A Silverlight front-end would only require creating the basic project, implementing the product search View, and wiring the new interface controls to the view properties. To replace the direct mode reference with a service reference, we could create a service facade that implemented the IModel interface, connected to a local or remote WCF service behid the scenes to handle the real model logic. And finally, instead of counting on our QA department to test all of the application interactions, we can create unit tests directly against the Presenter and Views to ensure that all of the interactions below the top surface of the application are happening consistently and to our expectation.

    Your Turn

    Getting this much of the architecture working is a good first step. I took a number of shortcuts on the BasicModel class in my example, but I now have a functional Model-View-Presenter application to play with. Hopefully there was enough information in the article to interest you in trying this out on your own. I urge you to read the articles linked in the top of the post (or several more in my Model-View-Presentation bookmarks) and come up with your own diagrams and sample project. Even doing a small project will force you to run into questions and considerations you wouldn't have had by simply reading about it, not to mention unrelated tidbits you will pick up along the way (for instance, I also learned about ObservableCollections today).

    About the Author

    User bio imageEli delivers software and technology solutions for a living. His roles have included lone developer, accidental DBA, team lead, and even unintentional Solaris consultant once. With experience in adhoc, Lean, and Agile environments across NSF grants, SaaS products, and in-house IT groups, he is just as willing to chat about the principles of Lean or Continuous Delivery as he is to dive into Azure, SQL Server, or the last ATDD project he created.
    Social SitingsTwitterLinkedInHomePagedeliciousLTD RSS Feed
    InstapaperVote on HN