Wednesday, September 28, 2011

The Perils of Soft Delete

Often times, applications cannot get rid of the database records for business rules. For example, if you are a cable TV provider, you might have a customer calling you to stop the National Geographic Channel subscription from next month. Ideally you would like to delete this record, but you can't do it until the effective date:( If you delete it, the next invoice will not be able to charge for this channel, although it's still being used.

In such scenarios, its common to fall back to a soft delete model. As an example, here's a little code:

This code looks simple and harmless at a first sight. But, as you develop your app, you'll run into a lot of issues from this. Here's a short list:
  1. You need to take care of cascading soft delete, for example, cancelling a customer's subscription needs to cascade down to all channels and other objects under it.
  2. Whenever, you are listing the current subscriptions of a customer, you need to filter out the ended ones.
  3. You need to figure out a strategy to periodically clean the ended subscriptions so that your database is not filled with outdated data.
  4. If you have a business key used as a primary key as well, you will be in trouble if an ended subscription is restarted.
  5. Your code will eventually have a lot of if-else blocks to apply changes to only on active objects.
So, what is the solution? Its best to avoid them as much as possible. Richard Dingwall has a detailed blog post on some alternative techniques to avoid soft-delete. But if you have to have soft delete, as shown in the example, its worth remembering the aforementioned points.

Friday, September 23, 2011

Hardcoded URLs in Javascript are too Slippery

Photo credits to Esteban Cavrico

I was working on a web project that lets you delete some records using Ajax. The following is just an example, but you might be familiar with a similar code already:

This code used to work when the DELETE endpoint was indeed under '/blog/posts'. However, at some point a developer wants to remove the '/blog' from all the endpoints to put them directly under '/posts'! You can see, in such cases it is very hard to catch the bug that would be caused by the faulty JS code.

Here's a quick recommendation:
Don't hardcode the URLs (or anything that is actually a server configuration) inside your JS. 
This is a code smell, as its duplicating code. But its also dangerous, because its hard to catch/fix these defects since they can be buried deep under an untested Javascript file. Instead feed this data from your server side code and you'll mitigate risk that way.

Tuesday, September 20, 2011

Excess of Private Methods is a Code Smell

Private methods, when used meaningfully, are a great tool for writing beautiful object oriented code. But as many other things in life, excess of private methods is bad, too!

In my opinion, we use private methods to:

1.  isolate a block of code to be reused inside the class.
2.  extract code from another method for code readability.

Now, taking these two use cases in mind, here's an easy conclusion:
The lower the ratio of public to private methods, the harder it is to write unit tests since the "units" are potentially larger.
I don't know if there is any rule of thumb, but you will smell it when you see your unit tests require a lot of setup and assertions. Here's a code example from the Play! framework, an MVC franework for Java developers.

You will see there are public methods with 100+ lines. I hope you agree with me:
"The code is not readable"
For the sake of readability, introducing private methods with good names would help. However, that doesn't eliminate any of the possible code paths from the public methods. So, if you are lucky, you will see really long unit tests with complex setup conditions and mock expectations. Otherwise, there will be no tests at all! Without any tests for such long and complex methods, use them at your own risk. I won't :(

Disclaimer: I like the play! framework a lot. However, if you take a look at their code and if you think unit testing is important, you'll see they have a lot of rooms for improvement with simple extract method refactoring.

Friday, September 16, 2011

Quiz: C# Async and Await. What is the Output of this Code?

C# 5.0 (CTP version at this point) has support for async and await to allow clean implementation of non-blocking IO using a task-continuation model. I was just playing with it and here's the sample code to tease your brain. Tell me what is the output of this program?

How to Extend a Ruby Module?

Modules in Ruby are like classes with a few important differences. One of the differences is, a module cannot inherit from another module using the same syntax as class inheritance. However, its pretty easy to inherit a module's method into another module, by just using the include ModuleToInclude syntax. Here's an example if you are looking for one: