Application Architecture: The Aspects of Development


This is the first in what is likely to be a long series of entries, as there are many introductory topics that people are missing when it comes to developing quality software. This particular post comes from an idea I have for a book on getting people focused on application architecture (or designing applications, if you like to think in those terms) and development.

At the Nashville .NET User’s Group Christmas party, I got into a conversation with John Kellar about application architecture. He stated that the important things in application architecture can go by the acronym ARP, which stands for Availability, Reliability and Performance. I don’t disagree with John on these, as these are 3 noticeable points of “failure” in applications. By noticeable, I mean these points are areas of concern for end users as they manifest themselves very clearly in the user interface.

I understand what John was saying, and we agree on application architecture to a very large extent. But many may see the P in ARP as a call to ensure every routine runs in the fewest number of milliseconds, no matter how complex the code gets. Or the A as making sure every web app has a web farm of servers supporting it. And this takes us to a very myopic view of the architecture, or design, world.

I have yet to come up with an acronym for the entire picture. When I look at development, I see a wheel, like this:

DevelopmentWheel

I like using a wheel as pictured above, as it makes for a nice analogy. Like balancing the tires for a smooth ride, you will have to weight the different aspects for  smooth application development, deployment and maintenance. Improper weighting leads to a bumpy ride. In worst case scenarios, it leads to a flat tire.

Here is a breakdown of what the aspects (of development) on the wheel mean (in alphabetical order, not order of importance – more about order of importance later):

  • Availability: The ability to get to the application to use it.
  • Extensibility: The ability to add new features.
  • Maintainability: The ability to change the code base easily.
  • Performance: The ability to run quickly.
  • Reliability: The ability to reliably serve data and persist alterations to data back to the data store.
  • Scalability: The ability to add additional users without breaking the application
  • Security: Ensuring only properly authenticated users can use the application and only see data they are authorized to see.

There is no one size fits all answer to what you put the greatest focus on. Just like a wheel on a car, you add weight to different parts of the wheel to balance it. Why not focus on everything? The problem is you can’t. Examples:

  • Scalability often requires moving application bits across multiple servers, but server boundaries introduce network lag and decrease performance.
  • Performance often requires very tight algorithms that only advanced developers understand, but complex algorithms make a solution less maintainable as you have to keep advanced developers on staff for maintenance (where they generally DON’T wish to be).

Performance is Overrated

I am possibly going to get in trouble for this statement, but stick with me until you finish this section before firing off comments. First a disqualifier. When I talk about performance being overrated, I am talking two things:

  • In most apps (Google excluded?) you have more than enough horsepower in your system to perform the application with a simple algorithm
  • In choosing performance, if both algorithms are equal in complexity, then performance IS NOT overrrated

The statement is a generalization from my years answering questions in forums. Many, if not most, of the questions in forums relate to one of two types of questions:

  • Can you solve my problem? This generally means “fix the problem the way I am trying to solve it” rather than “fix the problem”
  • Which of these runs faster?

The focus on performance is so heavy that people are often creating very complex algorithms to compare against simple constructs. When someone asks “should I run a binary compare or convert to strings first” I will ask “do the people maintaining the application understand binary comparison?” If yes, then go for the faster algorithm. If no, then you have to weigh if using a binary compare is necessary to achieve your performance goals (in one application I worked on many years ago, the answer was yes, despite the learning curve associated).

I should also state that on a personal level, you should learn complex algorithms. They can set you apart from the competition when you try to get jobs, are going for a raise, etc. I just don’t buy the “we have to use the fastest algorithm” argument in all applications. In fact, I would say I am generally against complexity except when needed.

Here are a couple of things I know to be true:

  • Processors will get faster in the future
  • Memory will get faster in the future
  • The price of  new technology goes down over time, after the R&D expenses are recouped
  • Memory, processors and even servers cost less than rock star developers

There are times when you will have to use complex algorithms, or even go to a C++ (or C) DLL to get maximum performance for you application. When you do, I suggest encapsulating the routine in its own library, where it can be maintained separately from the solution. This is not always possible, but it is a good rule of thumb. And,m if you program for Google, you might be writing complex algorithms most of the time. For the rest of you, weigh out your performance needs.

A quick story. In 1998, I worked for a company as a web developer (title: webmaster). The company was trying to determine the direction to go with development and I was asked to put together a brief presentation on the route I would suggest. I chose Visual Basic as the direction. My reasoning:

  • There were tons of VB developers in Nashville (resource intensive)
  • The cost of VB developers was lower than other languages (except perhaps mainframe programmers)
  • The VB skillset translated well to ASP, which was our preferred web framework

When I presented the findings, one developer fought for C++. His reasoning? Performance. The stalemate was solved by paying a consulting company about $100,000 to determine the best course of action. They recommended VB. While I did not think of it at the time, here was our situation:

TimeUsers

NOTES

  • The red line is the slowest the app could run.
  • The green line was the max we felt the app would need to scale over the next year (very aggressive number)
  • The C++ figures were extrapolated from an app we migrated from C++ to ASP, so they are not necessarily accurate

As you can see, C++ performed much better. From a sheer performance aspect, it is a logical choice. But when we look at requirements of the application, C++ was not worth the cost, as the VB application performed well under the bar for the next year. Realize also, that we could have chosen a beefier application server or a web farm before choosing C++ and incurring the extra expense for developers.

Now, there are times when an algorithm choice is sane, even if you are not focused primarily on performance. Consider the following:

Code Snippet
  1. public int Multiply(int a, int b)
  2. {
  3.     int returnValue = 0;
  4.     for (int i = 0; i < b; i++)
  5.     {
  6.         returnValue += a;
  7.     }
  8.     return returnValue;
  9. }
  10. public int Multiply(int a, int b)
  11. {
  12.     return a * b;
  13. }

The second algorithm is superior to the first, both on a performance standpoint and a maintainability standpoint. I would not choose the first, even though it solves the problem. But if I had to choose between lambda expressions and LINQ, I might default to LINQ, despite a slight performance penalty, as it is easier to teach LINQ than lambda expressions. Perhaps not the best example, as I love lambdas, but I think you get the point.

DEVELOPER NOTE: The difference between the two algorithms is largely based on the size of the number. If you are dealing with small numbers, there is absolutely no difference between the two algorithms, so the choice is largely a maintainability choice (and perhaps reliability, as complex algorithms are more error prone).

The Most Important Aspect

As I mention above, the application determines where you put the weight(s) to balance the wheel for a smooth ride. But, if I had to choose one aspect to focus on, it would generally be maintainability. Maintainability costs business more than any of the other aspects. This goes back to “programmers cost more than servers”, but also deals with the fact that an application spends more of its lifecycle in maintenance than development.

To understand the mindset of the majority, let’s look at a statement I have heard many times in my career (this is a paraphrase, the words change):

A simple problem has a simple solution
A complex problem has a complex solution

I see this a bit differently, as I tend to start with maintainability and then adjust based on the application needs:

A simple problem generally has a simple solution
A complex problem generally has one or more simple solution(s)

Does this mean I never write complex code that requires a rock star to maintain it? Certainly not. There are times that require very complex algorithms to fulfill the requirements of the application. In general, however, highly complex algorithms are not necessary.

Back to The Aspects

When I mentioned John’s concept of ARP, I said these were external concerns, or those related to the user interface. Here is a brief breakdown of all of the aspects when viewed from different people. I am using the typical concerns in the order I see them and not necessarily the order I feel they should be placed in.

AreasOfConcern

The main takeaway here is ARP is very important in holding and keeping customers. A site that is unavailable, unreliable or slow must be extremely compelling to keep users using it. If it is an internal application, you have a bit of a fudge factor, as users HAVE to use the application, but these concerns should be weighed in. On the other hand, you need to worry about other aspects as well. As the architect, you have to think of all of these four groups and weigh which concerns are the most important. You never neglect any of the aspects, but like truing a tire, you weight them properly for a smooth ride.

Takeaways

Here are a few things you should get from this blog entry:

  • There are many aspects to development
  • Each application is different, so you have to weight the aspects of development for each application.
  • Keep the skill set of the maintenance crew in mind as part of your weighing effort
  • Your personal focus will often depend on which role you are playing at the time, but be mindful of other roles (esp. as an architect)
  • Rule of thumb: Only go as complex as necessary to solve the problem projected out for the lifetime of the servers invovled
  • Rule of thumb: When in doubt err on the side of maintainability – this will buy you more from management in the long run, although you often have to summarize the ROI to get the kudos
  • Key point: Improper weighting of development aspects leads to a bumpy ride.

Hope this helps.

Peace and Grace,
Greg

Twitter: @gbworld

Future Topics Planned (will add links to topics when done):

  • What is an Application?
  • What are the Best Requirements Documents?
  • The Software Development Lifecycle
  • What Development Methodology Should I Use?
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: