Magic Comments and Magic Strings 126

Posted by tottinger Thu, 04 Jan 2007 22:19:00 GMT

You know what I hate? Okay, other than wasted vertical space and stupid programming comments… I hate magic comments. I am still an egg wrt Java but I just looked at the java comments like @noinspect. I think that these comments are “clever” in the WallyMoore school of clever == bad. Comments are supposed to be something that the compiler ignores, and sure enough they are. But here we have special semantic value given to special comments for use by bits of the development environment. Maybe it would have been better to add new syntax, new keywords, some kind of magic pragma thing, but doing this in comments is almost as bad as doing it in magic strings (as python’s doctest does).

Surely using magic comments and magic strings is evidence that we’ve run out of better ideas. It smells like a short-term hack to me. It’s frustrating, and annoying. It’s a “conceptual dog-leg”. You have to bend the idea 45 degrees to port to realize that yes, they can make it work that way. It’s a shoehorn hack.

Sure it works, but is that how it should work? Hopefully with aspects and decorators (python) and attributes and the like we can come up with something better than magic comments and magic strings.

At least I can pray we do.

Restarting 81

Posted by tottinger Fri, 22 Dec 2006 21:00:37 GMT

Today I had a problem in Eclipse—a coworker couldn’t commit.

We found he wasn’t in the svn group on the server, so that’s perfectly okay and not eclipse’s fault. After fixing that, he still could not commit, and with the same error. After an hour or so of tail-chasing, and trying the command line, I eventually realized that he was in Windows. I used standard windows answer part A: restart the app. Guess what? It worked PERFECTLY. That’s good because part B is “restart the client” and part C is the unacceptable—restart the server.

It’s amazing the kinds of unscheduled events that take time out of a day, but it was worth my time to make sure that a teammate could be productive. Especially since work was done but blocked from being checked in.

It’s another reason not to schedule 8 productive hours per day when estimating by time. The story point method is better, because we’ve absorbed all the “normal” maintenance and “average” amounts of troubleshooting into our velocity semi-accidentally. I don’t have to account specifically for the normal “noise” necessarily part of the normal software development “signal”.

Switching Tabs In Eclipse 133

Posted by tottinger Fri, 22 Dec 2006 16:59:00 GMT

I found it!

Well, not really. I asked people who told me. After expending far too much time searching through key listings and web pages, and wearing out my welcome by asking my friends who have been using the Eclipse editor for quite a while, I finally remembered that there's an IRC channel where helpful people lurk in order to help clue-free noobs like me. Maybe I've been listening to the commercial world too much, but somehow it managed to escape my notice that open source software really does have support, and darned quick support. I think maybe it's unwise to deny programmers access to open source, and it's certainly unwise of any company using open source to not allow access to the support forums. It is often the shortest distance between here and productivity. If it were commercial software, I doubt I would have waited for an hour on a tech support line (and paid for the time) in order to ask productivity-enhancing questions. I would tend to save the support calls for "real problems."

The answer to the problem of switching between editor tabs is Control-PgUp and Control-PgDn.

The answer getting a quick answer to prob lems is #eclipse at freenode.net. Thanks to the good people there, esp "buggs".

Teaching an Old Dawg New Tricks 44

Posted by Bob Koss Thu, 21 Dec 2006 16:16:00 GMT

I learned something a few weeks ago that has saved me quite a bit of typing. I’m a pretty good typist but I still feel that saving a few seconds here and there pays compound interest when integrated over weeks, months, and a career. I’ve never seen anyone do this before and I get to work with a lot of programmers so I thought I’d share it here.

Joe “J.B.” Rainsberger was in our office a few weeks ago giving some internal training. Joe is the author of JUnit Recipes and if you don’t already own the book, buy two copies – it’s very good. Anyway, Joe was doing a demo for us and I watched how he created objects in Eclipse. If I wanted a new Counter object, for example, I would type:

Counter counter = new Counter();

But Joe would type:

new Counter();

and he then uses Eclipse’s Quick Help (ctrl-1) which offers to either create a local variable or a field in the class. That’s 2 keystrokes if Eclipse does it or 15 if I type it. That’s quite a return on investment in my book.

Try it and see if it makes you go just a little bit faster.

Eclipse Java Style Settings 85

Posted by tottinger Thu, 21 Dec 2006 15:53:53 GMT

Normally we comment on larger ideas and bigger issues, but this time I just wanted to let people know where the heck the setting is:

Window->Preferences->Java->Code Style->Formatter

Click “Edit” or “Show” (depending on which appears)

now you can go to Indentation.

Make sure you set the number of spaces/tab to a reasonable number. I’m on a project now where we use 2. I prefer 3 or 4, but I’m just this guy. Also make sure you choose to use only spaces, no tabs. I don’t care if using tabs saves a few bytes here and there, it saves a lot of hassle if we all use spaces.

Also pop over to the Blank Lines tab and change the option so that it no longer double-spaces your stinkin’ field declarations. I don’t know who likes it that way, but it ain’t me, bub.

Okay. Now click buttons that say “OK” until you are back to your normal Eclipse screen. Get a ginger ale and a stresstab and GBTW!

The Need For Speed 30

Posted by Uncle Bob Thu, 21 Dec 2006 13:18:00 GMT

Yesterday was the day we felt the accelleration.

As you may know, we’ve been working on a largish web application to use as a running example in our new Principles, Patterns, and Practices course. The first couple of days of development were typically slow; and we all felt the pressure of getting “too little” done. But we stuck to our disciplines and wrote tests, and kept the code as clean as possible.

Working this way is not easy. We have a deadline that is very real; and there is a lot of money tied to it. So we all feel “the need for speed”. But all of us also know that Brian Marick is right when he says: “When it comes to software, it doesn’t pay to rush.” So we’ve nervously tolerated the pace and continued to practice TDD and continuous refactoring.

On the third day it started to pay off. The structure of our code is clean and simple enough that new features are starting to be able to take advantage of older features. We have enough tests (~90% coverage) to ensure that minor refactorings to facilitate reuse aren’t risky. And so we were able to twist the code a little here, and tweak it a little there, and within a single day triple the functionality of the code.

Let me make this more concrete. We have a set of stories. We’ve estimated those stories with point values. The sum of our velocity on Monday was close to zero. On Tuesday we got 11 points done. On Wednesday we got 26 points done. This acceleration is due to the fact that we were able to take advantage of the similarities in the features and craft the new features into place by making fine adjustments to the existing structure.

I don’t need to tell you that if we’d been practicing cut-and-paste programming we would not have had that option. Instead of a carefully crafted structure that allows new features to be easily melded, we’d have feature silos with much duplicated code and messy tangles.

Size Matters 379

Posted by Bob Koss Thu, 21 Dec 2006 10:58:00 GMT

Contrary to what you may have heard or what you might like to hear, size really does matter. We programmers must take matters into our own hands and become masters of our domains. Unless we take action, things are just going to get bigger and bigger until we have a real mess on our hands.

I travel a lot and I get to visit a lot of different companies. No matter which industry a company is in or which programming language a team is using, there is one commonality in all of the code that I see – classes are just too damn big and methods are just too damn long. (What did you think I was talking about?)

Way back in the olden days when I had hair on my head, I studied Structured Design. This was where I learned the concept of cohesion. A software module with high cohesiveness was considered a good thing. As I transitioned to Object Oriented Design (still with a full head of hair), I learned Bertrand Meyer’s One Responsibility Rule and later Robert Martin’s Single Responsibility Principle. These latter two concepts restate and reenforce what Larry Constantine said back when Structured Design was in vogue – a module should do one thing and do it very well.

The trouble with this idea of a module (class or method) doing one thing is that it is subjective. What I consider one thing you might consider several things. For example, I might see a method as getting a Customer object out of a database, yet you see it as:

  1. establishing a connection to the database,
  2. forming the sql,
  3. executing the sql, and
  4. creating and returning a Customer object from what it found in the results of the sql execution.

A guideline that sometimes works when deciding if a module is doing “too much” is simply to describe what it does. If you find yourself using the word “and” in this description (or working really hard to phrase the description in such a way to avoid using “and”), it might be doing too much. Of course you have to adhere to the spirit of the guideline. I can describe the National Air Traffic Control System as “Prevents Collisions”. I didn’t have to use the word “and” once. It doesn’t follow that we can write the entire system as one class with one method – let’s call it main. Or if you program in C#, call it Main.

Uncle Bob presents a different view of “responsibility” in his Agile Software Development book. He promotes a responsibility as a reason to change. If a class has two reasons to change, it has two responsibilities and it might be wise to split the class into it’s two pieces.

This notion of breaking a class into smaller and smaller pieces is exactly opposite to what I learned when I first started studying OO. Way back when I worried about bad-hair days, people believed that a class should encapsulate everything that concerned it. A Customer class would know the business rules of being a Customer as well as how to retrieve itself from the database and display it’s data. That’s a fine idea, provided the database schema never changes, the display never changes, or the business rules never change. If any one of those responsibilities change, we are at a high risk of breaking other things that are coupled to it.

So what’s the real problem? What harm does it do if we go around proudly making our big modules even bigger. Well, I can think of a few problems:

1. Comprehensibility

The bigger a method (or class) is, the harder it is to understand without significant study and effort. I believe that as soon as I have to scroll a method in order to read it, I’m wasting valuable time because the method is doing more than my brain can hold. I often find myself scrolling back because I forgot what scrolled off the top of my window. I know I’m in a minority (considering all the code I’ve seen with massive classes and methods) but I like methods short and sweet.

2. Magnets for change

Massive classes with big methods do a lot – they have to because there is a lot of code in them. Unfortunately, that also means there’s a lot that can go wrong in them. When we fix a bug in one of these huge modules, we have to change the code – and changing code often means the code becomes worse. When we have to add additional functionality, the hooks seem to be in these big classes, so they get even bigger, and once again the code deteriorates even more. It’s easier to add code to existing classes and methods than it is to create new classes. Some companies have a heavy hand on the source code repositories and developers would rather make existing classes bigger than deal with the bureaucracy of adding another module to the corporate SCR.

3. Collisions

Because a lot of code is in each of the ever-growing modules, it stands to reason that different team members will be editing the code in these modules for different reasons. You know what that means come check-in time; the dreaded diff and merge. And because it’s so painful, developers put it off as long as possible which only makes the problem worse.

4. Lack of reuse

The bigger a module is, the less likely it is that you will be able to reuse it in a different context. It does so much that it becomes specialized to the current context.

5. Comments are needed

Large methods can’t be named for their intent, i.e., you can’t tell what a method does from its name because it does so much. Earlier this year I saw a multi-thousand line method named ‘execute’. Yeah, it was obvious what it did – not. Developers tend to write comments to explain what a method does. We’ve all seen them – the next 200 lines calculate a thingamabob, then another comment explaining the next 450 lines. The problem with comments is that in large systems, worked on by numerous developers over a period of years, the code goes one way and the comments tend to stay as originally written. When the code says one thing and the comments say another, which will you believe? Yet more obscurity.

6. Decreased code quality

Where do you think you’ll spot a glaring defect quicker, in a 6 line method or in the middle of a 300 line while loop with page-long if-else constructs in it?

7. Increased maintenance costs

Every time you visit a large module, you have to understand the piece that you’re going to work on. Often, that means you have to understand the entire module just to find the area where you are going to work. All of this takes time, and time is money. Ha – I seem to be on a roll with these sayings – “time is money”, “size matters”, hmmmm…. can “your check is in the mail” be far behind?

8. Easier performance profiling

When you are trying to locate performance bottle-necks, and whatever tool or timing mechanism you’re using tells you that the 8,000 line doItToIt() method is taking “too long”, how are you going to find where all the time is spent? It would be much easier to see the 6 line calculateAmount() function was taking too long because it was hitting the database.

There are many things in life that I wish were bigger—lots bigger (hard disk, thumb drive, monitor, RAM, etc.) but classes and methods should not be in that list. Understanding at a glance with good, meaningful, intention revealing names can go a long way to keeping software costs down and making our lives as developers better. I know, it isn’t easy to spare the time. It’s much easier to use that time to struggle to squeeze another clause to that already overgrown method; it’s much easier to use that time single stepping through the vastly indented forest of if/else/for/while; it’s much easier to use that time poring through a tangled and twisted rat’s nest of code over and over just to work out what it might just be doing. Oh yes, it’s MUCH easier.

I got tired and debugged! 22

Posted by Uncle Bob Thu, 21 Dec 2006 00:02:00 GMT

My grandaughter slept over last night. She’s an early riser. She and I had breakfast at 6am. My wife got a new cell phone (TREO680) yesterday, and I helped her set it up. So I didn’t go to bed until late. In short, I didn’t get a lot of sleep.

A bunch of us are working on a new training example for object oriented design principles and patterns. It’s a large-ish web-based system that has lots of interesting lessons to learn. We’ll be presenting it as a series of exercises throughout the course. Anyway, we’ve all been working as a team, writing this software. It’s been a lot of fun!

Anyway, about 3pm I started to get really tired. I should have stopped. But I wanted to finish one last story! (You know the feeling.) So I pressed on.

I ran accross a small dependency problem between two of the classes. So I started an elaborate refactoring to resolve the issue. An hour later I had to back out the whole refactoring because it didn’t solve the problem, or even come close! I don’t know what I was thinking. The real solution was much simpler and took just 10 minutes or so to implement. I should have stopped then, but, well, you know…

I needed to leave at 5pm. By 4:30 I was executing my unit tests. There was a problem. It didn’t make sense. You know the kind! I stared at the code for a long time, but my brain was mush. I couldn’t think. The lines of code swam before my eyes, but did not speak to me. I should have stopped then.

But no. Instead, I did something I barely ever do. Something I haven’t done in many months. I set a breakpoint! Egad! I was single-stepping through the code. And then I would do that horrible little dance where you step to a point in a module and realize you’ve gone a step or two too far. The variables don’t make sense. So you start over, and step back to just before where you were. Hideous! I should have stopped! But I kept at it. Over and over, breaking, stepping, breaking, stepping.

Debuggers feed you a torrent of information. Even when you are awake it’s easy to misread them. When tired, you see what you want to see, not what you really see. And nothing I saw made any sense. I finally got to the point where an if statement comparing two identical strings was failing! (Or so I thought.) I demanded that the stupid machine was lying. I rebuilt the application. I rebooted my machine. I redid the breakpoint, over and over. No change.

Now it was after 5pm. I really needed to go. I also really needed to fix this damned problem and check in the code. So I did the only thing that might make a bit of sense (other than stopping, which is what I should have done 2 hours before), I turned off the debugger and asked my pair-partner James for some help.

James had been busy helping one of the other guys get subversion working with Eclipse, so he’d been somewhat distracted while I was spinning myself into a debug rathole. He came right over and looked at my unit test. He said “Oh, shouldn’t that fravitz be a dorvitz?”

...

Duh. Yes, that fravitz should have been a dorvitz. It was obvious. It was simple. It was a 2 second change, and the tests all passed. (sigh).

So I, once again, reinforce my rule about debuggers. They are a horrible time-sink. When you find you must debug, it’s time to get help or go home.

Blog 27

Posted by tottinger Wed, 20 Dec 2006 21:22:00 GMT

Welcome to the new Object Mentor blog. We've upgraded a server and upgraded our blog software to be more attractive and convenient. David has the software up and running on a newly-reinstalled Debian server. We will have much more frequent security updates, and we're able to use more modern software in general.

The blog will have a few changes. You may not see a special TimOttinger area separate from the RobertMartin or DavidChelimsky areas (or the other OM staffers). The way you reply will be different too, but hopefully you will find that we preserve the same basic spirit and high degree of interactivity.

The search function is more interactive and powerful than the old too. You can search for articles by keyword, in case you're looking for information about the Law of Demeter or Single Responsibility Principle.

We hope you enjoy the new blog as much as you enjoyed the old. The old one is still available as a read-only archive (at least until we migrate all the old blogs forward).

Older posts: 1 ... 36 37 38