10 Reasons Code Duplication Increases Cost

Eliminating duplication is rule #2 of Beck’s Simple Design.

Duplicates “Duplicates,” courtesy Pelle Sten. License.

Here’s a starter list of the costs that duplication creates:

  • increased effort to change all occurrences in the system. Think about 5 lines of logic duplicated 30 times throughout your codebase, and now they need to all be changed.
  • effort to find all occurrences that need to change. This is often compounded by small changes (e.g. renaming) made over time to the duplicated code.
  • risk of not finding all occurrences in the system. Imagine you need to change the 5 lines of logic; you locate 29 occurrences but miss the 30th. You’ve now shipped a defect.
  • risk of making an incorrect change in one of those places. 30x increases chances of screwing up by 30 times… or more. Tedium induces sleepiness.
  • increased effort to understand variances. Is that small change to one of the occurrences intentional or accidental?
  • increased effort to test each duplicate occurrence in its context. And more time to maintain all these additional tests.
  • increase in impact of a defect in the duplicated logic. “Not only is module A failing, but so are modules B through Z and AA through DD.”
  • increased effort to understand the codebase overall. More code, more time, less fun.
  • minimized potential to re-use code. Often the 5 duplicated lines are smack-dab in the middle of other methods, minimizing your potential for some form of algorithmic substitution.
  • self-perpetuation. A codebase and culture that doesn’t promote code sharing just makes it that much harder to do anything about it.

No doubt some of you can add additional costs associated with duplicate code in a system. Please do (in the comments).

More on That First TDD Exercise

incrementalism “Kata,” courtesy Brett Jordan. License.

A few weeks ago, I iterated characteristics for a very-first exercise for TDD newbies. But once you’ve settled on a great introductory TDD example, how do you deliver it? What do you talk about or demonstrate, and what do the students do on their own?

I used to initiate TDD training by first doing a demo, then letting students do their own similar exercise (or even the same one) on their own. When demonstrating my example, I’d first talk about the TDD cycle, then launch into some coding. During the demo, I’d discuss the mechanics of their unit-testing tool and assertion framework of choice, what a test looked like, what sorts of things to focus on during refactoring, and so on.

I got good at coding while talking and looking at the students. So what? The problem was, I was blathering and they were watching, providing a great opportunity for them to start tuning out–a very bad thing for people who likely are anxious about TDD in the first place. I tried a bit of choreographing: I’d demo bit-by-bit, waiting for students to catch up on coding the same bit. It worked, but still seemed like too much was getting covered all at once.

My goal instead became to get students into their own, simplest possible exercise as quickly as possible. Using a technique I learned from James Grenning long ago, students are given a complete set of tests for the first exercise. Initially the tests are all disabled or commented out. The tests are ordered to best promote consistent incremental growth of the solution.

The student’s job is to uncomment one test at a time, watch it fail, get it to pass, refactor, and then move on to the next test. My primary instruction to them is to ensure that they write no more code than needed to get the current test to pass. This is a hard and important lesson to learn and understand! My secondary instruction is to tell them to clean the code up with each passing test (yet they never do enough of it, regardless of instruction!).

If I’ve done my job particularly well in terms of ordering the tests, I can even introduce a tool that forces the issue of minimal implementations: The TDD Smackdown Tool is a simple test runner that generates test failure when students write code that causes any of the still-commented-out tests to pass. It’s not foolproof, but might prevent them from coding too much before you have time to get to their machine to, well, smack ’em down.

By simply following the instructions and getting tests to pass, students learn a lot by osmosis. A second exercise, without the training wheels of already-written tests, goes far more smoothly. They can look at the first exercise for what a unit test must look like.

No technique is perfect. Some possible challenges / discussions:
– “Since I have all the tests, I know what the complete solution will require, so why not code it already?”
– “Would I normally write all the tests at once?”

Using this Grenning Method, the focus shifts to one core element: how to incrementally grow a solution using TDD. Discussions can focus on the red-green-refactor cycle, emphasizing refactoring and “red first” / minimal implementation.

Selecting a First TDD Exercise

Kata “Kata,” courtesy Peter Gordon. License.

Introducing developers to TDD? You want to carefully choose a first exercise. Too short, too long, too simple, too complex, too toy-like, too close to their problems, too whatever, and you might have chosen a turn-off. First impressions matter!

Of course, you can’t please everybody, but you can usually find a good middle ground. Here are some criteria for selecting an appropriate first TDD exercise.

Not frivolous. While very many of us love games and trivialities, there are enough developers that don’t. Their takeaway: “TDD is just for toys, not the ‘professional’ development that I do.” The Bowling Game? Save it and other games for a second or later exercise.
“Real” enough. A dozen years ago, I used to demonstrate a stack example in Java. Its implementation was a trivial four methods that simply delegated to an underlying list. Same takeaway: “Why would I bother building such a thing? TDD is just for toy examples.”
Time frame: Not too short, not too long. For a very first exercise, something that takes learners about 25-40 minutes to implement as a pair is ideal. (For experienced test-drivers like you or me, this translates to about 10-15 minutes as an individual and 20 minutes in a pair.) Any longer and they’ll get frustrated; much shorter and they won’t have had a chance to get into the rhythm.
Promotes incrementalism. Part of TDD’s power is in its ability to help you incrementally grow an implementation in a series of small steps. A ~45 minute example as suggested might involve 5-7 individual tests. As a counter-example: Looking for a Benefactor, a challenge at the kata site CodeWars.com, provides a decent challenge. However, the end-implementation is fully codeable with a second test, and there’s perhaps only one additional (denegerate) test to try.
Allows alternate solutions. Just about everything does, but if there’s one and only one decent way to code it, find something that allows for more interesting choices.
Mild problem solving required. You don’t want learners to bog down on thinking terribly hard about the problem itself. Yes, they need to think, but not so much that they’re distracted away from the core concepts and technique of TDD. For this reason, problems requiring “interesting” math are probably not a great idea for the average IT developer. Think simple.
Promotes refactoring. The ability to refactor with confidence is perhaps the primary reason to do TDD, so this criterion is quite important. You want strong reminders at refactoring steps that the code will get out of hand without incremental cleanup. It’s likely that problems promoting incrementalism and requiring “mild problem solving” will provide enough refactoring opportunities.
Allows mistakes. Mistakes are great learning opportunities! You want the possibility for an average learner to make up to a few stupid (or not so stupid) mistakes when implementing a solution. It’s even better if they are also likely to make mistakes when refactoring.
Minimizes esoteric language knowledge. A good developer shouldn’t have to Google something to figure out how to implement a solution.
Potentially expandable. While there’s something to be said for “done,” having an example you can build on later, or add to for fast learners who are ahead of others, can be worthwhile.
Fun enough. Not a toy example, but something that programmers might enjoy enough to quickly relate to and dig into.

Knowing your audience can help you refine the above to chose an example even better suited to their interests!

One example of an exercise that I’ve found to work well: acronym generator, also at CodeWars. It can be done with or without regex string splitting, and the regex is simple if that’s the route the developer chooses. There are ample additional requirements you could introduce (salutations, suffixes, resolve clashes, etc.).

Mind you, this is all for a first example. Subsequent exercises can be as meaty, long, goofy, or tricky as needed!

The Compulsive Coder, Episode 7: Please AAA

Q. What behavior does the following JUnit test describe? (In other words, what’s an appropriate name for the test?)

        MockInitialContext mic = MockInitialContextFactory.getContext();
        mic.map.put(ClassicConstants.JNDI_CONTEXT_NAME, "tata");

        LoggerFactory.getLogger(ContextDetachingSCLTest.class);

        ContextJNDISelector selector = (ContextJNDISelector) ContextSelectorStaticBinder.getSingleton().getContextSelector();
        Context context = selector.getLoggerContext();
        assertEquals("tata", context.getName());
        System.out.println(selector.getContextNames());
        assertEquals(2, selector.getCount());

Maybe it helps, just a bit, if I tell you that the test name is testCreateContext.

Why must I spend time reading through each line of a test like this to understand what it’s really trying to prove?

The test designer might have made the central point of the test obvious, by visually chunking the test into its Arrange-Act-Assert (AAA) parts:

        MockInitialContext mic = MockInitialContextFactory.getContext();
        mic.map.put(ClassicConstants.JNDI_CONTEXT_NAME, "tata");
        LoggerFactory.getLogger(ContextDetachingSCLTest.class);
        ContextJNDISelector selector = (ContextJNDISelector) ContextSelectorStaticBinder.getSingleton().getContextSelector();

        Context context = selector.getLoggerContext();

        assertEquals("tata", context.getName());
        System.out.println(selector.getContextNames());
        assertEquals(2, selector.getCount());

Well, I think that’s right at least, given what we know.

(Yes, the word “test” in the name duplicates the requisite @Test annotation. And yes, there are other problems with the test, e.g. printing anything to the console. But it’s excruciatingly simple to first ensure the structure of a test is clear.)

Standards are only that if they are constantly adhered to.


Previous Compulsive Coder blog entry: this Duplication Is Killing Me
Next Compulsive Coder blog entry:

The Compulsive Coder, Episode 6: this Duplication is Killing Me

A few months ago, I got caught up in a series of contentious debates about duplication in test code. I’m the sort who believes that most of our design heuristics–simple design in this case–fall victim to the reality of the pirate’s code: “The code is more what you’d call ‘guidelines’ than actual rules.” Which is OK by me; rules are made to be broken.

this
Image courtesy drivethrucafe; license

Unit tests are different beasts than production code. They serve a different purpose. For the most part, they can and should follow the same standards as production code. But since one of their primary purposes is to provide summary documentation, there are good reasons to adopt differing standards. (I solicited some important distinctions on Twitter a few months ago; this will be fodder for an upcoming post.)

With respect to Beck’s four rules of simple design, many have contended that expressiveness slightly outweighs elimination of duplication, irrespective of being production code or tests. With production code, I’m on the fence.

But for tests? The documentation aspect of tests is more relevant than their adherence to OO design concepts. Yes, duplication across tests can cause some future headaches, but the converse–tests that read poorly–is a more typical and bigger time-waster. Yes, get rid of duplication, absolutely, but not if it causes the readability of the tests to suffer.

My dissenting converser was adamant that eliminating duplication was king, citing Beck himself in Test Driven Development by Example (2002), on page one, no doubt: Step four in the rhythm of TDD says you run all the tests, and step five, “Refactor to remove duplication.” In that summary of steps, Beck suggests no other reasons to refactor! I can understand how a literalist-slash-originalist might be content with putting their foot down on this definition, never mind that “refactoring” has a broader definition anyway, never mind Beck’s simple design to the contrary, and never mind 14 years passage in which we’ve discussed, reflected, and refined our understanding of TDD.

Why a contentious debate? The dissenter was promoting a framework; they had created some hooks designed to simplify the creation tests for that framework. A laudable goal, except for the fact that I had no clue what the tests were actually proving. That just wads my undies.

Where am I going with all this? Oh yeah. So as I watched the dissenter scroll through some of their tests & prod code onscreen, I noted this repeated throughout:

public void doSomeStuff() {
   this.someField = someMethod();
   int x = this.someField + 42;
   // etc.
}

Apparently their standard is to always identify field usage by scoping it with this. (I bit my lip, because at that point I was weary of the protracted debate, and figured I could write about it later. Here I am.)

“Hey, over-using this might be a good idea, because we can more easily identify where fields are used, which is important information!”

OK, I’m offended that duplication-monists don’t view the use of this in this case (i.e. not to disambiguate) as unnecessary duplication. It is. Squash it. Instead, use the power of your sophisticated IDEA or Eclipse IDEA, and colorize fields appropriately. (I like orange.) They’ll stand out like sore thumbs.


Previous Compulsive Coder blog entry: Extract Method Flow
Next Compulsive Coder blog entry: Please AAA

The Compulsive Coder, Episode 5: Extract Method Flow

To be a refactoring wiz in Eclipse or IDEA, you don’t need to memorize dozens of keystrokes. Combined with a few mega-important keys (particularly Ctrl-1, “quick fix”), seven fairly mnemonic keystrokes will supply the bulk of your refactoring muscle. In Eclipse, they happen to be the top seven on the refactoring menu:

refactorMenu

Your version of Eclipse won’t have a key assignment for Extract Constant. It’s one of the rare keys I custom-assign, and K makes sense if you remember enough high school math.

There are about 20 more refactoring menu items in Eclipse, yet I use most of those so infrequently that I don’t find value in trying to memorize the keys to which they’re bound. I use Convert Local Variable to Field often enough, but rather than assign and remember a keystroke, I simply delete the type declaration and use Ctrl-1 to define the field.

I use these “Super Seven” shortcuts frequently throughout a typical coding day. They (a) minimize the amount of typing I do (and subsequently reduce the opportunity for mistakes) and (b) minimize the amount of mouse clicking I do, which is about an order of magnitude slower and worse for my wrist.

I’m amazed at how often I’m able to accomplish some fairly significant refactoring by solely using combinations of the Super Seven.

One such ultra-common sequence is the extract method flow, a bread-and-butter operation for any developer.

Let’s do a bit of extracting against the following test method:

   @Test
   public void answersDaysLateWhenReturnedAfterDueDate() {
      holding = new LibraryHolding(THE_TRIAL, BRANCH_EAST);
      holding.checkOut(TODAY);
      Date threeDaysLate = new Date(holding.dateDue().getTime() + 3 * MS_IN_ONE_DAY);

      int daysLate = holding.checkIn(threeDaysLate, BRANCH_EAST);

      assertThat(daysLate, is(3));
   }

We want to isolate the ugly code to derive threeDaysLate into a helper method, perhaps named addDays. But if we highlight the entire line and simply do Extract Method (Cmd-Option-M), Eclipse doesn’t quite do what we want:

   @Test
   public void answersDaysLateWhenReturnedAfterDueDate() {
      holding = new LibraryHolding(THE_TRIAL, BRANCH_EAST);
      holding.checkOut(TODAY);
      Date threeDaysLate = addDays();

      int daysLate = holding.checkIn(threeDaysLate, BRANCH_EAST);

      assertThat(daysLate, is(3));
   }

   private Date addDays() {
      Date threeDaysLate = new Date(holding.dateDue().getTime() + 3 * MS_IN_ONE_DAY);
      return threeDaysLate;
   }

We want holding.dateDue() and 3 to be arguments to the method. Undo!

A better sequence:

  1. Extract to local variables any expressions we want as arguments.
    1. Highlight holding.dateDue() and press Cmd-Option-L (Extract to Local Variable). Change the variable name to simply date. The result looks like this:
            Date date = holding.dateDue();
            Date threeDaysLate = new Date(date.getTime() + 3 * MS_IN_ONE_DAY);
      
    2. Similarly highlight the 3 and extract it as a local named days:
            Date date = holding.dateDue();
            int days = 3;
            Date threeDaysLate = new Date(date.getTime() + days * MS_IN_ONE_DAY);
      
  2. Extract the method. First select either the whole line, or just select the right-hand side of the assignment to threeDaysLate. Then press Cmd-Option-M. Type in the new method name of addDays. The result:
       @Test
       public void answersDaysLateWhenReturnedAfterDueDate() {
          holding = new LibraryHolding(THE_TRIAL, BRANCH_EAST);
          holding.checkOut(TODAY);
          Date date = holding.dateDue();
          int days = 3;
          Date threeDaysLate = addDays(date, days);
    
          int daysLate = holding.checkIn(threeDaysLate, BRANCH_EAST);
    
          assertThat(daysLate, is(3));
       }
    
       private Date addDays(Date date, int days) {
          Date threeDaysLate = new Date(date.getTime() + days * MS_IN_ONE_DAY);
          return threeDaysLate;
       }
    
  3. Inline the arguments.
    1. Click on (no need to select) either occurrence of the date local variable (either the declaration+assignment, or its use as an argument to addDays). Press Cmd-Option-I (Inline). You’ll receive a confirmation dialog asking whether or not you want to Inline 1 occurrence of local variable ‘date’; simply press enter.
    2. Similarly, click on either occurrence of the days local variable, and press Cmd-Option-I to inline it. The result:
         @Test
         public void answersDaysLateWhenReturnedAfterDueDate() {
            holding = new LibraryHolding(THE_TRIAL, BRANCH_EAST);
            holding.checkOut(TODAY);
            Date threeDaysLate = addDays(holding.dateDue(), 3);
      
            int daysLate = holding.checkIn(threeDaysLate, BRANCH_EAST);
      
            assertThat(daysLate, is(3));
         }
      
         private Date addDays(Date date, int days) {
            Date threeDaysLate = new Date(date.getTime() + days * MS_IN_ONE_DAY);
            return threeDaysLate;
         }
      

      (In addDays, I find the local variable threeDaysLate personally useless, so I also inline it.)

What I love about extracting small abstractions like this is that they open my eyes to additional opportunities to clean things up. It’s now obvious that the method we created belongs elsewhere, perhaps in some sort of date utility class where it broadcasts its existence and thus entices folks to reuse it. What also becomes evident is that the local variable threeDaysLate no longer adds much value. We inline it:

   @Test
   public void answersDaysLateWhenReturnedAfterDueDate() {
      holding = new LibraryHolding(THE_TRIAL, BRANCH_EAST);
      holding.checkOut(TODAY);

      int daysLate = holding.checkIn(addDays(holding.dateDue(), 3), BRANCH_EAST);

      assertThat(daysLate, is(3));
   }

Three steps: extract locals, extract method, inline. No direct typing in the editor. Repeat and ingrain.


Previous Compulsive Coder blog entry: You Create, It Assigns
Next Compulsive Coder blog entry: this Duplication is Killing Me

The Compulsive Coder, Episode 4: You Create, It Assigns

roomba long exposure
Image courtesy Chris Bartle. License.

Some languages are destined to be always overly verbose. One feature I’d hoped for in later versions of Java was implicit typing. In C#, for example, you can declare:

var customer = new Customer("Jose Cañusi");

It’s not too hard for the compiler to figure out that customer is of type Customer.

Java still has no implicit typing. Any time you need a non-specific Customer instance, you need the following code:

Customer customer = new Customer("Elmer Sklue");

I’m out of breath doing all that typing! Well, not really: I didn’t do all that typing. But I’ve suppressed a scream too often pairing with folks who do type the word customer three different times.

We have computers to compute for us. Never mind that the Java language is a cranky old uncle, you at least have a Generation Z development environment if you’re using Eclipse or IDEA.

I’m pretty sure I first saw J.B. Rainsberger demonstrating the following tip at least a dozen years ago.

Type the instantiation (right-hand) side of things first:

new Customer("Anne Teak");

Do not type the left-hand side! Instead, press Cmd-1 (Quick Fix; the corresponding keystroke is Alt-Enter in IDEA). Select Assign statement to new local variable and press enter. If you’re young enough to store away another shortcut, use the slightly more effective Cmd-2-L key combination instead.

Unnecessary typing represents distraction, waste, and risk.


Previous Compulsive Coder blog entry: Typing Isn’t the Bottleneck
Next Compulsive Coder blog entry: Extract Method Flow

The Compulsive Coder, Episode 3: Typing Isn’t the Bottleneck

As Mike Hill says, “the hard part of programming is the thinking,” and not the typing. And yet in this Compulsive Coder blog series, I’m focusing on the very little things, things that might save you as few as milliseconds in some cases:

  • Auto-generated comments that you can simply delete in a quarter second.
  • A color scheme that might trigger slightly faster recognition about something important.
  • And in this post, I’ll implore you to delete lines (like those auto-generated comments) in one keystroke instead of three.

Is all this a waste of time? Shouldn’t we be focusing on bigger, headier things that *are* the bottleneck–such as ways to ensure your code stays clean, so that you don’t waste monstrous amounts of time on code comprehension? Sub-optimization goes against the lean software edict to “optimize the whole.” Why bother?

I’ll offer a few reasons:

  • Less typing ==> fewer opportunities to screw up. Let the computer do the work, it’s rarely wrong! Jeff Bay, via Twitter: “fixing obscure bugs because of obscure f-ing types is a major bottleneck.
  • Wasted time adds up. A mere hundred unnecessary movements across the course of a day add up to half a million across a twenty-year career.
  • RSIs are real, and unnecessary movements similarly add up.
  • Moments you spend on mechanical operations–hunting and clicking, or sequencing together operations–are things that distract from your thought process.

To me, it’s about having the craftsman mentality of caring, more than anything. A craftsman is always seeking better individual approaches to building software. They seek to optimize frequent operations by minimizing the waste involved. They don’t tolerate regular inefficiency.

So, my nit. Real small, real short.

We delete lines often enough in programming. I watch some programmers do so by first navigating to the beginning of the line (if needed), highlighting the text to the end of the line, and then cutting the text (Cmd-X, e.g.). Ridiculous.

In Eclipse, it’s simply Cmd-d (by default). In IDEA, it’s Cmd-Delete. If you have Vrapper (a VIM plugin), it’s dd. One operation, not three.


Previous Compulsive Coder blog entry: Syntax Coloring
Next Compulsive Coder blog entry: You Create, It Assigns

The Compulsive Coder, Episode 2: Syntax Coloring

eclipseColorWheelNote: I understand that not everyone sees the entire spectrum of color. This blog post is focused on those who are able to clearly distinguish color differences. Perhaps my sentiments and suggestions apply to other visual triggers, which as I understand still exist for many of those diagnosed as color blind.

In 1986, my manager broke down and bought me my very first color monitor–a good deal more expensive than a monochrome monitor. I still remember him saying, “What a waste. What do you need those colors for?” I didn’t have much of an answer other than that it was “easier on the eyes.” Mind you, this is in the days where most software was geared for of 25×80 character-mode, green-on-black terminals. I hooked into an HP/3000 minicomputer, and the OS (MPE-III) wasn’t going to cough up anything particularly interesting with respect to colors.

Today, we take color for granted on our phones and other devices, and know how colors play a significant role in garnering attention and triggering reactions.

And yet. At a customer site where developers code using Eclipse, a first glance tells me that virtually all programmers accept the default color scheme provided; no questions asked. Sigh.

What do Eclipse default colors look like? Take a look:

eclipseBlah

Pretty uninteresting, eh? Black, purple, blue. Neither panache nor nuance. Nothing really stands out.

In fact, Eclipse emphasizes the wrong things. Keywords such as public and void and throw are bold and purple, intended to stand out. Yet keywords are often the least interesting thing about a chunk of code; they are likely the thing I need to digest last. Even worthless comments stand out with the Eclipse default color scheme! At least statics are italicized; that seems OK. It’s also good that fields are colored–but unfortunately they are dark blue, which contrasts little with the other elements.

What should stand out in Java code? Fields, certainly. Where a class’s code interacts with fields is a key piece of information. As such, I configure my fields to be bright orange. For most people, the orange fields stand out like sore thumbs. Here’s the same code with my current orange-featuring color scheme:

eclipseColor

Where parameters and local variables are used is also relevant. Being able to track on a specific color for each (gold and green, respectively) can make it easier to track state changes across the body of a method (although the Eclipse feature Mark Occurrences is more useful for tracking a specific variable).

The return keyword isn’t typically very interesting, unless it occurs somewhere other than at the end of a method. No one uses underlining any more, but I’ve found that doing so can help me more quickly spot an early return.

The use of inherited fields–an odd practice, questionable at best (and one that this code doesn’t feature)–really stands out and annoys me, because I’ve made them bright red.

Emphasizing important elements is valuable, but so is de-emphasizing less relevant elements. Comments, too often not to be trusted, are now a light gray, barely visible. On days where I’m particularly affronted with the worthlessness of comments, I make them white.

While my color choices (which I change from time to time) suit me just fine, they might not suit you, however. You and I will disagree on precisely what the “right” things are to emphasize or de-emphasize. That’s ok. The key thing is to make a conscious, informed choice, and to pay attention over time to what the colors tell you about your code.

The world is full of color. Bring your IDE into that world.


Previous Compulsive Coder blog entry: The Stub Comment
Next Compulsive Coder blog entry: Typing Isn’t the Bottleneck

You can find my current color preferences for Eclipse here. You can merge these entries into the file ./.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs in your workspace.

The Compulsive Coder, Episode 1: The Stub Comment

Some things keep coming back, such as facial hair, indigestion, and platform shoes. And for me, Java. I’m once again back in the Java world for a current engagement, and accordingly I’m again working with Eclipse.

The instant I began pairing with folks on Eclipse, my “Felix sense” kicked in, and I became unbearably indignant about the horrible defaults that too many developers simply accept. No one could tolerate more than one Ungar-ism at a time, so in this post I’ll focus on a real simple one:

public Holding findBy(String key) {
   // TODO Auto-generated method stub
   return null;
}
422769556_4094cecb03_m
Image courtesy Adam Engelhart; license

My immediate reaction was probably much like this.

A stub comment! Egads! Why in the world would people pollute their code with stub comments? Coders use their powerful IDE to auto-generate a new, empty method, but then have to waste time picking up and deleting these ugly, useless little stub comments. And horror of horrors, sometimes they don’t–I just saw a screencast where the programmer didn’t even flinch as he created and abandoned a stub comment!

The reason? Maybe it’s the 45-second effort Eclipse requires to turn off these wonderfully useless “auto-generated method stubs.” Or the painfully inadequate system for saving and restoring preferences like this (they’re all over the place), a consideration that crops up whenever you create a new workspace.

Well, I don’t want you to be able to say “I didn’t learn anything from Jeff’s blog.” Let’s start incrementing some Compulsive Coder Principles and Techniques.

Compulsive Code Principle #1
A laziness mentality is acceptable as long as you really do minimize as much work as possible. Creating stubs that need to be deleted isn’t maximally lazy.
Compulsive Coder Technique #1
Open the Eclipse Preferences dialog. Select Java->Code Style->Code Templates. (You can find it quickly by typing code templates and pressing Enter). In the right-hand side of the dialog, select Code->Method body. Click the Edit… button. Change the template’s pattern from:

// ${todo} Auto-generated method stub
${body_statement}

to:

${body_statement}

Click the OK button.

An alternative choice: Change the template to:

throw new UnsupportedOperationException("not yet implemented");

It’s an uglier version of a stub! … but, it’s so ugly it forces you to get rid of it. Where it can be helpful is in keeping you to the red-green-refactor cycle of TDD–the thrown exception will most certainly result in a failing test.

Whichever route you choose, similarly change the Code Template for Constructor body and Catch block body.

I bet you won’t ever miss the auto-generated method stubs!

Stay tuned for more Ungarisms.


Next Compulsive Coder blog entry: Syntax Coloring

Atom