Articles tagged with: Architecture

Using derivated Exception classes for better error handling

One defect that I've been finding once and again in the past doing .NET projects is a bad exception handling strategy.

Too many times I've seen code that just places a generic try { ... } catch(Exception ex) { ... } code block to capture errors. And of course any code inside throwing generic exceptions (just with different messages).

The System.Exception class it is indeed the basis of any error that happens, but it is a bad habit to reuse it. Exception represents a fatal error, something critical unexpected.

.NET provides the System.ApplicationException class for a simple reason. To catch any exception from our applications.

It inherits from Exception, so a generic catch (Exception ex) would catch it anyway, but by using it, we differenciate between those exceptions generated by our application and those generated by external factors, like for example an OutOfMemoryException.

But if we just use ApplicationException instead of Exception we only have two layers of error levels... Why not going a step further and building a full hierarchy of exceptions?

  • InvalidRuleSetException
  • BLLException
  • ApplicationException
  • Exception

Look at that descending list... We can catch a lot of stuff from different layers:

  • If something goes wrong in our BLL layer while loading a fictional RuleSet, we can just show a message to the user telling him to choose a correct one.
  • If somehow the BLL components break, the presentation layer can catch it and present a "We're having technical problems, please try again later" message.
  • If something goes really wrong in the setup of our web application (for example a wrongly configured IIS), we can silently keep users out of the website without showing them multiple nasty errors.
  • And finally, if the server gets out of free space for the ASP.NET temporal files folder (which has happened to me too), we will avoid more ugly errors or generic IIS error descriptions...

The easy way is to stick to simple Exception throwings and catchings, but it doesn't helps your code readability. And probably, it won't help too much when the application fails and you just get a generic "Exception" in your log (it is amazing, but some people forget to at least log the full stack trace...).

And all of this can be applied to PHP too. PHP contains just two base exception classes, and a few typical derived ones.

So don't be lazy and create a hierarchy of exceptions. You, your colleages, and everyone who could use your code or the compiled components will not regret it, I promise.


Avoiding the break statement

Some coding guidelines and best practices advice against the use of continue and break statements.

With continue the solution is easy, placing an if (or if it existed to call continue, negate it to execute the code).

But with break, it is not always so easy. Some times, in fact the resulting code is more messed up or harder to read (usually because of too much ifs), so I use break sometimes in my code if avoiding it is going to be worse for readability.

The most common case of using the break statement is looping through an indexed array of elements searching for something:

int[] numbers = { 1, 2, 3, 4, 5 };
for (int index = 0; index < numbers.Length;
index++)
{
if (numbers[index] == 3)
{
break;
}
}

How to avoid here the break? As one of my bosses taught me, remember the tools at your disposal; A for loop contains three parts: initialization expression, condition expression and loop/increment expression. Nothing forbids us to add additional checks to the condition expression, as in the following improved code:

int[] numbers = { 1, 2, 3, 4, 5 };
bool found
= false;
for (int index = 0; index < numbers.Length && !found;
index++)
{
if (numbers[index] == 3)
{
found
= true;
}
}

We are short-circuiting the loop, but in a soft and more elegant way (and not commonly seen in the code!).


Think Generic

Sometimes, thinking in generic terms, instead of specific cases/problems, pays off later with greater benefits. I'm going to show you a small real world example.

When you develop a mobile website, you usually create at least two visual themes, and usually go up to three:

  1. WML layer: Limited, almost text only, and very crappy because of the limitations of the devices requesting this version of the site.
  2. XHTML layer, low/med-end capabilities: Devices that can render XHTML, some CSS, etcetera, but have small resolutions or some other problems (like no javascript, or a terrible CSS implementation, like PocketIE).
  3. "Full" browsers: mostly WebKit and Opera for mobile devices. Capable of standard javascript, really good resolutions (and zoom), can run almost perfectly any website, just with a lower resolution than a computer.

If your website is properly developed, all the "mobile versions" will have a common logic layer and data layer (or if it's an MVC, common Models and Controllers), so it's just a matter of detecting what version the visitor falls into and rendering the appropiate view(s).

For WML is quite easy with the HTTP Accepts header, but with the more capable devices, we usually rely on checking the HTTP User Agent header.

As an example, this is an iPhone with 3.0 OS user agent string:

Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A542a Safari/419.3

For an iPod Touch is almost the same, just changing the "iPhone" with an "iPod".

At first glance, a small regular expression to detect the words iPhone and iPod would solve the problem, no?

Well, it does, but not in a generic scope. Let's see now how an Android user agent looks:

Mozilla/5.0 (Linux; U; Android 1.5; en; HTC Magic) AppleWebKit/528+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20

Using the proposed approach we would have to add "Android" to the "nice devices" list, but until then we would be rendering on all Androids the less fancy XHTML version.

But the alternative, is to search inside the user agent for two words, "Mobile" + "Safari" (order matters!). If you look at both user agents, they both are WebKit implementations, so both are Mobile Safari browsers. Using this second approach we already support all present and future Android devices without changing our code. In fact, we will support any new browser based on Mobile Safari!

So the lesson here is to try to go for a generic approach. In this example, targeting for browser type instead of specific device id gives a lot more flexibility with the same effort and even lowers the need of modifying the code in the future.


Five basic concepts of scalability

Disclaimer: I've been only working for few months in high-scalability stuff so don't expect super-secret techniques or expert advices. It is just a newbie 5-point basic list based on what I've learned and read about this subject up to now ;)

  1. Don't touch the data layer. No matter what, try to avoid performing any SELECT query, any XML reading, except for the first time. ASP.NET page caching, XML caching or data caching (like for example PHP's memcached or Microsoft's Velocity). Avoid unnecesary querys: 15 queys on a page multiplied by millions equals insta-death against a DB-only data layer.
  2. Size matters. Every KB counts when daily pageviews go crazy. Compress Javascripts, CSS, output HTML, images, JSON data, DB table fields... everything you can. Remove all unnecessary data.
  3. Design for redundancy, balancing, partitioning, and implement failover architectures. Shit happens, no matter how good the system is. So better to be prepared to apply countermeasures or at least soft failures.
  4. Servers are no magical devices with unlimited resources. Skipping coding errors like memory leaks, big traffic sites need to be as optimum as possible with everything. If you use heavyweight objects here and there, think about refactoring them to smaller ones (or detach the most important and frecuently used data from the "extra" data, as when normalizing DB schemas).
  5. Design for scalability. Database partitioning, distributed web services, load balancers, archieving... We all hate twitter's fail whale, but having millions of twitts per day requires a lot of stuff underneath (and that's just an example, there are many more out there).

And as an extra, talking about web, prepare to enter the hell of browser incompatibilities, limitations and hacks. Desktop development is a piece of cake compared to any medium-complex web project.

Update: Here's an interesting round-up article about an example of .NET scaling.


Why not using a Wiki for project management?

Almost everybody understands the burden that represents managing a project (or even a company) with multiple tools: bug tracking, version control (not full source code, just labeled/released binaries), documentation, task tracking...

There are an almost infinite spectrum of tools to aid on some of those tasks, but the problem usually is moxing (or directly integrating) them. Microsoft's Visual Studio Team System tries to integrate the most common ones (even more coding-oriented stuff, like source control and automated testing), but installing a Team Foundation Server is not an option for everyone (for example, me).

One of the things I love most of all this internet era is the concept of hyperlink: you are reading in one place, and with just a click, you can navigate to another place. No more going to the index of a document and clicking on the desired chapter/subchapter, you just click and you're there.

Hyperlinks are not only the basic pilar of internet, they are useful even "offline". If you usually read PDF books, how often have you cursed the PDF creator for not placing "bookmarks" on them? And even with them, wouldn't it be easier if you are on chapter 11 and the book mentions Web Services' session state and you want to quickly check what it meant?

As a real world example, last year I wrote a 30 pages word document with UML use cases. Apart from the all-known index listing all of them, I placed hyperlinks inside the use cases that depended on or used other use cases. That way, looking at a specific use case took a whole less time (and since hyperlinks don't work on printed paper, we saved trees too :P).

Hyperlinking in a word document is fast and easy to do. But why restricting yourself to just that? Why not having everything hyperlinked and available from one place without having to buy an expensive server and licenses?

A few weeks ago I installed a wiki * on my home server. The needs I wanted to acomplish with it where:

  • Avoid depending on an online service for storing my TODO lists (Google Docs.)
  • Having a centralized and simple bug tracking solution for my websites and personal projects
  • Starting to maintain change logs (useful for example for my CS 2007 Addon Pack)
  • Storing post ideas and small drafts ("the best ideas come in the less suitable moments and places")
  • Maintaining a small knowledge base both of .NET tricks and practices (for example, how and where to setup a new demo for the Demos section of Kartones.Net, which needs modifying three files apart from the upload itself)
  • Storing small code samples of things to use in proof of concepts/demos/projects (I have a /Prog/ folder with subfolders, but some of them have too much files and zips, and I want instant access to what I'm looking for).
  • Keeping all of this private (at least my chosen wiki engine allows to restrict access to just registered users and disabling user registration ;)

Few weeks later, I can't be more pleased to have taken this approach.

My personal and internal wiki

I now have a basic fully-working wiki structure, being able to access my stuff by project name, by category ("TODOs", "KB", ...) or by searching. I can attach a zip containing a code snippet to a post idea and later retrieve it in a second. If I think of an improvement for Kartones.Net I can annotate it in seconds. Any KB article can link to another, to internet resources, or contain a batch file to execute.

And as an added bonus, I am modifying the wiki's engine to disable all non-desired functionality so it just does what I want the fastest way it is able to.

My Google Docs. "workspace" is now empty of dozens of individual documents that were harder to link between, and as the wiki detects things like orphan pages, if I forget to setup the categories for a new page, I'm warned about it, so all is added in harmony.

This might not be the ultimate solution. For example, my source code repository can't be integrated on a wiki. A company timesheet managing application or a professional bug tracking application can't neither **. But I have spent 0 money and less than one hour to have it running and ready to configure and add contents.

* I have installed Screwturn Wiki 3.0 beta. It's made in .NET (so I can customize and extend it) and doesn't uses a DB so its fast to deploy and use, but any wiki engine will suit your needs.
If you decide to use the same engine, be aware that the binaries for the beta are compiled in debug mode. I recommend downloading the sources and rebuilding in release mode for a small speed boost.

** If it is web-based, the wiki could be extended to support some kind of iframes, but it would be more a trick than a real integration.