The Burden of Features in Software

I’ve been removing a couple of dead features this week. You know, those features that senior people in organisations like to tell epic war stories about. Those mighty conversations at dinner parties, where a person involved talks about all the pain and sorrow, about how a particular capability ended up in the software, how (crappy) it got implemented, etc … . Everyone at the table is laughing. Some of them who were also there, adding more personal anecdotes to make the story more tragic.

But the good news is that these features are no longer relevant to the end-users. In some cases, these features don’t even work correctly anymore. But they are still there to haunt you as a software developer. They wander throughout the application as ghosts. Usually they are totally at odds with the current architecture and/or design. Whenever I come across something like that in the code, I turn it into a personal crusade to get the code out as soon as possible. Removing dead weight is equally important in our profession as adding new code. But how on earth did this feature get into the code base in the first place?

In a previous post I wrote about product and project focused software. In all cases, adding features to software adds a burden. There’s not only the cost of implementing and deploying it, but there’s also the (hidden) cost of maintaining it and further evolving it as the capabilities of the software grow or when the architecture evolves through time. Then there’s also the added complexity for the end-users, need for documentation, etc. …

In my experience, there tends to be more awereness in organisations where there is some form of a product focused mindset compared to “project” organizations. In “project” organizations, a particular feature might be necessary in order to succeed with a project or two. Afterwards, there might no longer be a need for this particular capability, but a (new) need for something else might arise. They pile up feature after feature after feature until they end up with a Big Ball of Mud. In these kind of organizations there is no threshold for adding new features.

I consider being cautious before adding new features a good thing. Adding capabilities over time that are harvested from actual needs tend to be more useful anyway compared to “we need this thing, and we need it by yesterweek”. As described in my previous post, things are usually no that absolute. Most organizations sit somewhere between completely “product” focused and completely “project” focused. But the really excellent ones refuse to add new capabilities to their software until not adding it becomes almost unresponsible.

The thing is that we should create awereness that crafting software is quite a fragile proces, both with ourselves as with our stakeholders.

Monitoring an MMO

I’ve been working on a free-to-play MMO which has been “officially” live since last April, and things have been going well – a steady growth of players; the game itself has been well-received, and all the important graphs are “up and to the right.”  Part of my job involves detecting problems before they become serious and fixing problems when they inevitably do.  So, there are two questions.  “Is there a problem in the game?” “What is causing the problem?” 

When trying to debug something on our development and test clusters, typically you can tail log files.  We have a python script that can monitor the communication between various parts of the game and pretty-print it along with color to highlight “this is a problem!”  Attaching a debugger to a running process is also not uncommon.  However, looking at logs and bus traffic in realtime on a production environment gives you this neat “Matrix-y” experience.  Attaching a debugger to a production process (assuming you could, which you can’t) would get you smacked with a rolled-up newspaper.  “Bad Developer!  No treat!”  So, what can you do?

Monitoring

When you’ve got clusters full of machines, using Nagios to monitor things is an obvious solution.  Beyond making sure the power is on and other sysadmin things, we’ve written other checks to see if the login process is working, the parts are working together, and automating typical in-game functions.  For example, if nagios can’t successfully log into the game do basic game activity, then alerts happen.

Metrics for EVERYTHING

Anything that happens in game has metrics reporting tied to it, generating piles of data constantly.  We use Cacti to visualize game activity.  An example metric is concurrent users, or CCU.  We graph how many people are in the game over time, which when things are healthy should be a nice smooth curve climbing to peak game hours, then descending nicely through the night.

We can tell by sight if the game looks healthy or not – if the CCU graph is jaggy, has a sudden drop or spike, or drops to zero then we know that something is wrong.  Typically nagios alerts accompany the graphs, giving more data points on where to look.  But this has also pointed out areas where a nagios check was missing or wasn’t working as intended.

Log Files

When a player gets an error in game, the error dialog box gives them the opportunity to submit the error details back to us.  If we see a spike in user-reported errors through this or other customer service means, we know we have something of interest to look for. 

The game server components make use of log4j and similar logging frameworks.  Anything that you’d want to watch happening in game needs to be aggressively logged.  All components are configured so that operations can change the log level on the fly.  That’s still quite a bit of data across many machines though, so all that information is run through Splunk to be indexed and searchable.  This gives us a great tool for searching through log data, examining trends, or watching selected activity in real time.  Unfortunately it is very expensive so we are selective about the data that passes through it. 

Why Software Development Will Never be Engineering

I always find it rather interesting when academics try to quantify generalized metrics about software development.

Things like: per lines of code, there will be X number of bugs.

Statements like: it has been empirically proven that “blah” affects the development of software in some way “blah.”

These are all interesting thoughts, but software development will never conform to rigid engineering principles like many other engineering practices.  The longer I work in the field, the more and more I realize that software development has nothing to do with engineering.  We just happen to attend some of the same math classes in school.

Building bridges

One of the main arguments I hear people make about the current state of software development as an engineering practice is based around its relative maturity to other engineering fields.

There is a huge problem with this line of thinking.

The argument goes something like this:  “Engineering has been around for hundreds of years and has matured to the point where it is a measurable science, but software development has only been around in earnest for the last few decades or so, therefore it is relatively immature as an engineering discipline.”

On the surface this argument seems sounds.  And certainly in 50 years software development will be different than it is now.  Heck, it is much more different than it was just 10 years ago.

But, here is the problem.  We build much more software than we do bridges.

 

Let me give you an example that came to light in another area of my interest… poker.

The poker quickening

An interesting thing happened in the poker community in the last 10 years; poker pros with decades of experience started getting beat time and time again by 19 year old poker prodigies.

From an outside perspective it looks like the poker world opening up just widened the search for talent and there it was.  But, a closer examination of the evidence leads to the truth.

Before the online poker industry was born, poker was played in card rooms and casinos in states where it was legal and occasionally at small home games throughout the US.

A poker pro might play poker tournaments perhaps 100 times to 150 times a year.  The sum knowledge of the poker community and the meta game around it was based on this base of professional poker players playing tournaments and gaining experience at this mediocre rate.

Once the internet poker rooms started opening up, things changed, and they changed rapidly.  Now anyone could play poker from their home PC.  Not only could they play poker, they could play poker tournaments at all hours of the day.

Here is a list of some of the major changes that took place:

  • Hands are dealt at 60-80 hands per hour instead of 10-30
  • Players can play in many tournaments at one time, 10 tournaments at once is not unheard of
  • Players can analyze hand histories and historical data about their play and opponents play through the use of software
  • Age requirements are out the window, technically any one of any age could be playing online
  • Players can play 24 hours a day
  • The professional online tournament player could easily play over 3000 tournaments in a year, while a brick and mortar pro would be lucky to reach 100 in a year.

 

So where am I going with all this?

The point is that as a whole more hands were dealt and more poker knowledge and experience was obtained in 1 year of online poker than probably the entire history of poker before that.  We reached such an accelerated pace of play that all previous knowledge of poker became obsolete. 

The strategy of tournament poker completely changed.  The game evolved perhaps 500 years into the future in a matter of 5 years time.

The same has happened with software development.

Back to the bridge building

So let’s take that poker example and look at it through the lens of software development.

Let us compare the engineering maturity to software development to the engineering maturity of the engineering discipline of building bridges.

I think most people would agree that bridge building is a very mature engineering discipline but many people would argue that software development is not.

How many bridges do you think have been built in the world?

Well there are about 600,000 bridges in the United States alone, so the world figure must be at least somewhere around 10 times that number perhaps 20.

How many software programs have been written?

This is a very hard number to estimate, but lets take a rough guess based on how many software developers there are in the world

If we say there are about 12 million software developers and each software developer has written approximately 3 programs, we can estimate that a large amount more programs have been written than bridges built.

My point is not to knock bridge building, we are pretty good at it as a whole, but rather to show that collectively, even though we have been building bridges for hundreds of years, we have probably devoted an equivalent amount of time to building software.

This line of thinking may lead you to argue back that software development and bridge building are very different.  Bridge building has a fixed set of requirements that are pretty close to the the same for each bridge you build, but software development is a big open void of whims and ambiguously contradictory statements.

I agree with you 100%!  And in essence that is my point.

Software development is different

And we have had enough time to realize that.  Waiting for software development to gel into some kind of engineering discipline like other engineering disciplines is like waiting for water without gelatin mix to turn into Jello. 

It’s just not going to happen!

In my mind it is clear that the argument that we haven’t given it enough time is just wishful thinking.  The nature of software development, just like online poker, leads itself to rapid evolution.

Consider what direction software development is evolving.  Is it even evolving in the direction of rigid engineering practices or is it evolving in the exact OPPOSITE direction?

Ten years ago, we tried to use UML diagrams and CASE tools to develop software.  Ten years ago waterfall was all the rage.  Ten years ago, we thought that ten years in the future we would have programs that would allow us to build software in the same way that CAD tools allow for building machine parts.

Not only did it not happen.  It went completely the other way.  Now we are all talking about Agile.  Now people don’t even remember what CASE tools are.  Now we are building software without trying to define the whole system in UML diagrams.

The fact of the matter is software systems are unruly beasts!

In my mind it comes down to one simple distinction.  Software is living, bridges aren’t.  When you are done building a bridge, you are done building the bridge. 

Sure someone, probably not you, will have to come along and do some routine maintenance on it.  Sure, some small things might change about it, but for all intents and purposes the work is done.

In most software development scenarios, this is not the case.  In most software development scenarios, releasing V1 is not even close to the end.  Sometimes V1 and V2 don’t even look that same at all.  Software development is about operating on a living breathing thing and all the while keeping it alive.

The truth is, we software developers have more in common with surgeons than with other engineers.

As always, you can subscribe to this RSS feed to follow my posts on elegant code.  Feel free to check out my main personal blog at http://simpleprogrammer.com, which has a wider range of posts, updated 2-3 times a week.  Also, you can follow me on twitter here.

Christmas Light Architectures Are Not That Shiny

I just want to get something of my chest that is bothering me for quite some time now. It’s not going to be a rant of some sort, but merely a couple of observations for which I couldn’t find the right words to describe things up until this point. In short: this post is way overdue :-).

image

What’s the major malfunction with those old, classic Christmas lights? We’ve all experienced it at some point. When one goes out, all the others go out as well. This is due to the fact that these lights are wired in series. The difference compared with today’s Christmas lights is that every bulb has a shunt, which basically prevents this kind of failure caused by one or more lamps. Enough about the Christmas lights for now. Where am I going with this? Back in enterprise IT, I’m seeing the same kind of failures as with those classic, old Christmas lights.

The diagram below shows a classic RPC style architecture, much like those classic, old Christmas lights.

image

This is all fine and dandy as long as every part of the chain runs without too much hassle. But what happens if for some reason the centralized back-end web service goes down (light bulb goes out). This means that every smart client, website and batch application that uses this web service gets affected by this, like some sort of chain reaction. Parts of these client applications will no longer function correctly or they might even go down entirely. Same thing happens when the database of the centralized back-end web service goes down or any other external system that it depends on. When being confronted with this kind of architecture, how would one go about preventing this doomsday scenario to happen?

Suppose you’re a developer that has to work on the centralized back-end web service. This is usually a complex system as it obviously has to provide features for all kinds of applications. When this centralized back-end web service also has to deal with and depend on other external systems that might expose some unexpected behavior, how could one prevent the sky from falling down when things go awry in production?

Well for starters, you could start building in some stabilization points. Suppose for some reason, the centralized web service needs to incorporate some functionality offered by a highly expensive, super enterprise system that for some reason behaves very unstable and unpredictably on every full moon (expensive enterprise software not behaving correctly sounds ridiculous, but bare with me 😉 ). For example, we could use a message queue as a stabilization point.

image

This means that we put a message on a queue that is processed by some sort of worker process or service that does the actual communication with the misbehaving system. When the external system goes down, the message is either left on the message queue or put on an error queue for later processing when the external system comes back up again. There are some other things you need to think about like idempotent messaging, consistency, message persistence when the server goes down, etc. … . But if one of these dependencies goes down, the centralized back-end web service is still up-and-running which means that the systems that depend on its functionality can also continue to serve their users as they are able to keep doing their work.

Earlier this week I overheard this conversation that somewhat amazed me. I changed the names of the persons involved as well as the exact words used in order to protect the guilty.

George: We want to incorporate a message queue in order to guarantee stability and  integrity between several non-transactional systems that our system depends on. It will also improve performance as these systems behave very slow at times and become unstable under pressure. This also gives us the opportunity to root out some major points friction that our end-users are experiencing right now.

Stan: But this means that the end-users are not completely sure if their actions are indeed fully carried out by the system.

George: End-users can always check the current state of affairs in their applications. If something goes wrong, their request is not lost and things will get fixed automatically later on as soon as the cause of the error has been fixed.

Stan:  I don’t think that’s a very good idea. End-users have to wait until everything is processed synchronously, even if that means that they’ll need to wait for a long time. And if one of the external systems goes down, they should stop sending in new requests. Everything should come to a halt. They just have to stop doing what they are doing.

George: This means that because you lose the original request, some external systems might be set up correctly while others are not. Then someone has to manually fix these issues.

Stan: Then so be it! 

For starters, I was shocked by this conversation. This is just insane. Everything should come to a halt? Think about this scenario for a while: suppose you’re finding yourself in a grocery store with a cart full of food, drinks and other stuff. You come at the cash register where the lady kindly says “Can you put everything back on the shelves please? There are some issues with the cash register software and we are instructed to stop scanning items and serve customers until these issues are fixed. Can you come back tomorrow please?”. Uhm, no! How much money do you think this is going to cost compared to the system that makes use of stabilization points? An end-user that is able to keep doing its work, whether the entire production system is down or not has tremendous business value.

I’m not saying that message queues are a silver bullet. I’m just using these as an example. As always, there is a time and place for using them. There are other things a developer can incorporate in order to increase the stability of the system he’s working on, like the circuit breaker pattern. I’m also not saying that every system should be built using every stabilization point one can think of. This become a business decision depending on the kind of solution. As usual, it depends.

But the point that I’m trying to make here is that we should stop putting software systems into production and just hoping for the best. That’s just wishful thinking. Software systems are going to behave badly and at some point they will go down. It’s just a matter of when this is going to happen and how much damage this is going to make.

The first step to take is awareness. I encourage you to pick up this book titled ‘Release It!’, written by Michael Nygard. This book is all about designing software that can survive this though environment called production. I can only hope that Stan picks up a copy as well along with some common sense.

Till next time.   

Could sealing a class be a sign of a good design

I recently attended this years Øredev conference and one of the things I had the good fortune of doing was to meet-up with a long time twitter friend, Philip Laureano. One of the days me and Philip started talking about a previous discussion he had with another attendee (whom shall remain nameless since I do not know the full details of his exact opinions). Anyway, the short version is that the person suggested that classes should be sealed by default, or at least have the developer explicitly state if the class should be sealed or closed.

My immediate reaction was that this was a terrible idea and that I had been struck down too many times by sealed classes before. But then I started thinking that maybe it was not such a bad idea after all. Maybe it even was a sign of a well designed class and that more developers would be better of by sealing their classes.

Now let me inform you that I am still on the ropes about this, but I would like your thoughts on it. In fact I am hoping that the most interesting part of this post will end up being the discussion in the comment section.

So when you take a moment to think about the S.O.L.I.D principles, most specifically the Open-Closed Principle and Dependency Inversion Principle, a long with the old design principle of ‘Favor object composition over class inheritance’ then maybe it is not such a bad thing after all. Throw in interfaces into the mix and program to an interface and not an implementation, and it will enables you to create different branches if needed. If your classes can flourish while being sealed, chances are that you have some pretty nice structures code in your hands.

There probably are some legit reasons to not seal classes at time, despite the reasoning above, so I am not going to be definitive and say that is never the case. Voice your thoughts in the comments and let us see where this ends up – who knows, I might be left standing as a fool!

As always, you can find me on twitter by the name of @thecodejunkie

Enforce Correct Usage By Wrapping Types

Have you ever written an API or a method and expected it to be used a certain way, but then found people doing all kinds of bad things with your precious API that you never intended?

I was working on building an automated testing framework for a welfare system in which cases could be added and benefits run for a given month.

A typical scenario might be something like:

  1. Create a new case for this month.
  2. Add some people, do some things.
  3. Run benefits for this month.
  4. Run benefits for the next month.  Something should happen because the child on the case is now 19.

Seems pretty straightforward until you consider what happens if someone hard codes dates into the test.

I am sure you can imagine plenty of scenarios in a situation like this where hard coded dates would eventually cause all kinds of problems.

The problem is…

If you create an API which takes in various dates, how do you ensure the dates passed in are calculated and not just hard coded?

pigsinblanket

Why convention doesn’t work

Your first response might be to create some documentation that describes the importance of making dates “float” forward with time, and not be hard coded.

You might clearly describe how you should not hard code July 7th 1990 to be the birth date of a 20 year old for a test case.

You might give some guidelines of how to properly calculate ages.

But, you have no way of making sure the users of your API will follow those conventions or even read your document.

What if we do the hard work for them?

Why utilities are still not good enough

The next idea you might have is to create utilities that would do date conversions and calculate ages for the user of your API, so that they just have to remember to use them and all will be good.

This solution is better than one relying purely on convention, but still has some major flaws.  Part of the problem of utility methods is that they are not self-discoverable.  I’ve talked about before how DateUtilities like classes can get overlooked if you don’t know the utility class is there.

If you are relying on your users to go out and find your utility methods to make life easier for them, you are putting a large amount of responsibility in the wrong place.  In my experience, it is very unlikely that anyone but yourself will actually use the utility methods.

You really need a way to stop them from being able to hard code dates.

How can you stop someone from hard coding dates?

Don’t accept dates in your API.

It is simple.

What?  What do you mean?  You can’t just stop accepting dates, you need dates.  Not just dates, but integers, or strings.  You can’t just not accept the bad data… or can you?

Consider wrapping the data type in another data type which creates your desired data type, but only using the convention or rules you desire.

Let me show you an example with the dates:

   1: public void CreateCase(DateTime applicationDate)

   2: {

   3:    DoSomethingWithTheDate(applicationDate);

   4: }

   5:  

   6: CreateCase(new DateTime(1990, 7, 8));

In the above example, you can see that I am directly taking a .NET DateTime object.  You can also see that I am directly hard coding a date when calling this method.

Let’s see if we can fix that.

   1: public void CreateCase(CaseDate applicationDate)

   2: {

   3:     DoSomethingWithTheDate(CaseDate.ToDateTime());

   4: }

   5:  

   6: CreateCase(CaseDate.YearsAgo(20));

What happened?

Here is what we did:

  1. We created a custom type called CaseDate.
  2. We replaced all the external usages of DateTime with CaseDate.
  3. We provided methods on CaseDate which allow the creation of dates, only through the way we want to allow them to be created.
    Now we can easily prevent users of the API from being able to create hard coded dates.  The API only will take CaseDate objects and internally creates DateTime objects from the CaseDate objects.
    We can add other methods to CaseDate to allow the creation of dates from x number of months ago or in the future, or any other valid creation method we want.

By doing this, we are restricting the valid set of inputs to our methods at compile time, not throwing exceptions at run time.

We are achieving the same kind of valuable input constrictions that we have been able to achieve with enumerations, except we are adding more complex restrictions than a simple list of selections.

Where can I use this?

Not just dates.  There are many places where restricting the input to your method or API is going to simplify logic, protect against error conditions, and enforce constraints.

Consider using this pattern in some of these scenarios:

  • You want to use an enumeration, but your list of possible choices is too large, or repetitive.
  • Anywhere you are using a primitive type and that primitive type represents some more complex concept.
  • Anywhere you have parameter validation or manipulation repeated in multiple methods.
  • Anytime you process some input or repeat a series of steps to transform it before sending it as input.

Every time you are about to make a primitive type a parameter to a method you should ask yourself if it makes sense to wrap the primitive type into an class.

Remember, especially when creating an API, any time your method takes a primitive type, you lose the ability to constrain that input, and are forced to validate it instead.

Should you always wrap all primitive types?  No, but it is another tool you can use to provide an extra layer of indirection between the logic of your API and your callers use of it.

As always, you can subscribe to this RSS feed to follow my posts on elegant code.  Feel free to check out my main personal blog at http://simpleprogrammer.com, which has a wider range of posts, updated 2-3 times a week.  Also, you can follow me on twitter here.

Prefer Additional Methods Over Additional Overloads

If you have ever written code that is going to be used as an API for other programmers, you may start to think about writing code in a different viewpoint from what you normally do.

Most of us write code for the purpose of achieving a goal.  If we practice writing elegant code, we are conscious of making that code as readable and terse as possible.

Seldom do we think about the use of our code from an API standpoint.

There is a subtle difference between designing your code in a way that will make it easier for someone else to maintain, and designing your code in a way that will make it easier for someone else to use.

Intellisenselessness

How often are you working against some API and you type a method name you want to use only to have intellisense present you with 5 overloads for the method all with several different parameters choices?

LoginOverloads

Which one do you use?  It is hard to be sure, you end up having to read through the long lists of parameters to figure out what method you should call and what parameters you should pass it.

Wouldn’t it be better if you were presented with what the method does in the method name rather than guessing what it does in the parameter list?  Something like this?

LoginMoreMethods

Perspective

From the perspective of the person writing the Login method(s), overloads probably seem like the most efficient and correct way to implement the multiple ways the method can be called.

From the perspective of the person using the Login method(s), additional methods are much preferred, because they are easier to understand and know what you are looking for.

Try to think from the perspective of someone using your code when writing your code.

Extract boolean parameter to two methods

I want to take a look at a very specific example that can be of great benefit to the readability and use of your code.

Take a look at this code below.

   1: public void Login()

   2: {

   3: }

   4:  

   5: public void Login(bool rememberMe)

   6: {

   7: }

Seems like a fine overload of a Login method.  I have written code just like this, you probably have also. 

 

Unfortunately, by adding this overload, we have added some complexity to our API, because now the user of that code has to see that there is an additional overload that take a bool parameter called rememberMe.

Consider this longer alternative.

   1: public void LoginRememberMe()

   2: {

   3: }

   4:  

   5: public void LoginDoNotRememberMe()

   6: {

   7: }

Instead of overloading Login and making the user have to decide which overload to call and pass in a parameter, we have elected to create two differently named methods which take 0 parameters and clearly state what they are going to do.

I’m not saying you should never write overloads, but anytime you see an overload in your code base, you should stop and think if it would be more clear to make that overloaded method into two different methods that can eliminate one or more of the parameters.

Any time you are restricting the number of choices someone using your code has to make, you are making that code simpler to use.

If you don’t believe me, consider why the iPhone has only one button.

As always, you can subscribe to this RSS feed to follow my posts on elegant code.  Feel free to check out my main personal blog at http://simpleprogrammer.com, which has a wider range of posts, updated 2-3 times a week.  Also, you can follow me on twitter here.

Say “No” to “Null”

I was recently asked to write a fairly simple piece of code.  In this simple piece of code, I didn’t handle a null input.  I was asked about what kinds of things I would consider about the input, and I pretty much knew what the asker was going after.

What do you do if “null” is passed in?

My answer may turn out to be a bit of a surprise.

Nothing, I don’t handle nulls in code that I control the use of.

“What?  What?” you say.  “You don’t handle null?  What kind of heresy is that?”  It is the kind of heresy that helps produce elegant code and I will show you why.

How well do you handle null right now?

Would you say that in most of the code you write you properly check all arguments for null?

Or, do you like most developers, handle null in certain cases when you happen to think about it, or after the application dumps a “null pointer exception” stack trace?

Be honest, look at your code if you have to.

The problem is “d00d ur d0ing it r0ng!”

john-mccarthy-programming-completely-wrong

Unless you are some kind of anal retentive perfectionist, you are probably not handling null in every single method call.  That means there are huge potential bugs in the code that you are writing which will throw null pointer exceptions.  That is bad, I agree.

So, if you are not handling it correctly right now, then what can you do to fix that?

Avoiding null in the code you “own”

You can’t control external libraries.  And you can’t control how people will use your code, but you can control the code you write and you can, to a degree, control the code your shop writes.

The better strategy is to never pass null in the first place.

You can either focus your efforts on:

  • Checking for null
  • Not ever passing null
    The more elegant solution is to focus on never passing null.  By doing this you will end up writing less code and avoid decisions about how to handle null inside of a method that doesn’t have enough context to decide what to do.

Let’s look at an example:

public string TransmographyThreeStrings(string first, string second, string third)
{
     if(string.isNull(first) || string.isNull(second) || string.isNull(third))
    {
           // hmm, I donno, what should I do?  Should I throw an exception?
           // should I return an empty string?
           // what if the first string wasn't null, can we still do something meaningful?
           // how will the caller of the method know what I will do?
    }

}

You can see there that we are checking each parameter for null.  The problem is we don’t know what we should do.  We have lots of options, but none of them are obvious.

How much better is it to make sure that we never pass null into methods, rather than write this kind of code in every method?

What about accidentally passing in null?

Many of you are probably thinking at this point that the main way null gets passed into a method is because someone calls a method without knowing that it contains a null value.

TransmographyThreeStrings("Hello", "World", mysteryObject.Text);

Perhaps mysteryObject.Text is null.  You wouldn’t even know it.

Ah, but you can.  Or you can prevent it at least.  Somewhere mysteryObject gets created.  When it gets created its values either get initialized or not.  You can prevent any of its values from being null, several ways:

  • Always initialize variables when they are declared.
  • Use a builder pattern to ensure that objects are always fully constructed before being created.
  • Use properties to provide default values or lazy initialize.
  • Make your objects immutable as much as possible.

The practices that prevent null from accidentally being passed in make your code much more elegant than repeating if blah == null code all over the place.

In general, you should always strive to eliminate the passing of null rather than checking for null.  By doing so you reduce extra lines of code in each method, and are forced to use better design practices.

Exceptions

Yes, there are times when you need to check for null.  If you are writing a library that external developers will use, then you will probably want to check for null in all of your methods that are exposed as part of the API.  (On your internal methods, you don’t need to since you have already cleansed the input.)

Also, if your code is being used as a callback to some API and you don’t know if it can ever pass null into your code, you probably should check for null.

A bad excuse is that other developers may pass null to your method. It is much better as a software shop to put the onus of not passing null on the caller of any method rather than putting it on the writer of the method being called.

You will also reduce your exception handling code, because you will have less exceptions for invalid parameters.

As always, you can subscribe to this RSS feed to follow my posts on elegant code.  Feel free to check out my main personal blog at http://simpleprogrammer.com, which has a wider range of posts, updated 2-3 times a week.  Also, you can follow me on twitter here.