February 2016

Volume 31 Number 2

[Cutting Edge]

Architecture Spinoffs of UXDD

By Dino Esposito | February 2016

Dino EspositoYears go by and I’m just happy if I know and can recommend one or two effective ways of doing most software things. Don’t let the emphasis of software marketing fool you. Software improves constantly, but software is not the core business of most companies out there. This means that it’s more than acceptable for companies to keep using the same software for many years. According to the Tiobe.com index, in the summer of 2014, Visual Basic 6 was still in the Top 10 of most used programming languages. A year and a half later, it dropped quite a few positions, however. This seems to confirm the trend that the silent majority of companies tend to postpone full rewrites of software as much as possible. Realistically, the silent majority of companies have at least a five-year backlog in software technology that’s still running in their businesses. But when it’s time for companies to update those backlog systems, architects will look for state-of-the-art software.

Software Architecture Today

As far as software architecture is concerned, a couple of keywords are buzzing around these days. One is “CQRS,” which is the acronym for Command and Query Responsibility Segregation,  and the other is “polyglot persistence.” I covered CQRS in a series of Cutting Edge articles recently. For a primer, you might want to read “CQRS for the Common Application” (msdn.com/magazine/mt147237) in the June 2015 issue of MSDN Magazine. CQRS is an architectural guideline that simply recommends you keep distinct the code that alters the state of the system from the code that reads and reports it. Broadly speaking, polyglot persistence refers to the emerging practice of using multiple persistence technologies in the context of the same data access layer. The expression, polyglot persistence, summarizes in two words the complex technical solutions adopted by social networks to deal with the humongous amount of data they have to manage every day. The essence of polyglot persistence is to just use the persistence technology that appears to be ideal for the type and quantity of data you have.

While both CQRS and polyglot persistence have noticeable merits and potential benefits, it’s sometimes hard to see their relevance in the context of a complex business application to revive from the ashes of a Visual Basic 6, Windows Forms or Web Forms large code base. Yet, relevance exists and missing it may be detrimental in the long run for the project and the company. At the same time, software architecture is not an act of faith. CQRS might seem like a great thing, but you must find the right perspective to see it fit into your scenario.

Well, if you look at software architecture through the lens of UXDD, you can easily find a fit for both CQRS and polyglot persistence.

Task-Based Design

Forms of UXDD workflows are being used already in companies of every size and I’ve personally seen flavors of it in small teams of 10 people or less, as well as in multi-billion dollar enterprises. When this happens there’s a UX team that elaborates screens in collaboration with end customers, whether internal or external. The UX team produces some colorful artifacts in the form of PDF or HTML files and delivers that to the development team. The issue is that most of the time the development team ignores such artifacts until the entire back-end stack is designed and built. Too often the back end is designed taking into little or no account the actual tasks performed at the presentation level. As architects we diligently take care of the business-logic tasks and think of ways to optimize and generalize the implementation. We don’t typically care enough about bottlenecks and suboptimal data presentation and navigation. When we get to discover that the actual experience users go through while working the application is less than ideal, it’s usually too late to implement changes in a cost-effective manner, as shown in Figure 1.

Bottom-Up vs. Top-Down Design of a Software System
Figure 1 Bottom-Up vs. Top-Down Design of a Software System

Let’s face it. Well beyond its undisputed effectiveness for data storage, the relational model is misleading for software architecture. Or, at least, it started being seriously misleading after its first two decades of life. Already in the mid-1990s in the Java space the mismatch between relational and conceptual data models was a matter of fact that led to experimenting with O/RM tools. Generations of software architects (now managers) grew up with the idea that all that matters is a solid database foundation. No doubt that a solid database is the foundation of any solid software. The problem is the complexity and the amount of domain and application logic. It was no big deal until it was viable to add bits and pieces of such logic in stored procedures. Beyond that threshold software architects evolved toward the classic three-layer architecture (presentation, business, data) and later on in the domain-driven design (DDD) layered architecture: presentation, application, domain and infrastructure. No matter the number of layers, the design was essentially a bottom-up design.

The bottom-up design works beautifully if at least one of the following two conditions is verified:

  1. The ideal UI is very close to the relational model.
  2. Your users are dumb and passive.

Software design seems an exact science when you look at tutorials ready-made to promote some cool new technology or framework. As you leave the aseptic lab to move into the real world, software design becomes the reign of fear, doubt and uncertainty—the no-man’s land where only one rule exists: It depends.

UXDD simply suggests you don’t start any serious development until you have some clear evidence (read: wireframes) of the ideal architecture of the information and the ideal interaction between users and the system. Top-down design starting from wireframes of the presentation layer guarantees you get really close to what users demanded. The risk of hearing the nefarious words “this is not what we asked for” is dramatically reduced. Keep in mind that if a wireframe is labeled as wrong, it’s never a matter of preference; it’s more likely a business matter. Ignoring the feedback of wireframes is likely creating deliberate bugs in the resulting system.

Figure 2 summarizes the architecture impedance mismatch nowadays. We have wireframes that describe the ideal presentation layer and we have the code that implements the business logic as it was understood. Unfortunately, more often than not, the two don’t match. If software projects rarely live up to expectations—especially from a financial point of view—are you sure it’s not because of the architecture impedance mismatch?

Architecture Impedance Mismatch
Figure 2 Architecture Impedance Mismatch

Addressing Architecture Impedance Mismatch

It turns out that a comprehensive domain model that covers the entire spectrum of the domain logic makes no sense at all, to put it mildly. The idea of domain models, and the entire DDD approach, came up to tackle complexity in the heart of software, but that was more than a decade ago. A lot has changed since and while some core elements of DDD—specifically the strategic design concepts and tools—are valuable more than ever today, an object-oriented domain model that comprehensively covers all read-and-write aspects of distinct bounded contexts is painful to build and unrealistic.

At the same time, the idea of a comprehensive domain model is aligned with a bottom-up vision of the software where you understand what users want, elaborate a model, code the model and then put some UI on top of it. As funny as you might see it, successful software is a nice and effective UX on top of some magical black box (MBB).

If you start any engineering effort from wireframes, then you know exactly what the MBB has to support effectively. And you also know that as long as the MBB does its job the system is really close to what users formally asked for. There’s hardly any room for developers’ assumptions and most of the iterations with customers are grouped in the initial phase of the project. Any change is cheap and once the UX tests have passed, most of what remains has the relevance of an implementation detail.

UXDD puts emphasis on tasks and events. In a top-down design, the starting point is a user action like a click or a selection. Each user action is bound to an entry point in the application layer. As an example, in ASP.NET MVC that means that every controller method (presentation layer) is bound to an entry point in an application layer class, as shown in Figure 3.

Figure 3 CQRS Controller

public class SomeController
{  
  public ActionResult SomeQueryTask(InputModel input)
  {
    var service = new QueryStack.SomeService();
    var model = service.GetActionViewModel(input);
    return View(model);
  }
  public ActionResult SomeCommandTask(InputModel input)
  {
    var service = new CommandStack.SomeService();
    service.GetActionViewModel(input);
    RedirectToAction(...);
  }
}

The two SomeService classes are the section of the application layer that’s visible from the part of the presentation layer represented by the SomeController class. The two SomeService classes may be part of the same physical project and assembly as the presentation or be distinct assemblies and projects. Consider that, architecturally speaking, the application layer goes hand-in-hand with the presentation layer. This means that when multiple presentation layers are required (that is, Web, mobile Web and mobile apps) it’s acceptable to have multiple application layers with subsequent limited reusability of the logic.

You will have an entry point method in the application layer for each possible task the user might trigger from the approved UI. If you faithfully reproduce the wireframes you received, you know exactly what comes in and out of each screen. You just can’t make it wrong. It can, perhaps, be inefficient or slow, but never wrong.

The application layer exchanges data-transfer objects with the presentation and orchestrates any required workflow for the task. In doing so, the application layer typically needs to read and write data from some persistent store, access external Web services and perform calculations. That’s just domain logic and domain logic is invariant to use cases. Whether requested from a Web or mobile presentation, the business domain task runs the same and is fully reusable. In short, the idea of business logic is split into two more specific segments—application logic as the logic necessary to implement specific presentation use cases, and domain logic that’s invariant to presentation and use cases.

The domain logic can be designed according to a variety of patterns, including Transaction Script and Table Module. In these cases, the business rules are a foreign body injected in the classes you use. Typically, business rules form a calculator you invoke to get a response about the feasibility of an action. The Domain Model pattern—often misrepresented as the true essence of DDD—is simply a pattern that suggests you create classes that behave like the real entities and subsequently incorporate the business rules and hide their application in the methods they offer. There’s no right or wrong way of designing domain logic—it’s a pure matter of attitude and effectiveness.

In a task-based design, you see immediately if the action alters the state of the system or reports it. By using a CQRS design, you naturally split commands from queries, and having them in separate stacks brings the obvious benefits of writing and optimizing them separately with no risk of regression, even with the potential of simplified scalability. CQRS is a natural fit in a UXDD context.

Persistence at Last!

Proceeding from the top to the bottom, inevitably persistence is the last of your concerns. Don’t get it wrong: All applications need to have data persisted effectively and data that can be queried effectively. The last of your concerns doesn’t mean you neglect persistence; it just means that in a user-oriented, interactive system, the design of persistence becomes critical only after other aspects—specifically UX and domain logic—have been cleared out. Just because of this, you have no constraints on which database technology should be used. Moreover, if you have a CQRS design, then you can easily have multiple persistence layers, one for commands and one for queries, managed independently and even—if that helps—based on different storage technologies and paradigms. For example, if you know that at some point analytics must be reported to the UI, you might want to adopt an event-sourcing framework and track each update and relevant actions as an event. This will give you the full log of whatever happened in the system and can be used at some point as the starting point of self-made business intelligence analysis. At the same time, if you need ready-made data to quickly serve to the user, you just keep the event store synced-up with a projection of the data that suits your presentation needs. A projection of data in this context is the state generated after a list of actions. It’s the same as willing to know the bank account balance (the projection) resulting from a list of transactions (events). The query stack is often simply made of plain SQL Server views whereas the command stack might be based on relational tables, NoSQL or event store, including any combination thereof.

This is just what some call polyglot persistence.

Wrapping Up

Like it or not, users judge the system primarily from the gut feeling of their direct experience. Today, the key factor to save money on software projects is ensuring that you create, right away, exactly what users want. It’s not just about doing it right, but doing it right, right away. With UXDD you know as early as possible for which output you’re going to create the system and this cuts down the fixes to apply when you deploy the system and users don’t actually like it. Furthermore, with a top-down design your design experience is naturally led toward modern patterns such as CQRS and polyglot persistence that, well beyond the level of buzzwords, are proven practices to build effective software.


Dino Esposito is the coauthor of “Microsoft .NET: Architecting Applications for the Enterprise” (Microsoft Press, 2014) and “Modern Web Applications” (Microsoft Press, 2016). A technical evangelist for the Microsoft .NET Framework and Android platforms at JetBrains and frequent speaker at industry events worldwide, Esposito shares his vision of software at software2cents.wordpress.com and on Twitter: @despos.

Thanks to the following technical expert for reviewing this article: Jon Arne Saeteras