Archive for the ‘Development’ Category

JavaScript Method Names

Wednesday, December 30th, 2009

I’ve been working on a new website for my company recently, and ran across an annoying issue with a JavaScript method name I was using to handle a mouse over event.  I usually define my methods with generic names and then rename them to fit their specific purpose once I have a better understanding of how I will use them in my code.

In this particular case, I named the method “MouseOver”.  However, when I ran the page, nothing happened – the method was never called, and no error was given.  This was pretty annoying, but a quick check by a second pair of eyes spotted that MouseOver was apparently a reserved keyword. 

There are a number of websites that list reserved words for JavaScript.  None of them list MouseOver (not to be confused with OnMouseOver, which is an existing method name that should be avoided), so this is my small addition to these lists – avoid MouseOver as a function name, as the behavior will apparently be undefined.

Creating a Custom Item Template in VS2008

Tuesday, December 22nd, 2009

I write a lot of C# code, so anything I can find to reduce the amount of time I spend “filling in the blanks” is great.  Visual Studio is perfect for helping out in these types of situations.  A case-in-point is the custom item template.

Whenever you select “Add New Item” on a project, you are shown a list of templates for the different items you can create.  These items range from new classes to database files to xml files.  I have found over time that I tend to always create the same basic structure for every class I write in C#:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace ProjectName

{

    /// <summary>

    /// ClassName

    /// </summary>

    public class ClassName

    {

        #region Private Data Members

        #endregion

 

        #region Public Accessors

        #endregion

 

        #region Constructors

        /// <summary>

        /// Construct a default instance of ClassName

        /// </summary>

        public ClassName

        {

        }

        #endregion

    }

}

After filling out the same basic structure a number of times, I realized it was time to automate.  Fortunately, as I mentioned, VS08 makes this ridiculously easy.  First create a file to use as your template, then under the “File” menu, select the “Export Template…” option.

A dialog will appear asking if you are creating an item template or a project template.  In this case, we are creating an item, so select the item option, and choose the project containing the file you created to use as a template.  Next, you will select the actual file from the project.  Note that you can select multiple files if your template needs supporting files.  Select the references to include, and then provide a name and description for the file.  make sure you have it automatically import the template, and you are finished.

If you are curious about the template structure, you view the template files as a zipped file under “Documents\Visual Studio 2008\My Exported Templates”.  By editing the files in the zip file you can further refine and enhance your template, and you can fix any problems that might have occurred during export.

Reading and Comprehending Your Way to the Top

Wednesday, September 30th, 2009

Let me start by saying that reading code is rarely fun.  Understanding it is hard.  Let’s assume that is a given, and avoid all the arguments that surround that topic.

Unfortunately, if you are a software developer, reading and comprehension skills are critical to your professional success.  Maintaining legacy code, integrating third-party components, even simple teamwork requires a developer to read and comprehend the execution of code written by a different developer.  Most real-world projects are simply too large to exist solely in the hands of a single developer, and if it did, the risk to that project would be so large as to be untenable for a responsible company.

Given the seemingly critical nature of reading and understanding code written by other people, why are we content to dismiss it as hard?  Writing software is just as hard, but no one seems to wave their hand at that problem as too difficult.  Not only that, but we talk about writing code for others, but never seem to discuss reading other people’s code (try searching Google for “writing readable code” and compare it to the results for “Reading Code”).

This seems to be a fundamental deficiency in the training of future software developers.  When we learn to write, we do not just sit down and memorize the rules for sentence construction along with word definitions.  Instead we balance those grammar rules by reading the works of authors who have already mastered their craft.  We read books, newspapers, magazines, journals, and develop an ability to recognize “good” and “bad” writing, independently of the actual validity and specifics of the sentence and paragraph construction.

Why can’t we do the same thing in software?

I’ve already talked about differentiating yourself by becoming comfortable in a domain outside of the development world, but that doesn’t always translate to your next project or job.  So if you want to differentiate yourself in the software development world, learn to read code.  Learn to recognize well-written code and poorly written code.  Learn how other people approach problems and construct solutions.  Your own work will improve immensely as you learn to recognize your own good and bad designs.

Reading Code without brackets

Monday, May 18th, 2009

Quick question, what is wrong with the following code?

bool result = false;
if (test1) {
  if (subtest1) {
    DoSomething();
  } else
    DoSomethingElse();
  result = FinalMethod();
} else if (test2) {
  result = GetSecondResult();
}
return result;

Stumped?  What if I told you that FinalMethod should only be called if “subtest1” is false?

I have changed the names and circumstances to protect the innocent, but the facts of the error remains the same as one i just encountered in a code review.  Of course, even knowing that little tidbit of information, it still took me a couple of minutes to see the error (Fortunately my spidey sense was tingling, so I knew *something* was wrong…)  The first time I read the code, this is what I saw (I reformatted to make the misperception clear, but the formatting was in reality the same as above):

bool result = false;
if (test1) {
  if (subtest1) {
    DoSomething();
  } else {
    DoSomethingElse();
    result = FinalMethod();
  } else if (test2) {
    result = GetSecondResult();
  }
}
return result;

Of course, that is a nonsensical statement, but that is how my brain interpreted the block.  Since the code was missing the brackets around the else statement, my brain simply supplied the expected syntax, regardless of its validity.  Given that the error was an introduced error, it is safe to assume the original developer’s brain did much the same thing, since there was even a comment to the effect that if subtest1 failed it would return the result of FinalMethod().

So how can we prevent these types of errors?  If our brains are actively working against us, then we need to work to give our brain what it wants:

bool result = false;
if (test1) {
  if (subtest1) {
    DoSomething();
  } else {
    DoSomethingElse();
    result = FinalMethod();
  }
} else if (test2) {
  result = GetSecondResult();
}
return result;

Now there is no need for our brain to supply the missing brackets, since they are explicit.  In addition, if we had originally used those brackets, it would have been immediately clear to anyone reading the code that the call to FinalMethod was occurring outside the else block, making the error much easier to detect, and much more unlikely to enter the codebase.

Casting Performance

Tuesday, May 12th, 2009

The system that I am currently working on depends a lot on casting an object to an interface to see if it implements that interface.  If it does, the system will take one action, if not, it will take a different action.  Because of this, casting performance is very important to the overall performance of the software.

As far as I am aware, there are 4 ways in C# to test if a given instance of an object implements an interface (without knowing the exact type of the instance).

1. “as” cast after an “is” check:

if (castingObject is StringBuilder)
{
  StringBuilder testBuilder = castingObject as StringBuilder;
  // do stuff
}
else
{
  // do other stuff
}

2. “as” cast with a null check:

StringBuilder testBuilder = castingObject as StringBuilder;
if (null != testBuilder)
{
  // Do stuff 
}
else
{
  // Do other stuff
}

3. Explicit cast after an “is” check:

if (castingObject is StringBuilder)
{
  StringBuilder testBuilder = (StringBuilder)castingObject;
  // Do Stuff
}
else
{
  // Do Other Stuff
}

4. Explicit cast with InvalidCastException:

try
{
  StringBuilder testBuilder = (StringBuilder)castingObject;
  // Do Stuff
}
catch(InvalidCastException)
{
  // Do other stuff.
}

Method #4 should clearly be the worst performing option if you expect any number of the casts to fail (since throwing an exception is very expensive in .NET).  So which of the three remaining methods would result in the best performance?  Well, the only way to know for sure is to measure it, so that’s what I did.

As Cast with Is check: 0.0082533 seconds.

As Cast with Null check: 0.0077226 seconds.

Explicit Cast with Is check: 0.008119 seconds.

Explicit Cast with No check: 448.7026034 seconds.

Judging from these results, doing an “as” cast followed by a null check is the fastest way to test if an object instance is of a certain type.  Of course, there is not enough of a difference between any of the first three methods to make me redo any existing code, and I certainly wouldn’t sacrifice readability/maintainability just to grab 5 milliseconds or so over 200,000 casts.

If you are curious I ran the casts inside a 100,000 iteration loop, with one “successful” cast and one “failed” cast, for a 50% success rate.  A more clever test would take into account the actual expected failure rate of the casts and use that to measure the performance, but this was just a question of curiosity for me – as I mentioned the possible improvements are too small for me to worry about as long as I avoid the explicit cast with no checks.

Standing out in a Crowd

Monday, April 13th, 2009

How many of you have ever commented on a manager’s lack of technical ability and/or knowledge?  I’d wager that most of us have been astonished at least once in our careers by the technical incompetence of someone in charge of a technical project.  A manager who doesn’t understand what “compile” means, who can’t grasp the concept of “automated testing”.  Someone who doesn’t understand the domain of their employees.

It is difficult to work for someone like that.  It can be difficult trusting their judgment when you know that they can’t grasp the simplest functions of your day-to-day job.  Now, before you think this is another internet rant about clueless managers, let me ask you a question:

Can you have a conversation with your customers in their domain? 

If you write financial software, can you sit down and talk with the financial analysts who use their software, without requiring the use of a “domain expert” to translate for you?  If you can’t, you should consider learning how. 

Too often we focus on learning our domain.  We learn all the neat tricks in our chosen language.  We become experts in the quirks of automated memory management.  We learn about the differences between allocating on the stack versus on the heap.

Honestly though, when was the last time a successful release hinged on some arcane development trick that only 10 people in the world know about?

Every software release hinges on the ability of that software to solve some pressing need of its customers.  And unless you are selling software and services to other software developers, those customers do not care about the software development domain.  They care about the financial services domain.  They care about the medical domain.  They care about the cellular phone domain.

Become a domain expert.  Learn to talk to your customers so you can anticipate their needs before they do.  Don’t be content to be just an expert developer, strive to be more, so that the next time a customer calls you, you don’t become that clueless manager, asking what exactly it means to compile your software.

Removing distractions and building relationships

Thursday, March 19th, 2009

I've been thinking a lot about management lately.? After a long stint working my way up the management ladder, I am now back “in the trenches”.? This has given me an opportunity to assess other management styles from the point of view of an employee, while also being able to evaluate it based on my own knowledge and experience.

Scott Berkun wrote that as a manger your “relationship with your programmers is everything”.? I like this statement.? You often hear that a manager's job is to protect the programmers from everything else so they can do their job.? Frankly, I find that position rather annoying.

Some programmers need and want to be sheltered in that manner.? They want to be left alone to create their next great class.? They don't care whether the customers like the software or that they customer can't use it because it is too slow.? That is someone else's problem.? For these developers, having a manager that hides all that messiness is a blessing.

Other programmers love to work in that environment.? They want to know the details.? They want to know how what they do fits into the overall plan.? If their manager were to make them simply work on their code without an understanding of the larger context, they would go nuts.

Still other programmers want to move beyond simply programming into leadership positions.? They want to be on the front lines, interacting with customers and clients, making the decisions that affect the direction of the project.? Their manager has to work with these folks and give them opportunities to learn and demonstrate that leadership abilities.

The moral here is that every employee is different.? They all want different things, and to simply say that a manager should block any distractions from the developer's job is dumping everyone into the same category.? Instead, as a manager you have to learn what it is your team needs, and give them that.? It will be de different for every person, and sometimes you won't be able to give them what they want.? But your relationship with them lets you accomplish your goals, while helping them accomplish theirs.

Bad API’s

Monday, March 16th, 2009

Bad API’s are the bane of every programmer’s existence.? They sap productivity and introduce errors into otherwise clean code.? They should be eradicated at all costs, yet they live on despite the best efforts to improve them.

How can you stop bad API’s?? The best way is to not write them in the first place.? This means paying attention to your design and paradigm.? This means taking the extra time to think about your problem.? This means that you will not be the first one across the finish line… at least for this race.

At least you can take comfort in the idea that some day some programmer won’t curse your stupidity for cleverly calling your simple AddItemToEnd method PutTheJunkInTheTrunk.? And they won’t throw things after discovering that you have to remember to increment a global count variable every time you use a factory to create a new object.? Trust me, it won’t be nearly as amusing after 10 hours of debugging, and it will be much harder to defend that decision.

Code smells, and passing a generic instance as a strongly-typed parameter

Saturday, March 14th, 2009

Whenever I see repeated blocks of code, I become suspicious.? I start to wonder if I can’t refactor that common code into a common method and (hopefully) simplify the existing code.? Recently I ran across a pattern of code that occurred intermittently throughout the codebase.? The pattern had a form similar to this:

Code In Review is proudly powered by WordPress
Entries (RSS) and Comments (RSS).