We need to rethink application architecture


I was answering a question on architecture this morning in which the person was asking how to lay out an application. There were three things that hit me and they are three things I see often in development.
  1. The poster seemeed to feel that small applications are best set up as monoliths, with all of the code in the ASP.NET application, while big applications should be tiered.
  2. The poster seemed to feel that you can either develop applications from the bottom up or top down.
  3. The poster was highly focus on the fact he was developing an "ASP.NET Application"

All of these are mistakes, in my opinion.

Application Labeling and Development

First, let’s look at how we label applications. I often hear people say, I am building a windows forms application, or I am building a WPF application, or even I am building a back end application. This is just plain wrong. You are not building an X application. You are building an application to solve a business problem. You are using ASP.NET for your user interface, or presentation, tier, but the application is not defined by the UI technology, or at least it should not be.

This type of thinking is why we end up completely rewriting our code when we add a new UI technology. We also brand applications by UI, so we have MyApp and MyApp Web or visa versa. And we treat the web app and windows apps as two separate apps, even though they are solving the same problem.

Tiering, or layering, applications is not new. Microsoft pushed this concept heavily in the COM world, even labeling it Distributed Network Architecture, or DNA. ANd, in the COM world, some people actually got it. The worm has turned, however, and many of the .NET technologies are not conducive to tiered architecture. The original 2.0 DataSet model illustrates this. And, since it is easier to leave the TableAdapters in the data object project, we find many people leaving it that way.

Microsoft is trying to separate concerns with technology, but you cannot force out bad process with technology. The original ASP.NET model was designed to separate code from UI, but the code behind classes were still UI and developers still loaded them with business logic, often without dividing the work into routines that could be refactored to tiers. With WPF and Silverlight, they took this a step farther, but there are still people putting business logic into WPF/Silverlight libraries, controls, etc. ASP.NET MVC takes this one step farther by making the ASPX classes, or views, "stupid". You cannot write much code in a view and it is hard to write code that is not UI related in the view. But, you can still load up your controller with lots of business and data logic, so they have not really solved the problem; they have just forced the errant developer to move the code on class lower on the food chain. It is still mixing business/data logic with the UI tier/layer.

The problem is exacerbated by the samples out on the web. Take, for example, the following code from a prominent member of the ASP.NET MVC team:

namespace MvcApplication5.Controllers
{
  public class ProductsController : Controller
  {
    NorthwindDataContext northwind = new NorthwindDataContext();

    [ControllerAction]
    public void Create(string ProductName, int CategoryID, int SupplierID, double UnitPrice)
    {
      Product product = new Product();
      product.ProductName = ProductName;
      product.CategoryID = CategoryID;
      product.SupplierID = SupplierID;
      product.UnitPrice = UnitPrice;

      northwind.AddProduce(product);
      northwind.SubmitChanges();

      RedirectToAction(new { Action = "Category", ID = product.CategoryID });
    }
  }
}

I am not here to dink the sample, as I feel samples teach concepts and not necessarily architecture. I also have great respect for the person who posted the code and have seen other examples of his work that do not blur the lines. The problem is not the sample, but what the developers reading the sample do. Seeing this in a blog entry, they assume this is a proper pattern.

Notice what happens here. If I build my entire ASP.NET MVC application in this manner and my boss states that he wants a WPF version of the app (or windows forms), I have to rewrite the entire application, as my data access (LINQ) is set up in my controller. Not a good way to build applications. Fine for samples, but bad for applications.

If this were an isolated incident and only related to samples, I would skip the entire thought process. But, I see this all the time. There are a couple of reasons for this:

  1. Few people are releasing books and articles to shift this way of thinking – and it is a paradigm shift. When the trainers are not teaching it, the masses will not learn.
  2. The drag and drop tools are set up, at least initially, where they blur the lines and do a bad job of separating concerns. And when they add bits that separate concerns, like the bits that divide the TableAdapter from the DataSet, it is not the default.
  3. There is a misconception that it costs lots of time to tier/layer an application.

Item #3 is somewhat true, but much of the time is only eaten the first time, as there is a learning curve. After the curve is crossed, the developer no longer needs to eat from that trough every time. There is still a bit of overhead, but it is more overhead in defining what you are building, which you SHOULD be doing anyway. It may also be overhead in writing tests and other code quality practices, but that is a story for another post.

I am working on a book right now, with no publisher yet. It is focused on properly tiering applications and I am focusing it on Visual Studio 2010. That will help with item #1, but we need more people doing this to turn the tide.

I cannot do anything about item #2 and neither can most of you. The only thing we can do is give feedback to the folks developing the tools and teach people how to overcome drag and drop as a liability.

Development Style

Tiering applications is not enough. The other practice we need to get to is defining applications in light of business. Business drives development; development does not drive business. I know this is an ideal that is not often met, but it should be.

I am all for Agile methodologies, as I see they are the best way to respond to changing business needs. I am against the concept that Agile and requirements do not mix. I don’t mind thinning down requirements, but an application without requirements is an application doomed to fail.

At minimum, I feel you need to have a good set of use cases. Properly done, the use cases describe the business process involved and do not get heavily into technology. Business people should not be designing databases or applications. Leave that to the developers. But, you should have a firm understanding of what is being accomplished before you start coding.

With a good set of use cases, you can more easily divide into teams and get everyone started from day one. The tester can start developing tests, even though he cannot fill them in. The technical writer can start writing manuals and help files, although he cannot get into firm specifics. And, if you take a bit more time to develop the contracts between layers, you can get UI, data and business developers rolling in parallel, not serial. This is powerful and greatly speeds up development. It also forces closer collaboration and communication, when done correctly. Yes, you will have some refactoring in each team, so the efficiency is not aboslutely perfect, but I have never seen optimal development. Remember: Even car engines lose most of the power created by combustion – there is no such thing as 100% efficiency.

If there is one take away, you must understand the process before you can properly build a tool for that process.

Small Versus Large

This one galls me. Perhaps even more than the other two points. Good architecture is good architecture.

Sure, you might take some shortcuts to bang together a quick prototype, but if management sees the prototype as a finished work, you are never going to find the time to refactor it the way it should be. And, once you get the mindset, it does not take that much time to divide the work into libraries and have a UI that is just a facade. As mentioned, you have to change your thinking.

One of the easiest ways to change your thinking is to adopt a Test Driven mindset. Unlike purists, I do not believe you have to always write tests first, although it is the best way. You do have to write them early and make sure you are testing the majority, if not all, of your code. There is a small amount of time taken in writing tests, but some of your tests will be generated once tools like PEX hit the mainstream, so you do not need to hand code to 100% code coverage.

How does TDD help you make your UI a facade instead of an interface with business logic? Simple. UIs are hard to test. This will change in the future, as well, so those of us training people have to hit the bricks before the tools are readily available to test app logic in a UI. After that hurdle is crossed completely, we will be fighting a losing battle.

The point here is small apps need proper architecture, just like large apps. You might shortcut a short lived app, but so many short lived apps become mission critical, so be careful here. You might also shortcut with a prototype, but make sure the owners understand it is a prototype or you will have to live with the mush you just created.

Summmary

What I am stating in this blog entry is an application is not a UI. Applications are code modules that solve business problems. The method of interacting with them is a faceplate. If you get this one item down, you will find you stop thinking "which is bettter? top down or bottom up?". You will also stop calling your apps "ASP.NET app" and "WPF app". And, you will stop thinking you can shortcut small apps. The last is perhaps the most important, as you develop habits when you code. Too many "small" apps and you will develop some pretty decent bad habits.

Have fun coding.

Peace and Grace,
Greg

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: