Slim 3
Those of you who have been following me on Twitter have heard me talk about Slim. Slim is a new testing front-end and back-end that I’m adding to FitNesse. Here’s what it’s all about.
FitNesse is a very popular open-source acceptance testing tool that allows non-programmers to write and execute tests. FitNesse is an authoring and execution wrapper around the testing engine Fit. Fit interprets HTML and uses a set of programmer supplied fixtures to invoke the system under test.
The problem is that Fit is big. There’s a lot of stuff inside there. And it all has to be ported to the language (or platform) of the system under test (SUT). Unfortunately, since Fit is all open source it means that the various ports don’t agree with each other. It also means that a change made to one, does not match a change made to another. This is deeply frustrating.
To make matters worse, the effort required to maintain a fit port is relatively high. The folks who maintain these ports do so out of the goodness of their own hears, and have real jobs that often take effort away from Fit.
The end result is that the universe of Fit is uneven at best. Java programmers can use one set of features and fixtures, whereas C++ programmers must use a completely different set. The .NET version of the fixtures work in a very different way from the Java versions. New languages and platforms require a relatively large effort just to get started with Fit. etc.
Slim—The solution
Fit interprets HTML tables in order to make specific calls to the SUT. Fit does all this interpetation in the SUT. What if we moved all that table interpretation to FitNesse? FitNesse is written in Java and communicates with the SUT through a socket. Right now it passes all the HTML through that socket to Fit and accepts the colorized HTML back through the socket from Fit. But what if we changed the partitioning? What if we did all the table processing in FitNesse and then shipped a list of calls across the socket to the SUT?
That’s what Slim is. Slim is a very small module that runs in the SUT. It listens at a socket for very simple commands that instruct it to create instances of fixtures and to call methods on those instances. It passes the return values of those method calls back through the socket.
Slim is very small. Porting it is a matter of a few hours work. Once ported, there’s virtually no other maintenance required. It seems unlikely that new Slim features will be needed very often.
What this means is that all the table processing is done on the FitNesse side, and will work exactly the same regardless of the platform of the SUT. C++, Ruby, Java, Python, C#? It doesn’t matter, your tables will work in exactly the same way.
And who said we needed tables anyway? Since all the processing is done on the FitNesse side, we can write new kinds of testing languages. We can write story runners like RSpec or JBehave. They will all use Slim to communicate to the SUT, and will all work identically with any platform that has a Slim port.
Slim Tables
If you are familiar with Fit, you know that there are different fixture types. There are ColumnFixtures, RowFixtures, ActionFixtures, DoFixtures, etc. Each of these require a library to be written and executed on the SUT.
In Slim we replace these with processors on the FitNesse side. Instead of ColumnFixtures we have DecisionTables. Instead of RowFixtures we have QueryTables. Instead of DoFixtures we have ScriptTables. New kinds of tables can be added using a simple plug-in mechanism.
Slim Fixtures
Slim fixtures are very similar to Fit Fixtures except that they don’t inherit from anything! There is no library on the SUT that you have to include.
Interestingly enough, if you already have a Fit ColumnFixture written for your SUT, it will very likely work with a Slim DecisionTable. Existing RowFixtures will likely work nicely with a Slim QueryTable, etc.
Migrating to Slim
To replace Fit with Slim for a test page, all you need to do is set the variable TEST_RUNNER to slim. This will invoke the Slim table processor rather than the old Fit test runner.
!define TEST_RUNNER {slim}
There are some minor differences in the table format. The biggest is that the table type is no longer known by the fixture. Therefore FitNesse needs to know what kind of table you are writing. So a column fixture that used to look like this:
|eg.Division|
|numerator|denominator|quotient|
|10 |2 |5 |
Will now require a simple prefix as follows:
|DT:eg.Division|
|numerator|denominator|quotient|
|10 |2 |5 |
Did you see the DT:? That’s it. Otherwise the tables should be the same. And as you might guess there will be similar prefixes for QueryTable (QT), and ScriptTable (ST).
Indeed, this is the part of the Slim Tables that I like the least. If anybody has a better idea, or at least some better prefixes, I’m all ears (er. eyes).
What if you like processing tables in fixtures?
Some of you might use TableFixture, or just do your own table processing in your Fit fixtures. You can still do that with Slim. One of the table types I plan to implement is a raw Table (Table prefix). The whole table gets shipped over the socket to the fixtures as a List of Lists of Strings, and the fixture returns with a table with the same geometry, loaded with “pass”, “fail”, or “neutral” to provide colorization hints.
Current Status.
I currently have Slim working in Java, and Decision Tables being processed. What I don’t have so far are any of the other table types, suites, command line test runners, etc. So there’s plenty of work to be done.
There will be code 3
During the last three decades, several things about software development have changed, and several other things have not. The things that have changed are startling. The things that have not are even more startling.
What has changed? Three decades have seen a 1000 fold increase in speed, another 1000 fold increase in memory. Yet another 1000 fold decrease in size (by volume), and yet another 1000 fold decrease in power consumption. Adding up all those zeros implies that the resources we have to play with have increased by twelve orders of magnitude. Even if I have over estimated by five orders of magnitude the remaining seven are still and astounding increase.
I remember building RSX-11M on a PDP-11/60 from source. It took several hours. Nowadays I can build huge java applications in a matter of seconds. I remember that compiling small C programs required dozens of minutes. Now much larger programs compile in a eyeblink. I remember painstakingly editing assembly language on punch cards. Now I use refactorings in huge java programs without thinking about it. I remember when 10,000 lines of code was five boxes of cards that weighed 50 pounds. Now, such a program is considered trivial.
Nowadays we have tools! We have editors that compile our code while we type, and complete our thoughts for us. We have analyzers that will find code duplication in huge systems, and identify flaws and weaknesses. We have code coverage tools that will tell us each line of code that our unit tests fail to execute. We have refactoring browsers that allow us to manipulate our code with unprecedented power and convenience.
But in the face of all this massive change, this rampant growth, this almost unlimited wealth of resources, there is something that hasn’t changed much at all. Code.
Fortran, Algol, and Lisp are over fifty years old. These language are the clear progenitors of the static and dynamic languages we use today. The roots of C++, Java, and C# clearly lie in Algol and Fortan. The connection between Lisp, and Ruby, Python, and smalltalk may be less obvious, but only slightly so. Today’s modern language may be rich with features and power, but they are not 12 orders of magnitude better than their ancestors. Indeed, it’s hard to say that they are even ONE order of magnitude better.
When it comes down to it. We still write programs made out of calculations, ‘if’ statements, and ‘for’ loops. We still assign values into variables and pass arguments into functions. Programmers from 30 years ago might be surprised that we use lower case letters in our programs, but little else would startle them about the code we write.
We are like carpenters who started out using hammers and saws, and have progressed to using air-hammers and power saws. These power tools help a lot; but in the end we are still cutting wood and nailing it together. And we probably will be for the next 30 years.
Looking back we see that what we do hasn’t changed all that much. What has changed are the tools and resources we can apply to the task. Looking forward I anticipate that the current trend will continue. The tools will get better, but the code will still be code. We may see some “minor” improvements in languages and frameworks, but we will still be slinging code.
Some folks have put a great deal of hope in technologies like MDA. I don’t. The reason is that I don’t see MDA as anything more than a different kind of computer language. To be effective it will still need ‘if’ and ‘for’ statements of some kind. And ‘programmers’ will still need to write programs in that language, because details will still need to be managed. There is no language that can eliminate the programming step, because the programming step is the translation from requirements to systems irrespective of language. MDA does not change this.
Some folks have speculated that we’ll have “intelligent agents” based on some kind of AI technology, and that these agents will be able to write portions of our programs for us. The problem with this is that we already have intelligent agents that write programs for us. They are called programmers. It’s difficult to imagine a program that is able to communicate to a customer and write a program better than a human programmer.
So, for the foreseeable future I think software will remain the art of crafting code to meet the requirements of our customers.
There is something else that needs to change, however. And I believe it is changing. Our professionalism.
In some ways our “profession” has paralleled that of medicine. 300 years ago there were a few thinkers, and far too many practitioners. There were no standards, no common rituals or behaviors, no common disciplines. If you got sick you might go to a barber, or a healer. Perhaps he’d let out some blood, or ask you to wear some garlic. Over time, however, the few thinkers gained knowledge, discipline, and skill. They adopted standards and rituals. They set up a system for policing and maintaining those standards, and for training and accepting new members.
THIS is the change that I hope the next thirty years holds for software development.
Baubles in Orbit 3
I have put together a nice little demonstration of the Bauble concept. You may recall that I first wrote about it here. Baubles are a simple component scheme for Ruby, good for when you want a component, but don’t need something as heavy as a gem.
orbit.zip contains all the files for this demonstration. I suggest you download and unpack it.
First you need to install the Bauble gem. Don’t worry, it won’t hurt anything. Just say gem install orbit/bauble/Bauble-0.1.gem (You’ll probably have to do it with sudo.) That should install Bauble. From now on you only need to say require 'bauble' in your ruby scripts that make use of it.
cd orbit/MultipleBodyOrbit/lib
jruby multiple_body_orbit.rb
A swing window should pop up and you should be able to watch an orbital simulation. Every run shows a different random scenario, so you can kill a lot of time by watching worlds in collision.
The thing to note, if you are a ruby programmer, is the use of the term Bauble::use(-some_directory-). If you look in the multiple_body_orbit.rb file you’ll see I use two Baubles, the Physics bauble does the raw calculation for all the gravity, forces, collisions, etc. The cellular_automaton bauble provides a very simple Swing framework for drawing dots on a screen. (Yes, this is jruby).
If you look in either of the two Baubles, you’ll see that the require statements within them do not know (or care) about the directory they live in. There is none of that horrible __FILE__ nonsense that pollutes so many ruby scripts. This is because the Bauble::use function puts the directory path in the LOAD_PATH so that subsquent require statements can simply eliminate the directory spec.
Take a look at the Bauble source code. It’s no great shakes.
Also take a look at the two baubles. They show a pretty nice way to decouple business rules from gui. You might recognize the MVP pattern. The multiple_body_orbit.rb file contains the presenter. Clearly the Physics module is the model. And the cellular_automaton module is the view. (There is no controller, because there is no input.)
Quintessence: The fifth element for the Agile Manifesto 44
“Quintessence” was the name of the keynote I gave at the banquet of Agile 2008. Though the talk covered a lot of ground, the upshot was that we need an addition to the agile manifesto…
As you know the Agile Manifesto is composed of four balanced value statements. Here they are:
- Individuals and interactions over processes and tools
- Working software over comprehensive documentation
- Customer collaboration over contract negotiation
- Responding to change over following a plan
In my talk I proposed the following addition
- Craftsmanship over Crap.
From this you can probably tell that my talk was primarily about behaving professionally, and writing clean code. This should not be a big surprise since I just finished writing a book entitled Clean Code .
The problem with my proposal is that it is not a balanced value statement. In the other four statements we value the second item. We just value the first item more. But in my proposed addition, we simply don’t value crap at all.
So I hereby change my original proposal, which was made for dramatic effect, to:
- Craftsmanship over Execution
Most software development teams execute, but they don’t take care. We value execution, but we value craftsmanship more.
Comments? Anyone have a better word?
(BTW, I used a wonderful web tool named Visual Thesaurus to find the word “execute”. Check it out!)
Tag: How did I get Started in Software Development
Micah tagged me with this “chain-blog”. I’ve enjoyed reading other peoples’ stories. You can read them too by just following the chain back to the start. (It’s a shame there’s no good way to do the forward links!)
Here’s my story.
How old were you when you started programming.
6th grade. That would have made me 11, so 1963. My mother bought me a little plastic computer named Digi-Comp I. This device contained 3 flip-flops and 6 “AND” gates that could be interconnected to create simile finite state automata. I played with it for weeks. I ordered the companion manual “How to write programs for Digi Comp I” which was a simple tutorial in boolean algebra. I inhaled it.
My freshman year in high school the math department was considering purchasing a simple electronic educational computer. It was called an ECP-18. It has 1024 15 bit words of drum memory. It had the coolest front panel. You programmed it in machine language by toggling in the instructions.
I learned to program it by listening to the salesperson has he entered in the diagnostic programs. He would mumble under his breath as he toggled them in. He’d punch in an octal 15 and mutter “store”, or an octal 12 and mutter “load”. Following the op-code he’d enter the memory address he was loading or storing. Fortunately I knew octal from my experience with Digi-Comp I. So I could follow along. After a while I started entering my own programs. Just simple things to compute 2x+4 or something like that. Fortunately for me I always put the constant zero at the end of each of my programs because I used it to clear the main register (the accumulator). I didn’t know it, but zero was the op-code for halt.
What was the first real program you wrote?
Mr. Patternson’s Computerized Gate. This was a simple little finite state automata that I designed for the Digi-Comp I. Mr. Patterson was a wise old man and people would line up to talk with him. His gate would admit only one person at a time. It detected when Mr. Patterson was free. Would open. When a new petitioner sat down the gate would close again.
Is that a “real” program? Were any of the ECP-18 snippets I put together “real”? I once saw a demo of someone typing BASIC into a GE timesharing computer. I didn’t know BASIC, but I inferred the structure and started writing programs in it. I was never able to execute any of them. My father bought me books on Fortran, Cobol, PL/1. I inhaled them all. I wrote lots of programs in those languages, but I had no computers to execute them on.
Probably the first “real” programs I wrote were for an Olivetti/Underwood Programma 101. It was a programmable calculator the size of a microwave oven. My father took me to a science teacher conference. They had one on display. They let me play with it. I wrote programs to solve pythagoras theorem, etc.
What languages have you used since you started programming?
Egad! Fortran, Cobol, PL/1. BAL. PDP8 assembler, PDP11 assembler, 8080 assembler, Varian 620 assembler, GE Datanet 30 assembler, 6502 assembler, 68000 assembler, 8086 assembler, SNOBOL, LOGO, Smalltalk, Prolog, C, C++, Java, C#, Ruby, Forth, Postscript, Flex, etc. etc. etc. etc….
What was your first professional programming gig?
At the ripe old age of 16 I got a very temporary job writing Honeywell 200 assembler (which is a lot like 1401 assembler) for a actuarial firm named A.S.C. Tabulating.
If there is one thing you learned along the way that you would tell new developers, what would it be?
Being a programmer is like being a doctor or a lawyer. You must never stop learning. Just as doctors will read medical journals, and lawyers keep up with legal decisions, programmers must keep up with new languages, operating systems, frameworks, etc. Learn, learn, learn.
What’s the most fun you’ve ever had programming?
I can’t rank them. There are too many to count. I wrote a Lunar Lander game in Logo. I wrote a multi-tasking nucleus for an 8080 in C. Any time I went into a store with a C64 on display I’d type in a quick program to print / and \ randomly on the screen. I wrote an 8080 program in binary to control a set of relays to play “Mary had a little lamb”. The fun never stops!!!
Up Next
Brett Schuchert, Dave Nicolette, Martin Fowler, (Pragmatic) Dave Thomas, (OTI) Dave Thomas, Grady Booch, Bob Weissman
Bauble, Bauble... 4
In Ruby, I hate require statements that look like this:
require File.dirname(__FILE__)+"myComponent/component.rb"
So I decided to do something about it.
This all started when my Son, Micah, told me about his Limelight project. Limelight is a jruby/swing GUI framework. If you want to build a fancy GUI in Ruby, consider this tool.
I have neither the time nor inclination to write a framework like this; but my curiosity was piqued. So in order to see what it was like to do Swing in JRuby I spent a few hours cobbling together an implementation of Langton’s Ant. This turned out to be quite simple.
The result, however, was a mess. There was swing code mixed up with “ant” code, in the classic GUI/Business-rule goulash that we “clean-coders” hate so much. Despite the fact that this was throw-away code, I could not leave it in that state – the moral outrage was just too great. So I spent some more time separating the program into two modules.
The first module knew all about Langton’s ant, but nothing about Swing. The second module was a tiny framework for implementing cellular automata in Swing. (Here are all the files).
I was quite happy with the separation, but did not like the horrible require statements that I had to use. The cellular_automaton component had two classes, in two separate files. In order to get the require right, I had to either use absolute directory paths, or the horrible File.dirname(__FILE__)... structure.
What I wanted was for cellular_automaton to behave like a gem. But I didn’t want to make it into a gem. Gem’s are kind of “heavy” for a dumb little thing like “cellular_automaton”.
So I created a module named “Bauble” which gave me some gem-like behaviors. Here it is:
module Bauble
def self.use(bauble)
bauble_name = File.basename(bauble)
ensure_in_path "#{bauble}/lib"
require bauble_name
end
def self.ensure_in_path(path)
$LOAD_PATH << path unless $LOAD_PATH.include? path
end
end
This is no great shakes, but it solved my problem. Now, in my langton’s ant program all I need to do is this:
require 'bauble'
Bauble.use('../cellular_automaton')
All the ugly requires are gone.
I’m thinking about turning Bauble into a rubyforge project, and making a publicly available gem out of it in order to give folks a standard way to avoid those horrible __FILE__ requires. I think there are several other utilities that could be placed in Bauble such as require_relative etc.
Anyway, what do you think?
Now 'and' for something completely different. 15
My son Justin is working as a Ruby apprentice for my son Micah at 8th light. We were sitting at the kitchen table, and he showed me a function he was writing. In the midst of the function I saw this:
handle_batch(item) and display_batch(item) while items_remaining?
I looked hard at this and then I said: “Justin, I don’t think you understand what
and does.
He said: “I think I do.” and he pointed me to a website which showed 21 Ruby tricks “you should be using in your own code.”
Trick #9 was the use of the and keyword to couple statements together to make “one liners”. It was billed as a trick that [cough] “more confident” Ruby programmers use.
So I got the pickaxe book out and looked up the and keyword. I showed Justin where it said that the second clause won’t be executed if the first clause is false (or nil!) So if handle_batch ever returned nil, then display_batch would never be called.
Warning bells were going off in my head. This was clearly an unintended use of the and keyword that could have rather nasty repercussions. I thought it was somewhat irresponsible for a website that boasted expertise in programming to tell people they should be using a dangerous stunt like this.
However, handle_batch did not return nil, so the and worked well enough in this case; and we had more to do. So I made my point to Justin and then we kept working, leaving the and in place.
An hour later we were making changes to a function. Suddenly a whole bunch of our tests broke. (You know what I’m going to say, don’t you?) The failure mode didn’t make any sense. Suddenly a whole bunch of processing simply wasn’t getting done.
It was Justin who said: “Wow, I’ll bet it’s that and. And it was. The change we had made had indirectly caused handle_batch to return a nil.
OK, this was a fun little story. You might think the moral is “don’t use and for one-liners” or “don’t trust websites that claim expertise”. Yes, those would be good conclusions to draw. But I’m concerned about something else.
The “and trick” is clever. In programming, clever != smart. (OK, sorry, that was clever…) Using a keyword like and in a manner for which it was not intended, and in a way that is not guaranteed to work in all cases, is risky. It bothers me.
By the same token it bothers me that so many Ruby programmers use the ||= trick for lazy initialization. I know it works. I know it’s a standard idiom. I’m not trying to stop people from doing it. Hell, I use it too because it’s become a standard idiom. But it bothers me nonetheless because it entered our vocabulary of idioms because it was clever trick; and clever little tricks have a way of turning into nasty little surprises.
Ruby is a fun and powerful language. But that doesn’t mean we should go out of our way to be clever. We shouldn’t be eager to adopt quirky little idioms and erudite little stunts just because they are cute, or neat, or nifty. Code is hard enough to understand without having to think sideways through the next novel application of the ?: operator.
Professionals write clear and clean code. They use their language well. They use their language efficiently. But they don’t aspire to be master tricksters. Rather, they prove their professionalism by writing code that needs no explanation.
So... You want your code to be maintainable. 7
We know that maintenance is 90% of the software lifecycle, and 90% of the cost. We know that our systems need to be flexible, reusable, and maintainable. Indeed, that’s why we spend so much of our time trying to get the design and architecture just right. Because we all know that good design and architecture is the key to flexibility, reusability, and maintainability…right?
Of course. Good design and architecture is what makes software easy to change. Good design and architecture separates the things that change for one reason from the things that change for another reason (The Single Responsibility Principle). Good design allows us to add new features without changing a lot of old code (Open Closed Principle). Good design makes sure that high level policy does not depend on low level detail (Dependency Inversion Principle), etc. etc.
So how do we get good design? Well, that’s tricky. Oh it’s not too tricky to get a good design in place at first. The tricky part is to keep the design good. That’s the problem, you see. It’s not that the design starts out so bad (although sometimes…) rather it is that the design degrades over time as the system changes.
Systems change. Often they change in ways that thwart the original intent of the design. Unfortunately, changing the design to align to these changes is hard. So we wind up hacking the new features into the system and thwarting the design. And that’s how even the best designed systems rot.
So how do we keep the design from rotting? How do we make sure we can migrate the design as the system changes? Simple. Tests.
When you have a suite of tests that covers >90% of the code in the system, you are not afraid to make changes. Every time you make a little change you run those tests, and you know that you have not broken anything. This gives you the confidence to make the next change, and the next, and the next. It gives you the confidence to change the design!
Nothing makes a system more flexible than a suite of tests. Nothing. Good architecture and design are important; but the affect of a robust suite of tests is an order of magnitude greater. It’s so much greater because those tests enable you to improve the design.
This can’t be overstated. If you want your systems to be flexible, write tests. If you want your systems to be reusable, write tests. If you want your systems to be maintainable, write tests.
And write your tests using the Three Laws of TDD.
Clean Code. Whew! 11
I’ve been working on this book for several years now. After a flurry of effort (you might have noticed I’ve been quiet lately) I’m very pleased to say that I’m done with the writing and am preparing the manuscript for production. See The Prentice Hall Listing

Table of Contents
Clean Code 1
There Will Be Code 1
Bad Code 2
The Total Cost of Owning a Mess. 3
Schools of Thought. 11
We are Authors. 12
The Boy Scout Rule 13
Prequel and Principles 14
Conclusion 14
Bibliography 15
Meaningful Names by Tim Ottinger 17
Introduction 17
Use Intention-revealing Names 17
Avoid Disinformation 19
Make Meaningful Distinctions 20
Use Pronounceable Names 21
Use Searchable Names 22
Avoid Encodings 23
Avoid Mental Mapping 24
Class Names 25
Method Names 25
Don't Be Cute 25
Pick One Word Per Concept 26
Don't Pun 26
Use Solution Domain Names 27
Use Problem Domain Names 27
Add Meaningful Context 27
Don't add Gratuitous Context 29
Final Words ... 30
Functions 31
Small! 34
Do one thing. 35
One level of abstraction per function. 36
Switch Statements. 37
Use descriptive names. 39
Function Arguments. 39
Have no side-effects. 43
Command Query Separation 44
Prefer exceptions to returning error codes. 45
Don't Repeat Yourself. 47
Structured Programming 48
How do you write functions like this? 48
Conclusion 49
SetupTeardownIncluder 49
Bibliography 52
Comments 53
Comments do not make up for bad code. 55
Explain yourself in code. 55
Good Comments 55
Bad Comments 59
Example 71
Bibliography 74
Formatting 75
The Purpose of Formatting 76
Vertical Formatting 76
Horizontal Formatting 84
Team Rules 89
Uncle Bob's Formatting Rules. 90
Objects and Data Structures 93
Data Abstraction 93
Data/Object anti-symmetry. 95
The Law of Demeter 97
Data Transfer Objects 99
Conclusion 101
Bibliography 101
Error Handling by Michael Feathers 103
Use Exceptions Rather than Return Codes 103
Write Your Try-Catch-Finally Statement First 105
Use Unchecked Exceptions 106
Provide Context with Exceptions 107
Define Exception Classes In Terms of a Caller's Needs. 107
Define the Normal Flow 109
Don't Return Null 110
Don't Pass Null 111
Conclusion 112
Bibliography 112
Boundaries by James Grenning 113
Bibliography 119
Unit Tests 121
The Three Laws of TDD 122
Keeping Tests Clean 123
Clean Tests 124
One Assert per Test 129
F.I.R.S.T. 132
Conclusion 132
Bibliography 133
Classes 135
Class Organization 135
Classes should be Small! 136
Organizing for Change 146
Bibliography 150
Systems By Dean Wampler 151
How would you build a city? 151
Separate constructing a system from using it 152
Scaling Up 155
Java Proxies 158
Pure Java AOP Frameworks 160
AspectJ Aspects 163
Test-drive the system architecture 164
Optimize decision making 165
Use standards wisely, when they add demonstrable value 165
Systems need Domain-Specific Languages 166
Conclusion 166
Bibliography 167
Emergence By Jeff Langr 169
Getting Clean via Emergent Design 169
Simple Design Rule 1: Runs all the tests 170
Simple Design Rules 2-4: Refactoring 170
No Duplication 170
Expressive 173
Minimal Classes and Methods 174
Conclusion 174
Bibliography 174
Concurrency by Brett Schuchert 175
Why Concurrency? 176
Challenges 177
Concurrency Defense Principles 178
Know Your Library 180
Know Your Execution Models 181
Beware Dependencies between Syncrhonized Methods 182
Keep Synchronized Sections Small 183
Writing Correct Shut-Down Code is Hard 183
Testing Threaded Code 184
Conclusion 188
Bibliography 189
Successive Refinement 191
Args Implementation 192
Args: the rough draft. 198
String Arguments 212
Conclusion 246
JUnit Internals 249
Conclusion 262
Refactoring SerialDate 263
Conclusion 280
Bibliography 281
Smells and Heuristics 283
Comments 283
Environment 284
Functions 285
General 285
Java 304
Names 306
Tests 310
Conclusion 311
Bibliography 312
Concurrency II by Brett Schuchert 313
Client/Server Example 313
Possible Paths of Execution 317
Knowing Your Library 322
Dependencies between methods can break concurrent code 325
Increasing Throughput 329
Deadlock 331
Testing Multi-Threaded Code 335
Tool Support for Testing Thread-Based Code 337
Conclusion 338
Tutorial: Full Code Examples 339
org.jfree.date.SerialDate 345
Cross References of Heuristics 406
Clean Code. Whew! 11
I’ve been working on this book for several years now. After a flurry of effort (you might have noticed I’ve been quiet lately) I’m very pleased to say that I’m done with the writing and am preparing the manuscript for production. See The Prentice Hall Listing

Table of Contents
Clean Code 1
There Will Be Code 1
Bad Code 2
The Total Cost of Owning a Mess. 3
Schools of Thought. 11
We are Authors. 12
The Boy Scout Rule 13
Prequel and Principles 14
Conclusion 14
Bibliography 15
Meaningful Names by Tim Ottinger 17
Introduction 17
Use Intention-revealing Names 17
Avoid Disinformation 19
Make Meaningful Distinctions 20
Use Pronounceable Names 21
Use Searchable Names 22
Avoid Encodings 23
Avoid Mental Mapping 24
Class Names 25
Method Names 25
Don't Be Cute 25
Pick One Word Per Concept 26
Don't Pun 26
Use Solution Domain Names 27
Use Problem Domain Names 27
Add Meaningful Context 27
Don't add Gratuitous Context 29
Final Words ... 30
Functions 31
Small! 34
Do one thing. 35
One level of abstraction per function. 36
Switch Statements. 37
Use descriptive names. 39
Function Arguments. 39
Have no side-effects. 43
Command Query Separation 44
Prefer exceptions to returning error codes. 45
Don't Repeat Yourself. 47
Structured Programming 48
How do you write functions like this? 48
Conclusion 49
SetupTeardownIncluder 49
Bibliography 52
Comments 53
Comments do not make up for bad code. 55
Explain yourself in code. 55
Good Comments 55
Bad Comments 59
Example 71
Bibliography 74
Formatting 75
The Purpose of Formatting 76
Vertical Formatting 76
Horizontal Formatting 84
Team Rules 89
Uncle Bob's Formatting Rules. 90
Objects and Data Structures 93
Data Abstraction 93
Data/Object anti-symmetry. 95
The Law of Demeter 97
Data Transfer Objects 99
Conclusion 101
Bibliography 101
Error Handling by Michael Feathers 103
Use Exceptions Rather than Return Codes 103
Write Your Try-Catch-Finally Statement First 105
Use Unchecked Exceptions 106
Provide Context with Exceptions 107
Define Exception Classes In Terms of a Caller's Needs. 107
Define the Normal Flow 109
Don't Return Null 110
Don't Pass Null 111
Conclusion 112
Bibliography 112
Boundaries by James Grenning 113
Bibliography 119
Unit Tests 121
The Three Laws of TDD 122
Keeping Tests Clean 123
Clean Tests 124
One Assert per Test 129
F.I.R.S.T. 132
Conclusion 132
Bibliography 133
Classes 135
Class Organization 135
Classes should be Small! 136
Organizing for Change 146
Bibliography 150
Systems By Dean Wampler 151
How would you build a city? 151
Separate constructing a system from using it 152
Scaling Up 155
Java Proxies 158
Pure Java AOP Frameworks 160
AspectJ Aspects 163
Test-drive the system architecture 164
Optimize decision making 165
Use standards wisely, when they add demonstrable value 165
Systems need Domain-Specific Languages 166
Conclusion 166
Bibliography 167
Emergence By Jeff Langr 169
Getting Clean via Emergent Design 169
Simple Design Rule 1: Runs all the tests 170
Simple Design Rules 2-4: Refactoring 170
No Duplication 170
Expressive 173
Minimal Classes and Methods 174
Conclusion 174
Bibliography 174
Concurrency by Brett Schuchert 175
Why Concurrency? 176
Challenges 177
Concurrency Defense Principles 178
Know Your Library 180
Know Your Execution Models 181
Beware Dependencies between Syncrhonized Methods 182
Keep Synchronized Sections Small 183
Writing Correct Shut-Down Code is Hard 183
Testing Threaded Code 184
Conclusion 188
Bibliography 189
Successive Refinement 191
Args Implementation 192
Args: the rough draft. 198
String Arguments 212
Conclusion 246
JUnit Internals 249
Conclusion 262
Refactoring SerialDate 263
Conclusion 280
Bibliography 281
Smells and Heuristics 283
Comments 283
Environment 284
Functions 285
General 285
Java 304
Names 306
Tests 310
Conclusion 311
Bibliography 312
Concurrency II by Brett Schuchert 313
Client/Server Example 313
Possible Paths of Execution 317
Knowing Your Library 322
Dependencies between methods can break concurrent code 325
Increasing Throughput 329
Deadlock 331
Testing Multi-Threaded Code 335
Tool Support for Testing Thread-Based Code 337
Conclusion 338
Tutorial: Full Code Examples 339
org.jfree.date.SerialDate 345
Cross References of Heuristics 406
