Wednesday, April 9, 2014

'Separation of Concern' A Key Driver in MVC


Separation of Concern (SoC) is a concept which distinguishes a solution into distinct phases  in which each concern has a different purpose. By separating these sections, each can encapsulate information that can be developed and updated independently. N-tier development is an example of SoC in which the user interface (UI) is separated from both the business layer and the data access layer.
MVC adds a level of concern due to the client-based nature of web browsing. Supporting JavaScript in the browser means there are two parts of the UI the developer needs to consider:
  1. The part of the UI created and rendered on the server 
  2. The part affected solely by code on the client side. 
SoC adds some complexity to the application’s design,  but the benefits outweigh the extra complexity.

Models vs. ViewModels




In general, we can build model, Domain, View, or Input modeling in different ways. Use a domain model when the object you are using describes the data you work with in the middle tier of that application. For example, present these objects to a view for display, you are using a domain model approach for creating your model. 





A ViewModel approach describes the data being worked on in the presentation layer. Any data which present in the view is  found within the properties of the ViewModel class, which represents all the data the controller transmits to the view after processing the request. A ViewModel is generally the result of aggregating multiple classes into a single object.

In simple terms, Model closely maps to the raw tables in the database where ViewModel is closely mapped to the data that are going to show in the view. It is a good practice that the Model remains clean and consists less data manipulation logic. We can use POCOs or POJOs as data structures which holds the data in the Model and the ViewModel is an aggregation of  POCOs or POJOs based on the requirements of the View.

Input Model


The input model faithfully represents the data being uploaded to the server from the client with each individual HTTP request. The input model approach uses model binding to capture user input. When consider a typical complex data entry form, we might have one entry form that captures information that would typically span across multiple objects in a domain, such as name, address, employers, phone numbers, and other values. Those objects would get mapped to different domain objects. The use of an input model, however, enables all the work to create and manage these domain objects to stay within a single controller and model.

The best time to conceptualize the controller structure is when building the data model for the application. Although there is generally not a one-to-one match between a controller and the application’s data or object model, there is a correlation. We should not follow a specifically data-based approach, however, because the work the user will be doing is an important consideration. If the screens the user will be interacting with do not map to the application’s data model, the  controllers likely should not either. Instead, we should consider the use of a separate business layer that more closely matches the business process the user will follow, or a ViewModel approach that enables you to create a specialized object or set of objects as an intermediary between the object model and the user. In either case, we should align the controllers with those objects to provide a sensible separation.

Handling Exceptions Across Multiple Layers

 


There are different places in an application in which we can throw an exception, and what we do with those exceptions will be affected by where the exceptions were thrown. When we are writing an application that enforces separation of concern, determining how best to manage errors is complicated by this separation. If all work is done in the same layer, managing errors is easy because you do not have to negotiate boundaries. However, multiple layers complicate things and require you to understand layer rules. A layer should know only about the layer it communicates with, and it should have no knowledge about layers that might be calling it.

Because of the relationships between the layers, errors in the data layer will make no contextual
sense in the UI. They do, however, make sense to the business layer. This shows one of the primary architectural considerations when needing to handle exceptions across multiple layers. A layer should ensure that no errors pass through. The business layer, for example, should capture all data layer errors. It should do whatever work needs to be done as a result of those exceptions and determine whether an exception should be sent to the UI for rendering to the user.

Consider an example: One common example is Database exceptions. Let's say a user comes to a web application and attempts to log-in where the web application is acting as the UI layer in an n-tiered application and calls the business layer with the log-in information. The business layer reaches out to the data layer to determine whether there is a match. However, the database server is down, so when the business layer makes its call, it gets an error. There are several choices at this point.
  • We can pass the error up to the UI layer
  • Or analyze it in the business layer and decide what to tell the UI layer.
Does a user typically need to know that information? Probably not, so it would make sense to capture the error when you get it and then log it. However, because it is a fatal exception, you need to tell the user something. It would be reasonable to throw a new custom exception such as a "DatabaseException". Because this would no longer be a data layer exception, it would be sensible for the user interface to manage it.
The same approach is suited when dealing with Model errors where it should be managed by the controller. If work needs to be done to manage the error, logically it should be managed in the controller. Controller errors are usually propagated out of the controller and into the processing layer.

Any Other Layers


Hell yes, one prominent layer is collection of Services, Rather than me deciding what are the other layer, I let you decide :)

Why SoC? 


A term closely associated with SoC is loose coupling. Loose coupling is an architectural approach
in which the designer seeks to limit the amount of inter-dependencies between various parts of a system. By reducing inter-dependencies, changes to one area of an application are less likely to affect another area. Also, by eliminating inter-dependencies, you ensure that your application is more maintainable, testable, and flexible, which tends to result in a more stable system.

No comments:

Post a Comment