Friday, July 5, 2013

Clean Code Question: Properties vs. Methods

Earlier this week, I spoke about Clean Code (Clean Code: Homicidal Maniacs Read Code, Too!) and a couple of questions came up that are good to explore a little further.  We'll talk about properties here.  In the next article, we'll think a little more about exception handling.

Properties vs. Methods
The first question had to do with the refactoring of a conditional.  Here's the original code:

It's easy to see what this block is doing (checking to see if something is more than 10 seconds old), but it doesn't really tell us why.  In following our principle of intentional naming, we want to make the code a bit more clear.  So, we created a property called IsCacheValid wrap the details:

Now, we can tell that this conditional is checking to see if the cache is valid.  If we need details on how that decision is made, we can drill into the property.

So, the question came up:
Why use a property here instead of a method?
A very good question.  My answer was that it didn't really matter either way and that I chose a property to show other ways of wrapping details other than just methods.

That's mostly true from a "wanting to show stuff" standpoint of this particular session, but there's a little more consideration to give this.

Let's see what this same code looks like as a method:

There's not that much difference.  Just a few syntactic changes: (1) adding parentheses and (2) removing the "get" block.

Is There a Performance Difference?
Our first concern is to see if there is a performance difference.  We know that Properties are really just methods in disguise (Explained: Properties in .NET or video).  And if we were to explore the IL, we would see some (but not many) differences between the two.

Realistically, even though there are technically some differences that may affect performance, this code will not see any noticeable difference.  Remember where this code is: it's in a view model.  This is part of the code our users interact directly with.  In this scenario, the slowest part of this application is the user.  So, we don't need to worry about differences between 10 or 12 clock cycles affecting real-world performance.

Now, if this were in a tight loop or the functionality was called repeatedly (hundreds or thousands of times per second), then we would really need to dig in and see what the performance is.  But in this case, the difference is undetectable.

Is There a Readability Difference?
So, now that we've decided we don't need to be concerned about performance differences, we need to focus on the readability of the code and what developers expect to find.

Since the conditionals end up being almost identical, it's hard to argue that one is easier to read than the other.



So, we'll decide that the physical readability is the same either way.

What do Developers Expect?
The last thing to consider is what would a developer expect to see.  Remember, our goal here is to have code with no surprises.  We want to make it as obvious as possible.  The code should be easily readable by a developer who is not entirely familiar with the details of the application.

So, the only argument that I would have to prefer a Property over a Method has to do with the naming. As discussed in the session, we prefer to have nouns for "things" in our code (classes, properties, parameters, variables).  And we like to have action verbs for our methods and functions.

There is one more state that we talked about: it is common (especially in the XAML world) to have properties that are state verbs.  Some examples would be "IsReadOnly" and "IsEnabled" that we have on a number of UI controls.  These aren't action verbs, they are simply a way to query the current state of an object.

We followed this same naming convention with the "IsCacheValid" property name.  So, in this instance (with this particular name), I would prefer for this to be a property rather than a method.  But we could just as easily change the method name to something more appropriate.

Wrap Up
We've seen that when we're working in the user code space, it doesn't really matter whether we use a property or a method to wrap up coding details.

We do need to be aware of a few standard guidelines regarding properties, such as, we don't want to put "slow" code into properties.  Developers expect properties to return quickly (and definitely not asynchronously).  So, we should not put things like database calls or network calls into properties.  And we should not put processor intensive code into properties -- in cases where we "get" a property many, many times, this can add up.

As always, we need to be aware of our environment.  We need to keep our code unsurprising to other developers.  And we need to make sure that we weigh the pros and cons for the decisions that we make.

The more we understand, the better able we are to make those decisions.

Happy Coding!

No comments:

Post a Comment