Slim 3

Posted by Uncle Bob Thu, 02 Oct 2008 14:33:11 GMT

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

Posted by Uncle Bob Thu, 28 Aug 2008 21:02:45 GMT

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

Posted by Uncle Bob Tue, 19 Aug 2008 01:29:32 GMT

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.

Now you should be able to run the orbital simulator. Just type:

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

Posted by Uncle Bob Thu, 14 Aug 2008 19:01:00 GMT

“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

Posted by Uncle Bob Tue, 29 Jul 2008 05:09:40 GMT

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

Posted by Uncle Bob Sun, 20 Jul 2008 15:42:29 GMT

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

Posted by Uncle Bob Thu, 26 Jun 2008 13:16:00 GMT

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

Posted by Uncle Bob Tue, 24 Jun 2008 23:07:46 GMT

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

Posted by Uncle Bob Tue, 08 Apr 2008 00:10:16 GMT

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

Posted by Uncle Bob Tue, 08 Apr 2008 00:10:16 GMT

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

Older posts: 1 2 3 ... 5