The presentation layer - Devising the architecture - Microsoft .NET Architecting Applications for the Enterprise, Second Edition (2014)

Microsoft .NET Architecting Applications for the Enterprise, Second Edition (2014)

Part II: Devising the architecture

Chapter 6. The presentation layer

Design is not just what it looks like and feels like. Design is how it works.

—Steve Jobs

Everybody would agree that the presentation layer manages and makes possible any expected interaction between the user and the system. Much like in a restaurant where a waiter gets and forwards orders to the kitchen staff, the presentation layer picks and dispatches commands to the nearest interfacing layer in charge of processing the command. Just as the waiter at some point serves the ordered dish to the eagerly waiting client, the presentation layer is slated to show at some point any calculated response to the user.

It sounds like the classic chicken vs. egg debate, but it is probably worth raising the question once more: when setting up a new restaurant, which staffing and organizational issues do you focus on first? Is it the serving or kitchen side of the matter?

For a long time in the software world, we started from the back end, and many of us considered presentation the less noble part of the system—just a detail to tackle after the business and data access layers had been completed. There’s no question, however, that both the presentation and back end are equally necessary in a system of any complexity. In the past edition of this same book, some five years ago, we wrote the following:

Your attitude, your preferences, and even your skills determine the “priority” you assign to each layer and, subsequently, the order in which you focus on the various layers.

This is a point that today, some five years later, we perceive differently.

Today, most systems are consumed through a wide variety of devices, either smartphones, tablets, laptops, very large or very small screens (such as smart TVs), and wearable devices. The application back end is essentially the same, but the front end might take multiple forms and colors. Each device, in fact, might require its own set of use-cases, and this might lead to an organization of the back end different from the organization you would reckon ideal for one, default type of device.

In addition, years of experience have taught us that requirements tend to continuously change and only a deep understanding of the domain can help smooth the pain and effort. Focusing on the presentation first helps you to gain a better and earlier understanding of the orders to serve and how they should be served. After the presentation layer has defined required scenarios, setting up the back end is far simpler.

User experience first

The most interesting things for an application usually take place in the Domain Model Layer, which is also where you create the engine that gives life and fuels the entire system. Starting the design from the Domain Model Layer is certainly acceptable and also common. Yet, we’d like to push another approach here that might save time and effort, especially when you are relatively new to the domain and the use-cases that are relevant for the users. In some past presentations, Dino called this approach “the Copernican revolution of software development.”

Copernicus didn’t observe something new that nobody else had seen before. Instead, he just offered a totally different perspective of things and proposed a different explanation for things like day and night that everybody was experiencing.

Similarly, we don’t claim to have a new magical potion that will save the world. More simply, we like to share a design approach that puts a lot of emphasis on the presentation layer, focuses on tasks, and has the merit of letting you attack most of the interesting things when the user interface has been already validated by users, refined, and approved. Everything can still change, but most of the presentation wrinkles surely have been ironed out.

Short for user experience first, UX-first is what we named this approach to software design that is centered on presentation and user/system interactions.

Focus on interactions

We write software to let customers do their own business the way they like it and that is most effective. Any software exists to produce results, whether it is screens, files, or just database updates. As obvious as it might sound, the more you know about the expected results, the more effectively you can make development plans.

When expected results involve some graphical interface for the user to interact with, focusing on those interactions first sounds like a natural choice. Focusing on interaction leads to a task-based design.

Task-based design

Sometimes the complexity you face is too big for one bite. Starting from the model, then, might be a pretentious and heavyweight approach. A lightweight start focuses on tasks to implement, the input that each task needs, and the output that each task produces.

So you iteratively take a task from the list and start sketching out a possible user interface and, subsequently, a workflow behind it. It’s nothing new in the end. This is precisely what the Unified Modeling Language (UML) use-case diagram is for.

In UML, a use-case diagram provides a graphical representation of an application’s use-cases. A use-case describes an interaction between the system and one of its actors. In particular, a use-case diagram shows which actors do what. An actor can be a user or any other external system (for example, a database) that interacts with the system being described. An actor cannot be controlled by the system; an actor is defined outside the system itself. Figure 6-1 shows a sample use-case UML diagram.

Image

FIGURE 6-1 A sample use-case UML diagram.

The use-case identifies two actions: retrieve orders and retrieve product details. This scenario likely raises the need to have one screen for placing the request and one screen for showing the response. Users won’t work directly with the part of the system that retrieves orders or product details. All that the user is interested in is how she specifies the order or the product to retrieve.

The next step is sketching out screens, jotting down ideas for how requests should be specified and how responses should be laid out.


Image Important

The adoption of a task-oriented UI is an emerging trend in the industry that goes hand in hand with separation between the read and write models. In a world that feels the need to separate the domain from data, the transition from data-centric interfaces (Access-style, grid-based) to task-oriented interfaces is just a natural step. This new approach makes it easier to turn requirements into specifications and makes it possible to refine the user interface to turn it into a pleasant user experience. Finally, a task-oriented UI helps simplify the structure of the back end via architectural patterns like Command/Query Responsibility Segregation (CQRS), which we’ll start discussing in Chapter 10, “Introducing CQRS.”


Aim to find the best way of doing things

Let’s say it: for decades, developers didn’t pay much attention to the user interface of their applications. The focus was on models and databases and the model behind the presentation was largely ignored and considered to be a pain in the neck. It seemed that ending up with different models for presentation and storage was a sign of bad design.

As a result, the user interface was often more inspired by the entities in the back end rather than by the desired experience and actual tasks performed on the client.

The user interface is the means through which users accomplish their tasks and interact with the system. Any user interface that allows the user to accomplish a task is good; but not all of them are good in the same way. Let’s admit it: as developers, for years we faced a mass of forgiving and passive users humbly accepting any user-interface implementations.

Things are becoming different. Now our software more faces a mass of users much less forgiving and often dictating user-interface aspects. As far as we can see, this is already true for consumer applications, and the trend seems defined. It just takes time for it to also become mainstream in the world of enterprise applications.

Continuously refined sketches that focus on interaction rather than data are the way to go. In essence, we think this is where the difference between user interface (UI) and user experience (UX) lies.

A view model class for each screen

In terms of software development, having screens defined and approved is great news and an excellent point on which to start building the rest of the system. A screen is ultimately a collection of input elements and can be easily abstracted to a class.

The class doesn’t need to be rich in behavior; a plain data-transfer object (DTO) is more than fine. A DTO is a class used to carry related data across layers and tiers of a system. A DTO indicates what comes out of the screen and gets passed to the application layer for executing the command. Another DTO indicates the data that needs to flow into the form to populate it, for example, with the response of a server action.

Outgoing DTOs form the input model; incoming DTOs form the view model.

UX is not UI

Some 30 years ago, graphical user interfaces (GUI) changed the rules and both developers and users learned the importance of visual design. Up until a few years ago, and surely before the advent of smartphones and tablets, well-designed visual interfaces were sufficient to ensure a good experience to users of software applications. The road ahead seems to indicate that a good UI is no longer sufficient for delivering a well-designed presentation layer.

To stay on the cutting edge, we have to replace UI with UX.

So what’s UX, and how does it compare to UI? In a nutshell, UX is more than just visual interface design and, in the end, UI is just a part of UX and probably still the most relevant part. What about other aspects of UX? That’s where UX experts chime in.

Responsibilities of a UX expert

A UX expert—sometimes called a UX architect or even UX designer—is an analytical and creative position at the same time. The UX expert analyzes the users’ behavior with the purpose of outlining the best possible experience for them to work with and within the system. The four pillars of a user experience are summarized in the following list:

Image Information architecture

Image Interaction design

Image Visual design

Image Usability reviews

The order is not coincidental. The first point to look at is the hierarchy of the information and then determine the ideal way for it to show through the application. Next comes the way in which users interact with that information and the graphical tools you provide for that to happen.

All this work is nothing without the fourth point—usability reviews. A UX expert can interview customers a million times—and should do that, actually—but that will bring about only an understanding of the customer’s basic needs. This leads to some sketches that can be discussed and tweaked. A high rate of UX satisfaction is achieved only when the interface and interaction form a smooth mechanism that neither has usability bottlenecks nor introduces roadblocks in the process.

For a UX expert, talking to users is fundamental, but it’s not nearly as important as validating any user interface live from the field, observing users in action, listening to their feedback and, if possible, even filming them in action.

Usability review is an iterative process that delivers a collection of mockups ready to be translated into any UI formalism supported by allowed technologies. More pragmatically, this means creating things like CSS, HTML, or XAML templates.

Tools for UX experts

The field of UX development is relatively new, though it is growing fast. The art of UX development passes through at least three stages—sketches, wireframes, and mockups—that require ad hoc tools. The fourth possible stage—prototypes—just requires regular coding tools. We want to mention four UX tools. They are described in Table 5-1.

Image

TABLE 5-1. Short list of tools for UX development

In addition, Visio and Microsoft Office PowerPoint are still good at creating quick sketches and wireframes. They’re not specific to user interface creation, though. Balsamiq came in to fill that gap. The real challenge as we see it, however, is to go beyond plain sketching and move toward scenarios where UI is mixed with interaction and multiple sketches are connected to produce at least a vague idea of the workflow behind the process. Microsoft’s SketchFlow does something in between wireframing and prototyping, but it works only for XAML applications.

Why you might need to spend time on interactions

If UX analysis is the central point of modern presentation layers, usability review is the central point of UX analysis. Here’s a brief true-life story that we hope might tell you more than abstract reasoning.

A customer asked for an internal-use quick tool to cherry-pick tweets based on user name and hashtag. All they wanted was a list of tweets to scroll so that they could select those of interest. We offered to create a quick web application based on the following wireframe (created using Balsamiq). They agreed, and we had a deal. (See Figure 6-2.)

Image

FIGURE 6-2 A sample wireframe created using Balsamiq.

It was a quick gig that involved only a couple of days of work. After the first test, everyone was happy: the application was fully functional. After a couple of days of really intense use, however, we got the first complaints about the overall experience. Dino also used the application personally for a few hours; although he probably wouldn’t have complained as a user, he could fully understand the pains of the users. At the end of the day, two key features were missing that apparently everybody ruled out because they considered them to be advanced features and not strictly required initially. One was the ability to select and hide unwanted tweets so that picking really interesting tweets became an easier task. The other missing feature was the ability to hide tweets in the stream that had been already picked.

The lesson we learned is that when it comes to UX, even a super-simple, two-page, CRUD web application might have bad surprise in store. Only by looking at users using the application can you reliably say whether the UX you offer is good or not.

How to create an effective experience

So what should you do to implement a killer UX? Overall, it’s a three-step procedure. First, you iteratively outline your ideas, moving sketches to wireframes and finally to full-fledged mockups. Second, you turn views into a working prototype using canned data and working without a back end or with a fake, test-only back end. Third, when the prototype work is done, that’s when you get to the hardest part: telling the customer that what he’s just approved is only a prototype and not the final app!


Image Note

Before we go any further, it’s time we clarify what we intend exactly by terms like sketch, wireframe, and mockup, which are common UX jargon. A sketch is a freehand drawing done primarily to jot down ideas. A wireframe is a higher level sketch where you focus on functionality, layout, navigation, and info. A wireframe doesn’t focus much on UI details. Finally, a mockup cares about the actual look-and-feel and is a wireframe with some sample UI attached.


Turning interactions into views

Without a doubt, HTML and CSS, or even XAML, would let you prototype a working view in a matter of minutes. However, the main point here is outlining an interactive model that works for the customer. The customer will probably feel more relaxed and be more open minded if you present sketches and drawings at first rather than colorful screen shots. The risk is that irrelevant details get too much attention at too early of a stage.

So you better work with low-fidelity and stay agnostic with regard to technologies. When sketches are clear enough, you proceed with wireframes and add more details about functionality, layout, and navigation. Tools like Balsamiq help a lot with quick wireframes. Wireframes set up the structure of the screen; mockups are just some graphical ideas developed on top of wireframes.

All you’ve got up to this point, however, is pure static content with no life and no action in it. Depending on the tool you chose for wireframing, you might want to create true storyboards to demonstrate the flow of UI screens.

Turn views into prototypes

Even after you convince the skeptics, you’re far from being done. Keep in mind that even the best and most widely agreed-upon user interface might turn bad when used extensively. So our best recommendation is that you do not stop at first approval; instead, try to convince yourself about the quality of the interaction design you created. If you still have doubts about it, you can go with a prototype and maybe film users using the prototype to get a true indication of their feelings.

In terms of concrete technologies, a prototype can be anything that fits the bill. It can be a set of HTML pages as well as a XAML-based application. It consists only of the presentation layer and uses canned data or just a fake back end to simulate some behavior.

Depending on the level of fidelity you want to offer, creating wireframes and prototypes for an agreed-upon set of sketches is a matter of very few days of work.

Now tell customers it’s only a prototype

So the customer likes the prototype and gives the go-ahead to build the application. Having the screen ironed out brings some benefits. You know exactly what the back end of the application has to produce. Each screen can be easily mapped to an outbound class, which becomes the input of the application layer and, in turn, the entry point in the back end of the system. The application layer forwards the input to the back end and that input proceeds down the stack. Any calculated response is carried up the stack to the application layer, packaged in a view model object, and returned to the presentation.

Ideally, each screen should be bound to a view model class that describes the data required to populate the view. In addition, each screen should be bound to an input model class that describes the data that goes out of the screen when an action is triggered. As an example imagine a page in an ASP.NET application that collects the name of two players or teams and returns the list of past matches. (See Figure 6-3.)

Image

FIGURE 6-3 The screens used to collect names of players or teams and return the list of past matches.

The first screen requires no data to be populated and forwards the data as described by the following C# class:

public class H2HInputModel
{
public Int32 PlayerId1 { get; set; }
public Int32 PlayerId2 { get; set; }
}

The second screen posts the same data as in the H2HInputModel class and requires a richer class to be populated:

public class H2HViewModel
{
public Int32 PlayerId1 {get; set;}
public Int32 PlayerId2 {get; set;}
public IList<H2HResult> Results {get; set;}
}

If it were an ASP.NET MVC application, the input model would result from the model-binding layer, whereas the view model would just be the model being passed to the Razor view engine. The following code snippet shows a possible implementation of the controller method that receives the click from the Proceed button:

public class H2HController
{
public ActionResult Results(H2HInputModel input)
{
var model = _service.GetH2HResults(input);
return View(model);
}
}

With this entire job done, the hardest part that remains to be done is ensuring the customer knows that the application is not already half done. The team has to forget about any prototypes and start building the real thing. Among other things, this means thinking about technologies, planning layers, and identifying tiers. So let’s have a look at a few common scenarios and investigate technologies and patterns for organizing a presentation layer.


Image Important

In Chapter 5, “Discovering the domain architecture,” we stressed the importance of identifying business contexts that are loosely coupled with others. Most of the time, this produces a minimal diagram with a few blocks and very few relationships. Each block probably can be implemented separately using the most appropriate architecture, design, and technologies.



MVC, MVP, MVVM, and other patterns

Short for Model-View-Controller, MVC is a pattern devised in the 1980s to architect the entire application. Applications of the time, though, were essentially monolithic applications, and using MVC as a general pattern totally made sense. The primary goal of MVC is to split the application into distinct pieces—the model, the view, and the controller. The model refers to state of the application. It wraps the application’s functionalities and notifies the view of state changes. The view refers to the generation of any graphical elements displayed to the user. It captures and handles any user gestures. The controller maps user gestures to actions on the model and selects the next view. These three actors are often referred to as the MVC triad.

The MVC pattern evolved into Model-View-Presenter (MVP), where the presenter element replaced the controller and took more responsibility. This included everything from summing the orchestration of tasks to rendering the view. In MVP, view and model are neatly separated and the presenter mediates between them.

Model-View-ViewModel (MVVM) is just a much more popular name for a pattern that was originally introduced as the Presentation Model. In MVVM, you have a class that incorporates both the commands and view model for the UI. A single class—the view model object—exposes properties to bind to UI visual components and methods to bind to UI events. MVVM is particularly well suited to application scenarios where a powerful bidirectional data-binding mechanism exists. This is especially true for XAML-based applications and Universal Windows applications.

Don’t be confused: in the context of layered applications, MVC, MVP and MVVM are all patterns for the sole presentation layer.


Realistic scenarios

Generally speaking, the presentation layer is made of two main components: the user interface and the presentation logic (also often referred to as the UI logic). The user interface provides users with the tools to use the application. Any behavior that the application can carry out is exposed to the users through graphical or textual elements in the user interface. These elements—mostly graphical elements nowadays—provide information, suggest actions, and capture the user’s activity.

Any gesture a user makes within the user interface becomes input for the presentation logic. The presentation logic refers to all the processing required to display data and to transform user input into a command for the back-end system. In other words, presentation logic has to do with the flow of data from the middle tier to the UI and from the UI back to the middle tier.

As far as the Microsoft .NET Framework is concerned, the range of possible scenarios for the presentation layer of applications includes a web and Windows Presentation Foundation (WPF) front ends as well as Windows Store and Windows Phone applications. Under the umbrella ofweb applications, though, fall quite a few interesting application models, including plain ASP.NET websites, device-oriented websites, and single-page, client-side, responsive applications.


Image Note

When it comes to Windows Store and Windows Phone applications, the universal application project allows you to share the same core UI logic project between the Windows Store and Windows Phone application. In the end, you have one project for each platform and the difference is all in the views (XAML, styling, form-factor and other minor stuff); the vast majority of the C# code in the presentation layer is shared.


ASP.NET websites

In a classic ASP.NET website, the presentation layer is split between the browser and the web server. The user interface displayed to the user is rendered on the client device through HTML pages. The presentation logic lives for the most part on the server and is, in most cases, minimal and limited to passing data between user-interface elements and the application layer.

ASP.NET comes in three flavors: Web Forms, Web Pages, and MVC. Frankly, there’s no real difference in terms of functionality.

Presentation logic in ASP.NET MVC

In an ASP.NET MVC scenario, controllers are responsible for the implementation of any UI logic. Controllers should not be considered part of the application or business layer and should be kept as thin as possible. The point of thin controllers is not so much for enforcing separation of concerns at all costs; instead, the point is recognizing separation between layers when we find it.

Controllers are tightly bound to the runtime environment and expose the HTTP context as a property. The logic you might need to have here is only any logic that depends on the HTTP context and headers. If an explicit check is required on the user agent, session state, or cookies, those actions belong to the controller. The orchestration of any task requested, though, should be moved outside the controller into the application layer. Here’s a code snippet that illustrates the point:

public class HomeController
{
private IApplicationLayer _appLayer;
public HomeController(IApplicationLayer appLayer)
{
_appLayer = appLayer;
}

public ActionResult Index()
{
// Determine the view name analyzing the user agent
var request = HttpContext.Request;
var viewName = “index";
if (IsSmartphone(request))
viewName = “index.smartphone";

// Retrieve session state for further processing
var session = HttpContext.Session;
var currentState = session["CurrentState"] as AppCurrentState;

// Process the request (pseudo-code)
var model = _appLayer.Index(currentState);

// Return the view
return View(viewName, model);
}
}

The application layer receives from the presentation (for example, the controller) whatever it needs in order to process the request, but it has no need to be aware of the HTTP runtime. In this regard, the application layer is fully testable because it runs in total isolation.

What about controllers and testability?

In general, the amount of presentation logic in the controller is minimal and trivial and might not even raise the need to test coverage. However, if you think it is important to test that, say, session state is correctly handed out to the application layer, all you do is provide mocks for both the application layer and HttpRequestBase. In this regard, ASP.NET MVC lends itself to write tests much more than Web Forms.


Image Important

As you might have experienced, testing a controller mostly means mocking the HttpRequestBase object, which has been made as easy as possible but still remains a rather convoluted process because of the complexity of the HttpRequest interface. In our vision, this is clearly the heritage of an original design that came about at a time when testability was not a concern. As fans of old horror movies, we paraphrase the popular “Don’t open the door” to be “Don’t test the controller.” In the end, the controller is part of the ASP.NET infrastructure and is only minimally extended by your logic. The need to have tests here is low.


Presentation logic in ASP.NET Web Forms

In ASP.NET Web Forms, there are no controllers. To be precise, there’s nothing with the shape and name of an MVC controller, but there’s a software entity that plays exactly the same role: postback handlers. As emphatic as it might sound, we state that there’s no logical difference between button-click handlers and controllers. Both are placeholders for presentation logic, and both should be kept thin by moving out to the application layer the orchestration of any processing tasks.

This is also a statement in favor of testability in ASP.NET Web Forms.

When ASP.NET Web Forms came out, it was the right framework at the right time. And 15 years ago was a time in which rapid application development reigned with nearly no opposition and testability was far from being perceived as an issue. It was no surprise that the design of the framework didn’t lend itself to unit tests. But this is not an excuse today to be lazy on separation of concerns. By simply introducing an application layer in a Web Forms site, you make the site a lot more testable.

Application services

Within the context of ASP.NET applications, we design the application layer through classes that match the controller. We also use a naming convention internally for application-layer classes and call them worker services. At the end of the day, what we tend to call worker services are known in DDD as application services.


Image Note

We’ll be using the term “application service” in the rest of the book. We consider “worker service” and “application service” to be synonyms.


In the end, the HomeController class is associated with the HomeService class. An instance of the HomeService class is injected in HomeController either via IoC or poor man’s injection. The association between controllers and application services is also reflected in the project structure, as shown in Figure 6-4.

Image

FIGURE 6-4 Using application services in an ASP.NET MVC project.

In our projects, the application layer is the entire content of the Services project folder. Moving the application layer to a separate assembly is as easy as creating a new class library out of the Services folder. Moving the application layer to a separate tier requires a host application and some wrapping layer to expose endpoints. The host application can be anything—like a Windows Communication Foundation (WCF) service—or, if you are interested only in HTTP communication, it might better to have it be another ASP.NET MVC site or a Web API application.


Image Important

Our advice is to bet on Web API rather than WCF and step out of WCF over the long term. As we see it, Microsoft is investing a lot in Web API and SignalR, and it just slated WCF to be in a sort of maintenance and support mode for the future. This said, for the time being Web API cannot do everything that WCF can do. For example, Web API is inferior to WCF when it comes to the full range of transportation protocols, security options, transactions, and reliability. Not all developers need these features, so in the end the rule is simple: if Web API does what you need, use it; otherwise go for WCF.


Application service classes contain methods that match one-to-one with use-cases. Each method orchestrates the necessary workflow, starting from the input model and returning a view model. In most cases, the controller logic is as thin as in the Index method shown here:

public class HomeController
{
private readonly IHomeService _service;
public HomeController(IHomeService service)
{
_service = service;
}
public ActionResult Index()
{
var model = _service.FillHomePage( /* input model */ );
return View(model);
}
...
}

The application service has access to all the layers and tiers down the stack. It is able to query and update data and to invoke, if required, external web services. If you have a domain model, the application service should also be able to access those entities and make use of adapters for translating from the domain model to the view model. (See Figure 6-5.)

Image

FIGURE 6-5 Ramifications of the connections from the application layer down the stack in an ASP.NET scenario.

User interface in web applications

The user interface of a web application is HTML served to the browser. In ASP.NET MVC, the controller invokes the application layer. When the response has been received, the controller instructs the view engine to generate the HTML markup using the specified view template (mostly a Razor file) and the view model object that the specific view template requires. The view model is often just the response received from the application layer. In other cases, the view model can be the result of some further aggregation process run by the controller itself.

In Web Forms, the request processing takes place within the boundaries of a Page object. A Page object is built around an HTML template and cannot be decoupled from that. In other words, in Web Forms, users request a page and receive it as it was designed to be. In MVC, there’s a lot more flexibility because the component that renders HTML is separated from the component that processes the request to get a response from the back end. This means that in MVC the same request can be easily configured to return different markup under different runtime conditions. In Web Forms, you can achieve the same either by placing a module that rewrites the URL to point to a different page than the originally requested one (for example, default.tablet.aspx instead of default.aspx) or by heavily restructuring the page so that the final template results from the aggregation of user controls selected based on runtime conditions.


Image Note

Today, the amount of JavaScript in web pages is growing. However, unless you organize a website to be a rich client-side HTML5 application, the role of JavaScript in the presentation layer of a web application is minimal. It’s mostly used for prevalidating input and to speed up the rendering and refresh of some parts of the page via Ajax calls and client-side data binding. We’ll cover JavaScript-intensive client pages as a separate scenario later in the chapter.


Web Forms vs. ASP.NET MVC

In the Microsoft web stack, ASP.NET Web Forms is by far the most well-known and frequently used framework. The majority of remakes of existing sites start from a large Web Forms codebase. When the time for a remake comes, architects pick up their heads after years of hard work on a single system and can clearly see that now ASP.NET Web Forms is a thing of the past—sort of a walking-dead technology.

Architects diligently look around for alternatives but sometimes they find nothing that, to their eyes, is clearly better than ASP.NET Web Forms. More precisely, they sometimes miss a strong business reason for choosing ASP.NET MVC over Web Forms. And for the most part, they’re right.

Other architects find that for complex web applications ASP.NET MVC is far more flexible and offers better control than Web Forms.

Who’s wrong, then?

Technical and strategic differences

Devised in the thick of the browser wars of the later 1990s, ASP.NET Web Forms introduced server controls to produce user interfaces without learning HTML. It also introduced some ad hoc infrastructure to handle common aspects of web programming, such as session state and authentication and also statefulness. In particular, the Web Forms postback model was the junction point between web and desktop programming. The postback model enabled a programming model similar to what developers did for years: paint the user interface, wait for the user to interact, have the system react to the user’s action, and repaint the user interface. Everything took place over the HTTP protocol, making it completely invisible to the developer. That was exactly the purpose; it was not a design flaw.

ASP.NET MVC came 10 years later, when people were demanding different tools—in particular, they were looking for more control over HTML and HTTP. Exactly what designers of Web Forms managed to hide from developers became the primary request of MVC developers. As you can see, there’s no room for compromise. It’s just two different visions of the same world. It’s pointless to determine who’s right and who’s wrong.

The advent of Ajax and the subsequent change of developers’ perspectives are real, but is it also true that Web Forms is now pure junk?

Web Forms didn’t fall out of fashion overnight. You can still build successful web applications using ASP.NET Web Forms. You still have plenty of commercial extensions and libraries. You still have a mature and reliable platform that will be maintained for a few more years and supported for the foreseeable future. If it works for you, then it just works. Period.

Another way to look at it is as follows. Web Forms worked well for you in the past decade, and your whole team knows the platform very well. Now, you’re about to embark on a significant remake. Is Web Forms up to the task you want it to? If your task is to build a JavaScript-intensive application, you might have a hard time. If you want testable components, you might have a hard time. If you need to ensure full accessibility to any page of the site, you might have a hard time. If it’s critical to have SEO-friendly URLs, you might have a hard time.

Facing difficult tasks doesn’t mean not being able to do things, however. Following up version 2.0 of ASP.NET Web Forms, Microsoft improved several aspects of Web Forms to minimize exactly the aforementioned aspects. So honestly, there’s no compelling business reason to leave ASP.NET Web Forms to embrace other web frameworks.

Does this mean that advocates of ASP.NET MVC are dead wrong?

Most points that MVC advocates make against ASP.NET Web Forms are absolutely true and honest. Except that—in our opinion—they don’t make a strong difference businesswise. So the bottom line is that if you don’t have a special reason to seriously complain about Web Forms, and if you see a significant effort/cost for your team in acquiring new MVC skills, you can continue on with Web Forms. Regardless of what you might hear, the majority of production sites based on ASP.NET are using ASP.NET Web Forms. You won’t be alone out there.

By the same token, ASP.NET MVC is a newer platform and comes closer to meeting the needs and expectations of today. Sticking to the past might be not the savviest choice for your company. But this consideration has little to do with the functional efficiency of the Web Forms platform.

Lack of HTTP endpoints in Web Forms

ASP.NET Web Forms was originally designed to shield developers from the actual structure of the HTML being sent to the browsers. As a developer, you had no control—and only a faint idea—of the ID used to name HTML elements. In these conditions, how could you arrange to replace a grid or a chunk of text with downloaded data? Microsoft addressed this problem already with ASP.NET Web Forms 4, which was released back in 2010, and made DOM manipulation also quite effective in Web Forms.

But that was only the first half of the problem.

Before developers can get to manipulating the DOM dynamically, they have to collect data from some remote HTTP endpoints. In some cases, these endpoints are located on sites outside of your control—for example, RSS feeds, Twitter, or other business partners of yours. The URLs are known and constants. Using JSONP, or other tricks, you can make the calls you need quite nicely.

How can you easily expose, on the other hand, your own endpoints from within a Web Forms application?

Although solutions exist—from ASPX pages returning JSON to ad hoc HTTP handlers up to WCF services bound to the HTTP transportation—the real problem that makes ASP.NET Web Forms feel outdated is the lack of an efficient way to expose HTTP endpoints so that they are easily consumable by whatever JavaScript framework you want to use on the client side.


Image Important

As of today, the official answer to the problem of exposing application-specific endpoints from within a Web Forms application is Web API. Exposing a Web API front end out of Web Forms is as easy as adding controller classes in the App_Code folder. Visual Studio 2013 makes this process quite straightforward.



Image Note

Today, Web API is confusingly similar to ASP.NET MVC because it pushes a programming interface that appears to be a clone of ASP.NET MVC. At the same time, up to .NET 4.5 the Web API runtime is completely separated from ASP.NET MVC. This situation will change in a future major release of the .NET Framework, when ASP.NET MVC and Web API will be sharing the same OWIN-based runtime environment.


Mixing Web Forms and MVC together

A common scenario today is that you have no time or budget for a complete remake of the site and you just want to implement a slew of new features using Ajax and libraries like jQuery, jQuery UI, Bootstrap, or perhaps AngularJS or Breeze. Can you do that on top of Web Forms? Can you just bring in some ASP.NET MVC features and leave the rest of the site as is?

Mixing Web Forms and MVC is definitely possible. We did it several times, and it always worked beautifully. We never heard of issues or troubles. And when looking at the underlying architecture, it comes as no surprise. In addition, Visual Studio 2013 specifically supports this scenario and allows you to join the binaries of Web Forms and MVC in one click or two. So the question becomes: should you?

We see two main scenarios for mixing Web Forms and ASP.NET MVC.

Suppose you want to rewrite a website using ASP.NET MVC, but you can’t start at full speed on the first day. The site is large, and years of accumulated viewstate and server controls make it hard for the team to bite on the MVC paradigm. So you take one module at a time and rewrite it from scratch using ASP.NET MVC concepts. This means writing routes, controllers, and Razor views; preparing CSS and script bundles; and getting familiar with frameworks and libraries like jQuery and Twitter Bootstrap.

The second scenario is when you just want to add a bit of interaction to some of the existing pages. This mostly means using jQuery to download JSON data from your servers. Given this objective, mixing the existing site with ASP.NET MVC is definitely a possible solution. However, in this scenario, we’d rather go for Web API because it seems to be a cleaner solution.


Is OWIN something we should care about?

If you visit the home page of the OWIN website at http://owin.org, you’ll find out that OWIN aims to define a standard interface for web servers and .NET client applications to use for interacting with one another. OWIN stands for the Open Web Interface for .NET. The design of OWIN—which you can read on the website—was inspired by Node.js and similar frameworks for other environments, such Ruby’s Rack and Python’s WSGI. Node.js, in particular, allows you to create web servers that operate under your total control. This is also one of the goals of OWIN.

However, the primary goal of OWIN is not to enable you to build your own web server. While that is a possibility, the goal of OWIN is to give the web stack a standard interface and decouple it from any concrete implementation, such as the IIS and the ASP.NET runtime. In a future version of the .NET Framework, OWIN will likely be used on top of IIS. In this regard, OWIN is a very important foundation for the future of ASP.NET MVC, whereas ASP.NET Web Forms will hit a dead end.

You might not see the need to use OWIN in 2014, but it will be a critical pillar for the future once it is fully incorporated in IIS and exposed as a common API.


Adding device support to websites

We bet that in a couple of years all websites will be easy to consume from mainstream devices. Cell phones are a thing of the past, and smartphones are changing too, as devices that are only two years old start are significantly different in terms of capabilities and power from newer ones. In this context, nobody can reasonably afford to stick to websites that get stretched into the device viewport and need users to zoom in and out to read and follow links.

Adding a layer of device-orientation to websites, therefore, is vital. It’s not even a simple matter of separating mobile devices from desktop browsers. What’s a mobile device today? The term mobile means everything and nothing. A wearable device (for example, Google glasses) is mobile in the sense that it moves with the individual, but it can’t be compared to a tablet when it comes to content. A smart TV is not a mobile device, but it still requires ad hoc content.

Which strategies should you take to make a website really responsive to the capabilities of the requesting device?

Responsiveness through feature detection

Most developers remember well what a nightmare it was a decade ago to make websites look (nearly) the same on different browsers. As developers, we embarked upon the flaky parsing of user-agent strings and created intricate branches in our HTML code. Not really a pleasant memory. We learned our lesson, though, and when a few years later we started facing the same problem with mobile devices, we opted for something decidedly smarter—feature detection.

Feature detection is a concept first popularized by Modernizr—a JavaScript framework that detects HTML5 and CSS3 features in the browser. Modernizr offers an API that checks whether the current browser supports HTML5 input types, local storage, web sockets, CSS gradients, media queries, and much more.

Is the type of the device a feature you can programmatically detect? Not at the moment.

Anyway, a design methodology known as Responsive Web Design (RWD) came to the rescue, mixing together CSS media queries—a CSS3 feature that most browsers support—grid-based layouts, and proportional dimensions. With CSS media queries, you apply different CSS style sheets depending on the size of the current browser window. You define a few breakpoints that require the change of the style sheet, and grid-based layouts and proportional dimensions ensure that intermediate sizes show nicely. Typical breakpoints are placed at 480 pixels to work with smartphones and 800 pixels for tablets.

Devised to render pages responsively as the user resizes the browser, RWD ended up being used to scale down content on mobile devices too. In effect, a 480-pixel-wide screen just requires appropriate rendering regardless of whether it is a resized browser window or full-screen mobile browser.

That’s the major strength and major weakness of RWD. To us, these are mostly weakness if we put it in the perspective of providing an optimal device experience.

Pros and cons of responsive web design

If you think it’s great that RWD allows you to write one page and adapt via CSS to any window size, we invite you to consider also the following:

Image CSS doesn’t perform magic; all it does is hide and resize HTML elements. If an image is too large for a small screen, it will simply be resized; however, nothing changes in terms of bandwidth and downloading. And bandwidth is not a secondary point on a device.

Image On mobile sites, the 80/20 rule holds true, meaning that only 20 percent of the content is usually relevant for the audience. By using RWD, you risk downloading a lot of content on a mobile device just to hide it in the end because it’s not relevant. Or you make it quite slower (and possibly expensive) for the user to read the page.

Image User experience is all the rage these days, and it is especially important on devices. With RWD, you just focus on one set of use-cases and adapt it to any window size. In doing so, you can’t provide specific use-cases and ad hoc organization of the user interface to users of, say, tablets.

Image Some people contrast that prior point by claiming that mobile-first design would fix everything. Mobile-first merely consists of thinking of the set of use-cases for a mobile audience first so that you ensure it works well enough on smaller devices first. You then proceed from the bottom up. Unfortunately, this doesn’t address the point of performance or the point of usability. As long as CSS is the only tool you rely on to adapt views, all you can do is hide and resize things. To serve content on both small and large screens via CSS, you need to have in place and downloaded all content regardless of the device. The content doesn’t change on a per-device basis.


Image Note

Some techniques exist to mitigate the issues of RWD when it comes to performance on devices and the use of bandwidth. In particular, CSS files for a small screen can request different and smaller images.


Taking mobile-first to the extreme, and to some extent moving away from plain RWD, you might decide that with a little bit of extra JavaScript code you download content and style sheets on the fly and possibly on a per-device basis. In doing so, you face another big hurdle. How do you detect the type of the device that hosts the browser?

Responsiveness through server-side device detection

The golden rule to optimize performance and usability on devices is that you need to know their type and intelligently serve ad hoc markup. You maximize performance and usability if you detect the type of the device on the server.

When making the request, each browser identifies itself through the user agent string. Subsequently, a thorough analysis of the user agent string might reveal the identity of the device. Apparently, detecting devices is a boring but not difficult task. A bunch of regular expressions can do it. Well, as usual, it depends. If your purpose is only to identify the operating system and roughly the name of the device, well, that’s probably not too hard. If the user agent string contains iPhone, iPad, Windows Phone, or Kindle, you can be reasonably sure what it is. You still don’t get details about versions, but that’s probably a secondary point for a large share of applications.

What about Android, BlackBerry, and Sony devices? When the only hot keyword you find is Android, what can you conclude about the device? It can be anything: a smartphone, tablet, minitablet, legacy phone, or perhaps even a smart TV.

Device detection is a serious matter, and if you need it done seriously, you need expertise. The de-facto standard for device detection is WURFL (http://www.scientiamobile.com). WURFL is a cross-platform library—used by, among the others, Facebook, Google, and PayPal—that can detect over 20,000 devices and return over 500 capabilities for each. For the ASP.NET platform, WURFL is available as a cloud solution with an elastic number of capabilities and works as well as an on-premises install you get via a canonical NuGet package.


Image Note

The hardest part of having some logic to recognize devices from their user-agent strings is maintenance. New devices hit the market every day, and that logic and the back-end database must be updated regularly. This entails a significant effort, and it’s the primary reason why device description repositories (DDRs) like WURFL are not free, at least for premium users.


A point that is sometimes raised against the server-side approach is that capabilities are kind of guessed instead of detected. At the moment, browsers don’t expose in a common and accurate way the operating system or the more specific aspects of the host device, such as touch support, radio system, SMS, streaming, and so forth. It is not surprising, after all. The browser is not the device, even though we can use the browser agent string to figure out what the device is. As an example, consider that Dino had the incredible adventure of buying a low-cost tablet that clearly runs Android 4.0. The built-in browser, though, keeps on sending an agent string like that of an iPad 3.2. Any automatic software will certainly mistake it for an iPad.

Display modes in ASP.NET MVC

For some reason, a server-side approach is perceived as one that leads to code duplication as opposed to RWD that builds on a single codebase. This is a false perspective of things. In a server-side approach, you provide different views in much the same way you provide different CSS files (or rule sets) in a RWD solution. However, having different views is precisely what maximizes performance and usability. Let’s see the steps required to build a WURFL-based adaptive solution in ASP.NET MVC.

The trick that enables a server-side adaptive solution for devices consists of selecting the most appropriate view based on the user agent. Here’s some pseudocode to illustrate the point:

public ActionResult Index(InputModel input)
{
// Usual work to process the request
var model = _appLayer.FillHomePage(input);

// Find and serve the most appropriate Razor file for the “index” view
var viewName = SelectAppropriateView(“index”, Request.UserAgent);
return View(viewName, model);
}

Internally, the SelectAppropriateView method will check the user-agent string and, assuming to have multiple versions of the same view, returns the one that best fits the detected device. Starting with version 4 of the ASP.NET Framework, the selection of the most appropriate view is code that can be buried in the folds of ASP.NET MVC thanks to display modes.

A display mode is essentially a Boolean expression that evaluates the HTTP context. In addition, each display mode is associated with a unique suffix. Concretely, in ASP.NET MVC, a display mode is an instance of the DefaultDisplayMode class, and all currently defined modes are grouped in the DisplayModeProvider.Modes global collection. Here’s some code that initializes the application from global.asax:

var modeDesktop = new DefaultDisplayMode("")
{
ContextCondition = (c => c.Request.IsDesktop())
};
var modeSmartphone = new DefaultDisplayMode("smartphone")
{
ContextCondition = (c => c.Request.IsSmartphone())
};
var modeTablet = new DefaultDisplayMode("tablet")
{
ContextCondition = (c => c.Request.IsTablet())
};
var modeLegacy = new DefaultDisplayMode("legacy")
{
ContextCondition = (c => c.Request.IsLegacy())
};
DisplayModeProvider.Modes.Clear();
DisplayModeProvider.Modes.Add(modeSmartphone);
DisplayModeProvider.Modes.Add(modeTablet);
DisplayModeProvider.Modes.Add(modeLegacy);
DisplayModeProvider.Modes.Add(modeDesktop);

The sample code creates four displays modes, which roughly match breakpoints in RWD. Instead of a media query expression that selects the style sheet, you have a context condition that selects a suffix. The context condition evaluates on the HTTP context and typically checks the user agent. In the sample application that comes with the book, IsSmartphone and IsTablet methods in the demo are extension methods on HttpRequest and use WURFL internally to detect the capabilities of the requesting device.

All this would be nothing without the view engine’s ability to evaluate context conditions before rendering HTML. Consider the following controller code:

public ActionResult Index(InputModel input)
{
var model = _appLayer.FillHomePage(input);
return View(model);
}

When the view engine receives the command to render the view named, say, index, it then checks all display modes and tries to get a suffix. The suffix is then appended to the view name. So, for example, if the smartphone context condition returns true, the actual view employed will beindex_smartphone.cshtml.

Note that any device-specific view is a full-fledged view that can contain whatever HTML you want it to, including RWD code and media query expressions. This is not a bad idea because, for example, you can rely on RWD to make the view fit nicely in tablets and minitablets or smartphones of different screen sizes. Finally, consider that RWD is still the most effective way of detecting changes between portrait and landscape mode.

Responsiveness through client-side device detection

Yet another option for device detection is calling a remote service to get details about the local device. Based on the received information, you then proceed to tweak the page to adapt it to the specific device.

This approach is sort of a middle ground between RWD and server-side detection. More than RWD, it allows you to increase usability because you can create new HTML elements on the fly to create device-specific use-cases. In a mobile-first perspective, this approach is excellent, because you download the absolute minimum for small devices and download extra content as needed. Relying on a server-side service ensures reliable detection of the device.

Many scripts have been around for a while to make client-side detection happen. The most reliable is a branch of the WURFL project. Add the following script element to your pages:

<script type="text/javascript" src="http://wurfljs.com/wurfl.js"></script>

You get the following JavaScript object downloaded in your page:

var WURFL = {
"complete_device_name" : "...",
"is_mobile" : false,
"form_factor" : "..."
};

The form_factor property can contain any of the following strings: Desktop, App, Tablet, Smartphone, Feature Phone, Smart-TV, Robot, Other non-Mobile, Other Mobile. That gives you the basic information; the rest is up to you. By the way, the wurfl.js script is free.

Single-page applications

A single-page application (SPA) is a web application based on one or just a few distinct pages. The building of the interface happens through a series of related calls that progressively download HTML, JavaScript, and CSS. As the user interacts with the application, the user interface is modified entirely on the client. The experience is smooth and fluid, and performance is usually excellent.

The canonical example of a SPA is Gmail. For sites subject to huge volumes of traffic, a SPA might be an attractive option because the amount of work required on the server side is dramatically reduced. Conversely, the insane power of personal computers, and the still-relevant power of tablets and devices, is squeezed out, thus bringing about a better balance of work between the client and server.

Presentation logic in a SPA

A SPA is characterized by thin server architecture and thick client. A large share of the logic that would live on the server in a classic web application is moved to the client. This includes the entire presentation logic and also large chunks of the application logic.

The orchestration of tasks following users’ actions might likely take place on the client. The client, therefore, contains logic to coordinate multiple calls to the back end. As a result, the role of the web server in some cases changes dramatically and scales down to be a mere façade for data exchanging.

This is just one possibility though.

Similarly, you can create a task oriented application with logic in the server and sending commands from JavaScript. In this case, the server is not just a mere data publisher. You can have most of the orchestration done on the client, but the core business logic still stays on the server where data will still be validated due to security reasons.

You should note that while the inspiring principles of a SPA are stable and mature, the actual implementations can differ quite a bit for the distribution of application logic between the client and server. In other words, it’s OK to have a thin server, but how thin it actually is might be numerically different from one application to another. In implementations where the client is particularly rich, the overall architecture is not really different from the old-faithful client/server architecture of some decades ago. The web client is as rich and smart as Visual Basic clients of the 1990s, and the web front end plays the role of the Microsoft SQL Server database of that time.

The MVC-like organization of the client

The typical workflow of a SPA is summarized in Figure 6-6. The SPA makes its first request to the server just to get some initial HTML. Once some user interface has been presented and the application is fully initialized, any successive interaction takes the form of HTTP requests uploading and downloading JSON data.

Image

FIGURE 6-6 The typical workflow of a SPA: an initial request for HTML followed by a long list of requests for JSON data.

Requests can be for things as simple as basic CRUD operations on data in a plain REST style or for server-side commands that might trigger transactional tasks.

In general, if you decide to jump on the SPA bandwagon, it’s likely because you want to make the most out of the client and get a better user experience. So any changes to the user interface happen via direct modification of the DOM. This means that your JavaScript files might be full of snippets like the one shown here:

$.getJSON(url)
.done(function (data) {
// Access the DOM here
});

Invoking the URL in response to an event is part of the presentation layer; what happens in the done function is arguable. If it’s simply DOM updates, we can consider it part of the presentation. If it involves linking to other operations, it’s orchestration and the whole thing all of a sudden becomes part of the application layer. Anyway, we admit this distinction might be essentially pointless, but ignoring where each piece of code actually belongs is the surest path to building big balls of mud. Let’s say that the ugliest part of that code is the direct binding of HTML elements in logic that might not be pure presentation.

In general, single-page applications use comprehensive frameworks such as AngularJS to gain a bit of structure and some conventions. Most frameworks for SPA push an MVC-based pattern for the organization of the client code. Some opt for MVC; others opt for MVVM. In the end, the difference is minimal and, anyway, nothing different from what we stated earlier about server websites: each view is abstracted to a view model, including subviews.

Depending on the specific framework, actions on the view belong to a separate controller class (MVC) or are exposed as methods out of the same view model class (MVVM).

Bidirectional data binding plays a key role in a SPA because it’s the way through which downloaded data is bound to visual elements. AngularJS and other frameworks (for example, KnockoutJS) let you use ad hoc HTML attributes to indicate which property of the bound view model links to a particular HTML element. This is the KnockoutJS way of creating a UL looping through the matches property of the view model and displaying for each match the value of the Team1 and Team2 properties:

<ul data-bind="foreach: matches">
<li>
<span data-bind="text: Team1"></span>
vs.
<span data-bind="text: Team2"></span>
</li>
</ul>

In this way, it’s the binding code that goes to the HTML and not vice versa when HTML elements are mixed with JavaScript code.

Transferring data from the server

To build the back end of a SPA, you just need to expose a few HTTP endpoints. This can be done in a variety of ways, ranging from WCF to HTTP handlers, from an ASP.NET MVC site to Web API. In general, no technology is necessarily more favorable than the others. However, we should note that Web API is the leanest of all and also the most recent and well-designed when the concept of SPA was developed. Our guideline, then, is to use Web API unless you have other stronger reasons—mostly legacy reasons—to do otherwise.

When it comes to creating a Web API façade, you can take the REST route or even the RPC route. The REST route means you define one or more resources you’ll be exposing over the web through the classic HTTP verbs—GET, POST, PUT, and DELETE. The RPC route means you just expose endpoints for actions and use ad hoc data-transfer objects to move data around.

Yet another option to consider is Open Data Protocol (OData). OData is a protocol designed to expose a data source over the web in order to perform CRUD operations. Originally defined by Microsoft, the protocol is now being standardized at OASIS. In the end, OData implements the same core idea as ODBC, except that it is not limited to SQL databases and lends itself to interesting uses over the web.

The protocol offers several URL-based options for users to query for metadata, query for flat and hierarchical data, apply filters, sort and, last but not least, page. You might want to check http://www.odata.org for more information on the protocol and details about the syntax. As an example, consider the following URL corresponding to a Web API endpoint:

/api/numbers?$top=20&$skip=10

By enabling OData in Web API, you can have your client place calls that will be interpreted to filter the data being returned. In a way, OData can be seen as a queryable interface over the server data exposed to the JavaScript client. In the context of applications that see the back end mostly as a data server, a bunch of OData endpoints can really cut down the complexity of many use-cases and also the amount of code written and run on the server.

Possible hidden costs of a SPA

What we summarized so far is the theory of SPAs. In principle, it’s a great idea, and the thin server and the thick client work together beautifully. At a higher level view, we see that a SPA sits in between the classic world of the web and the classic world of desktop applications. And, at least for the time being, the approach is far from capturing the best of both worlds.

The issues with the SPA model are largely related to the conflict between the old way of using the web and the new way of using the web that a SPA pushes. The SPA model works great if we break up the consolidated practices of the classic web. We mean things like the page refresh, deep linking into the site, tabs, and maybe more. The hidden costs of building a successful SPA are here.

Best practices and specific HTML5 APIs exist (for example, the History API) to smooth out or wipe out these problems. So building a SPA that works and doesn’t bring a long queue of complaints is definitely possible. At the same time, in our opinion, embarking on a SPA project on the wave of enthusiasm for a demo application that some guru showed around is risky. You need mastery and expertise to tame the SPA beast.

We want to call your attention on a couple of points:

Image Be extremely clear about what you expect out of a SPA, and make it clear with customers that SPA is a new form of using the web. A SPA is closer to a desktop application just built and deployed over the web. Precisely for this reason, it moves from deep statelessness to deepstatefulness. It’s not a minor change. Realistically, in an enterprise world, a SPA might require a bit of extra time for syncing up users with interfaces.

Image The SPA model doesn’t work well in the mobile space. Be skeptical about the possibility of writing a SPA once, running it on a variety of mobile devices, and even turning the app into a native application for all mobile systems of the foreseeable future.

Except for this, everything else works like a charm!

Desktop rich client

Our neat perception is that the number of deployed desktop applications is still very high but the number of new applications is decreasing and are being replaced by rich web front ends (for example, SPA) and native mobile applications. It was not coincidental that this echoes our previous statement about SPAs being halfway between the web and desktop and that it heralds a new web that is envisioned like desktop-style applications that are just deployed as websites.

Whether the rich client is physically built with WPF and XAML and compiled to Windows 8, or as a Windows Store application, or just as a SPA or mobile application, the overall architecture—which is our primary concern here—remains nearly the same.

Classic WPF applications

When the front end of the system is a WPF application, the way to go is already paved. You use the MVVM pattern to model each screen into a class with public properties and methods. Properties represent bindable visual elements, whereas methods represent actions triggered by the user interface. The code in these methods invokes application-layer endpoints. (See Figure 6-7.)

Image

FIGURE 6-7 General schema representing the MVVM pattern as implemented in a XAML-based application.

The deployment of the application layer can take any form, and there are really no globally accepted rules that make a choice stand out. The application layer might be entirely on the server, entirely on the client, or split between the client and server.

The only discriminating factor we like to point out is that the application layer deployed on the client requires a lot more network traffic, because it configures a chatty model of interaction between the client and server instead of a sober and plain chunky model—make a request, let the server do the job, and wait for results or error message.

Web rich clients

Not that many years ago, Dino would have bet the farm on browser plugins like Silverlight conquering the world, dismissing HTML and JavaScript. Thankfully, that never happened (the betting, actually). Today when you say rich client over the web, the only thing that comes to mind is SPA on top of HTML5.

It should be recalled, however, that HTML as we know it today with the wide range of surrounding frameworks (such as WebSockets, local storage, IndexedDB, rich input, SVG, canvas, history and more) is significantly different than the HTML of five or six years ago, at the time Dino was going to bet the farm on Silverlight. The HTML of today is a close relative to Silverlight in terms of additional functionalities over the plain DOM.

Even before Microsoft pushed Silverlight into the corner, the industry trend was to proclaim HTML as the winner. Now the challenge for having successful and rich solutions deployed over the web is finding the right balance between the old and new web, and taking some time to educate customers about the new web, where Back and Forward buttons might not work and deep linking might be optional. Preserving the state of the application over the web is problematic, even though nobody is entirely shooting in the dark and solutions (and ad hoc frameworks) exist.

In terms of architecture, a rich web client is a single-page application if based on HTML and is a Silverlight application otherwise. If it’s a Silverlight application, it follows the same pattern of Windows Presentation Foundation (WPF) desktop applications as far as the presentation layer is concerned.


Image Note

Silverlight applications are still supported and, when written, they work. However, choosing between updating an existing large Silverlight application and building a brand new HTML application is a tough call for architects and CTOs. In general, Silverlight is not going to have a brilliant future. For what it’s worth, this has little to do with Silverlight itself, and to a large extent the same can be said for Adobe Flash. The change of perspective is due to a change in the devices industry rather than just the quality of plugins.


Native mobile applications

A native mobile application—whether it’s running on iOS, Android, Windows Phone, Windows Store, or other platforms—is, architecturally speaking, comparable to a desktop client of a layered system. It communicates with the back end using HTTP services and implements the presentation layer and at least chunks of the application layer on the device.

The organization of the user interface depends on the presentation idiom supported on the platform. That is plain MVC on iOS and MVVM on Windows Phone and Windows Store. Conversely, there’s no direct mapping with a recognized pattern in Android even though the inspiration of MVC is clearly visible.

A point we would like to reiterate is that the application layer is the implementation of the use-cases exposed by the presentation layer. For this reason, the presentation and application layers go hand in hand. If the mobile front end requires a different set of use-cases, the application layer should be tailor-made. Having part of the application layer incorporated in the device, and using a chatty model instead of a chunky model, might reduce the amount of code that needs to be written or refactored on the server back end to support a new mobile front end.

Summary

Once upon a time, architects had one insanely powerful computer (the server) to deal with, a few insanely slow personal computers and, more importantly, a mass of forgiving and passive users humbly accepting any user-interface rules from highly respected developers. (The chief architect was usually put just one level or two below God.)

Now it’s a different world. The mass of users is much less forgiving and even dictate strict user-interface requirements. So user experience is all the rage today, but for the most part we keep on designing systems the old way, focusing more on storage than users.

UX-first is a design philosophy that suggests you start from the presentation layer and run a preliminary analysis on a double track—collecting business domain data and UX data that can guide you to design interaction models that work for the user before they are made to work for the system. The goal of UX-first is building screens as users love them, and once wireframes and mockups of screens are signed off on, you start defining data workflows from here and domain logic, services, and storage.

In this chapter, we discussed the user experience and the structure of the presentation layer in a few realistic scenarios, including websites, mobile websites, single-page applications, and desktop clients.

Finishing with a smile

A lot has been said about the usability of programs, and we said a lot about the importance of delivering a system that works as expected and, more importantly, provides the features that customers really need. Making jokes about the user interface of computer programs, however, is like shooting the piano man—it can sometimes be way too easy and way too fun. For more tongue-in-cheek Murphy laws beyond the following ones, have a look at http://www.murphys-laws.com:

Image The only thing worse than an end user without a clue is an end user who has a clue—usually the wrong one.

Image When designing a program to handle all possible dumb errors, nature creates a dumber user.

Image Build a system that even a fool can use and only a fool will want to use it.