<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Object Mentor Blog</title>
    <link>http://blog.objectmentor.com</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description></description>
    <item>
      <title>Using Band XI's FitNesse Plugin for Eclipse</title>
      <description>&lt;p&gt;Our friends at &lt;a href="http://www.bandxi.com"&gt;Band XI&lt;/a&gt; have an Eclipse &lt;a href="http://www.bandxi.com/fitnesse/index.html"&gt;plugin&lt;/a&gt; for &lt;a href="http://www.fitnesse.org"&gt;FitNesse&lt;/a&gt;. I spent a few hours trying it out for a client. Here are some notes to help you use it.&lt;/p&gt;


	&lt;p&gt;Band XI&amp;#8217;s plugin makes it easy to run FitNesse from within Eclipse and to edit the Java code and FitNesse pages in one place. Hence, no more switching between windows while you&amp;#8217;re making your acceptance tests pass.&lt;/p&gt;


	&lt;p&gt;The &lt;a href="http://www.bandxi.com/fitnesse/download.html"&gt;download and installation&lt;/a&gt; page describes how to get started. While it only lists support for Eclipse 3.1 and 3.2, it seems to work fine in Eclipse 3.3 and 3.4 M7.&lt;/p&gt;


	&lt;p&gt;After you have installed the plugin, you will have two new toolbar buttons, one to start and stop a local FitNesse server and one to start and stop a remote server.&lt;/p&gt;


	&lt;p&gt;You configure where these servers are located in the &lt;strong&gt;Preferences &amp;gt; FitNesse&lt;/strong&gt; page. These settings apply for the whole workspace. It might be nice to be able to configure them on a project by project basis, but that&amp;#8217;s not supported (and maybe not that important, either).&lt;/p&gt;


	&lt;p&gt;You also get a new project option in the &amp;#8220;&lt;strong&gt;New&lt;/strong&gt;&amp;#8221; wizard. &lt;strong&gt;Java &amp;gt; FitNesse &amp;gt; FitNesse Example Project&lt;/strong&gt; creates a new Java project with &lt;strong&gt;src&lt;/strong&gt;, &lt;strong&gt;FitNesseRoot&lt;/strong&gt; and &lt;strong&gt;fixtures&lt;/strong&gt; source directories. The include all the standard example acceptance tests and code that comes with the FitNesse download.&lt;/p&gt;


	&lt;p&gt;I encountered a little oddity the first time I started the local server by clicking the toolbar button. The usual front page, with links for the  examples, manual, &lt;em&gt;etc.&lt;/em&gt; weren&amp;#8217;t shown on the FitNesse front page.&lt;/p&gt;


	&lt;p&gt;I determined that this happens because the default &lt;strong&gt;FitNesseRoot&lt;/strong&gt; in the preferences is &amp;#8221;.&amp;#8221;. Instead, start the server the first time by right-clicking on the &lt;strong&gt;FitNesseRoot&lt;/strong&gt; folder, then select the &lt;strong&gt;FitNesse&lt;/strong&gt; menu and the &lt;strong&gt;Launch FitNesse runtime on this root folder&lt;/strong&gt; option.  From then on, it will launch with this folder as the default, until you select a different one.&lt;/p&gt;


	&lt;h2&gt;Using your own FitNesse installation and projects&lt;/h2&gt;


	&lt;p&gt;Here&amp;#8217;s what I did to work with existing projects and use a separate FitNesse installation outside of an Eclipse project.&lt;/p&gt;


	&lt;p&gt;If you have another project with the &lt;strong&gt;FitNesseRoot&lt;/strong&gt; folder, you can use it as just described (&lt;em&gt;i.e.,&lt;/em&gt; using the context menu).&lt;/p&gt;


	&lt;p&gt;Otherwise, go to the &lt;strong&gt;Preferences &amp;gt; FitNesse&lt;/strong&gt; page and paste the full path of your alternative &lt;strong&gt;FitNesseRoot&lt;/strong&gt; in the &amp;#8220;local root directory&amp;#8221; field. Be sure to delete the &amp;#8221;.&amp;#8221; value that is present by default and also watch for spaces before and after the string. It appears that they aren&amp;#8217;t removed, causing mysterious behavior&amp;#8230;&lt;/p&gt;


	&lt;p&gt;To build fixtures in your Java project, add the &lt;strong&gt;&lt;span class="caps"&gt;FIT&lt;/span&gt;_LIB&lt;/strong&gt; and &lt;strong&gt;&lt;span class="caps"&gt;FITNESSE&lt;/span&gt;_LIB&lt;/strong&gt; &amp;#8220;variables&amp;#8221; (defined by the plugin) to the Java build path for your project (using the project properties dialog). The default values of these environment variables should be fine unless you are running a different version of &lt;span class="caps"&gt;FIT&lt;/span&gt; or FitNesse in your separate installation (in which case you can change the values as needed).&lt;/p&gt;


	&lt;p&gt;Finally, set your class path in your FitNesse pages to point to the correct directory for the compiled classes. For example,&lt;/p&gt;


&lt;blockquote&gt;&lt;code&gt;!path /home/me/projects/workspace/MyFitProject/bin&lt;/code&gt;&lt;/blockquote&gt;

	&lt;p&gt;That should do it!&lt;/p&gt;</description>
      <pubDate>Fri, 16 May 2008 17:22:22 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:20d4f070-1129-46e5-b5da-501f4af145fa</guid>
      <author>Dean Wampler</author>
      <link>http://blog.objectmentor.com/articles/2008/05/16/using-band-xis-fitnesse-plugin-for-eclipse</link>
      <category>FitNesse</category>
      <category>Eclipse</category>
    </item>
    <item>
      <title>It's All Data</title>
      <description>&lt;p&gt;&amp;lt;sarcasm&amp;gt;&lt;/p&gt;


	&lt;p&gt;&amp;#8220;So, you managed to pick stories that only involved changing data&amp;#8230;&amp;#8221;&lt;/p&gt;


	&lt;p&gt;&amp;#8220;Yep.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;Great, there&amp;#8217;s no need to test it, right?&lt;/p&gt;


Therefore, testing Java classes is unnecessary.
	&lt;ol&gt;
	&lt;li&gt;The &lt;span class="caps"&gt;JVM&lt;/span&gt; simply reads files in a particular format (the Java Class format)&lt;/li&gt;
		&lt;li&gt;The &lt;span class="caps"&gt;JVM&lt;/span&gt; processes those files&lt;/li&gt;
		&lt;li&gt;Java class files are just data to the &lt;span class="caps"&gt;JVM&lt;/span&gt;&lt;/li&gt;
		&lt;li&gt;Java source files are just data to the Java Compiler to generate data used by the &lt;span class="caps"&gt;JVM&lt;/span&gt; &lt;/li&gt;
		&lt;li&gt;We do not need to test data changes&lt;/li&gt;
		&lt;li&gt;Therefore we do not need to test Java classes.&lt;/li&gt;
	&lt;/ol&gt;


&lt;p/&gt;

	&lt;p&gt;q.e.d.&lt;/p&gt;


	&lt;p&gt;Then Norbert asked &amp;#8220;Oh, by the way, did you version your data changes?&amp;#8221;&lt;/p&gt;


	&lt;p&gt;&amp;lt;/sarcasm&amp;gt;&lt;/p&gt;</description>
      <pubDate>Wed, 14 May 2008 16:37:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:d1a1903c-5b5d-415d-ba25-2605dd57ec49</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2008/05/14/its-all-data</link>
      <category>Schuchert&#8217;s Scattered Synapses </category>
      <category>test</category>
      <category>sarcasm</category>
    </item>
    <item>
      <title>Your code is not flat</title>
      <description>&lt;p&gt;There are three possibilities for the universe. On the one hand it is Closed. 
There&amp;#8217;s enough matter that the universe, currently expanding, will eventually 
stop expanding and collapse in on itself.&lt;/p&gt;


	&lt;p&gt;The universe might be open. There&amp;#8217;s not enough matter for gravitational forces
to bring the universe back in on itself.&lt;/p&gt;


	&lt;p&gt;The final option is that the universe is flat. There&amp;#8217;s just enough mass that it will stop
expanding but it will not collapse in on itself.&lt;/p&gt;


	&lt;p&gt;Assuming an infinite number of universes, the final option, the flat option,
must surly exist, somewhere. Probably not here, but somewhere. So for all 
intents and purposes, our universe is likely open or closed but not flat.&lt;/p&gt;


	&lt;p&gt;While you were reading that, your code rotted just a little. You&amp;#8217;ve heard of 
it, bit rot. The bits in a program sitting on a disk rot. It&amp;#8217;s a well known
fact. Sure the magnetic surface could give out or if it&amp;#8217;s in memory, a stray cosmic 
ray could flip a bit.&lt;/p&gt;


	&lt;p&gt;But that&amp;#8217;s not what I&amp;#8217;m talking about. You know the experience. It was just
working and now it is not working. You did not change anything so therefore
it is the same as it was and so something else must have changed. This is
bit rot.&lt;/p&gt;


	&lt;p&gt;Typically, bit rot is really just our expectations being crushed by reality.
Never let a fact get in the way of a good theory, that&amp;#8217;s my motto. This works
especially well if you tend to be a better talker than listener (guilty).&lt;/p&gt;


	&lt;p&gt;At any rate, your code continues to rot as you continue to read this. Why?
Someone using it has managed to find another thing programmers did not think about.
So what was &amp;#8220;working&amp;#8221; before is not &amp;#8220;working&amp;#8221; now. Wait, was it really working?
If someone was getting value out of using it then yes it was working. Is it
working now? If nothing about the system has changed but it no longer serves
a purpose, then it is not working.&lt;/p&gt;


	&lt;p&gt;Here&amp;#8217;s a question. If a tree falls in the forest and nobody hears it, does 
it make a sound? Answer from a human perspective, no. If there&amp;#8217;s nobody to
hear it, then it didn&amp;#8217;t make a sound. Sure it moved some air about and you
could take an infinite sum of sine waves to characterize that air movement
but then if you characterize it then something was there to observe it
and that seems to violate the spirit of &amp;#8220;nobody hears it.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;What about if there&amp;#8217;s a problem in the code and nobody hits it, does your 
code have a defect? Using the tree as an example, then the answer is no.
However, unlike the tree&amp;#8217;s sound, which quickly dissipates (if for no
other reason that then laws of thermodynamics), your code tends to stay
around a bit longer so the chance for observation of a sleeping 
defect is higher (though to be fair, if you wait long enough your code, like the sound in the forest, will go away).&lt;/p&gt;


	&lt;p&gt;OK, but it is even worse than that. Things change. If your body is not changing
then you are dead. That&amp;#8217;s a fact. In one study by Dr. Frisen, he demonstrated
the age of cells in a rib bone of a 30 year old to be just over 15 years, while
the cells that line the stomach to be closer to 5 days. Your body is constantly
fixing itself. Cells replace themselves. That&amp;#8217;s why you can donate platelets 
every 3 days and blood every 56 days.&lt;/p&gt;


	&lt;p&gt;What about your code? Is it fixing itself? Is it repairing itself? Does it need to?
If your code is not changing, then the project is dead. Sure, it takes some time
for all usefulness to finally wear out of the system but at some point the
system will essentially bit rot so badly that is serves no useful purpose.
(While there are multiple clinical definitions of &amp;#8220;dead&amp;#8221; for a body, some life
remains long after you are clinically dead &amp;#8211; your fingernails will keep growing
for some time after you expire.)&lt;/p&gt;


There are several things that cause your system to decay. Here are just a
few:
	&lt;ul&gt;
	&lt;li&gt;What the business needs changed so until the system catches up it has less value&lt;/li&gt;
		&lt;li&gt;The act of introducing the system has changed the business so that the system needs to change&lt;/li&gt;
		&lt;li&gt;Someone misunderstood something (it&amp;#8217;s actually no small miracle that people can communicate at all &amp;#8211; my wife would argue she cannot get through to me)&lt;/li&gt;
		&lt;li&gt;Someone actually changed some code badly (most 1-line bug fixes introduce new defects &amp;#8211; see Weinberg)&lt;/li&gt;
		&lt;li&gt;Someone is compelled to hack it in to meet the deadline/demo/beat the lunch crowd/...&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Your code is rotting while you read this because the environment around it is 
changing. Add to that an observation that most changes to code
introduce rather than reduce chaos and it&amp;#8217;s no wonder your system is either
closed (code collapses in on itself, weighed down by its own incidental complexity) or open (nobody can decide what to do and
the project eventually sort of fizzles into nothingness).&lt;/p&gt;


	&lt;p&gt;So what are you doing to actively maintain your system&amp;#8217;s integrity? Are you 
just using antibiotics (patching things quickly hoping that there&amp;#8217;s no super
bug on the horizon &amp;#8211; there&amp;#8217;s always a super bug on the horizon no matter 
how strong an alligator&amp;#8217;s immune system might be), or are you doing what
the surgeon general has been saying for years: getting enough sleep, 
working out regularly, eat healthily (there&amp;#8217;s a moving target).&lt;/p&gt;


	&lt;p&gt;Your code is rotting every day in every way unless you are actively working 
against that tide. Talking to your users &amp;#8211; being friendly even, writing tests 
(acceptance, integration, smoke, unit, load, exploratory, ... mostly automated),
integrating often, refactoring, learning to see beginning of rot rather than the end of it, etc.&lt;/p&gt;


	&lt;p&gt;There are a lot of things we can do and need to do to make a system. Part of that
is keeping the system alive and breathing. Unlike biological systems where nature
(and natural selection) has resulted in a self-monitoring, self-healing systems, code
does not really monitor itself and fix itself (well most code does not do that).&lt;/p&gt;


	&lt;p&gt;Maybe there&amp;#8217;s been a hidden force driving the creation of these things we
called code maintainers whose existence is predicated on the need to
repair living code to keep it around just a bit longer.&lt;/p&gt;


	&lt;p&gt;If this is the case, then just like the waist lines of americans are increasing 
as our biological systems have not had enough time to adjust to the changing 
environment, our code bases are bloating and getting to the point where code 
maintainers cannot keep the systems living long enough.&lt;/p&gt;


	&lt;p&gt;It seems a shift is in order to make it possible to keep these living, but often
very sick, applications alive longer. In a sense, if you are practicing keeping your
code clean, you are like a doctor because you diagnosing sickness, prescribing 
a path to heath and, if necessary, making incisions, using slugs or just waiting
for a given sickness to simply follow its natural course before going away (like the 
requirement that simply must be done right away, just because).&lt;/p&gt;


	&lt;p&gt;Unfortunately, if we are calling ourselves doctors, then we&amp;#8217;re still learning the value of
keeping our hands clean between procedures. Unlike doctors of the mid-19th century
who thought more blood on clothes = more experience, Ignaz Semmelweis figured 
out that hand washing saved lives.&lt;/p&gt;


	&lt;p&gt;As a community we&amp;#8217;re not there yet. There&amp;#8217;s still pride is hacking something together.&lt;/p&gt;


	&lt;p&gt;Your code is getting worse, what are you going to do about it?&lt;/p&gt;</description>
      <pubDate>Mon, 05 May 2008 23:35:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:270143c7-bfa7-491e-a827-6672b0ad46bb</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2008/05/05/your-code-is-not-flat</link>
      <category>Schuchert&#8217;s Scattered Synapses </category>
      <category>bit</category>
      <category>rot</category>
      <category>clean</category>
      <category>code</category>
    </item>
    <item>
      <title> What We Can Learn from the Ojibwe Language</title>
      <description>&lt;p&gt;Ojibwe (sometimes spelled Ojibwa; the last syllable is pronounced &amp;#8220;way&amp;#8221;) is one of the few Native American languages that isn&amp;#8217;t immediately threatened with extinction. It is spoken by about 10,000 people around the Great Lakes region. Brothers David and Anton Treuer are helping to keep it alive, as they discussed in a recent &lt;a href="http://www.npr.org/templates/story/story.php?storyId=89851668"&gt;Fresh Air interview&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Ojibwe is a language that is optimized for an aboriginal people whose lives and livelihoods depend on an intimate awareness of their environment, especially the weather and water conditions. They have many nouns and verbs for fine gradations of rain, snow, ice conditions, the way water waves look and sound, &lt;em&gt;etc&lt;/em&gt;. You would want this clarity of detail if you ventured out on a lake every day to fish for dinner.&lt;/p&gt;


	&lt;p&gt;In the past, speaking languages like Ojibwe was actively suppressed by the government, in an attempt to assimilate Native Americans. Today, the threat of extinction is more from the sheer ubiquity of English. I think there is another force at play, too. People living a modern, so-called &amp;#8220;developed&amp;#8221; lifestyle just don&amp;#8217;t need to be so aware of their environment anymore. In fact, most of us are pretty &amp;#8220;tone deaf&amp;#8221; to the nuances of weather and water, which is sad in a way. We just don&amp;#8217;t perceive the need for the richness of an Ojibwe to communicate what&amp;#8217;s important to us, like sports trivia and fashion tips.&lt;/p&gt;


	&lt;p&gt;So, what does Ojibwe have to do with programming languages? Our language choices inform the way we frame problem solving and design. I was reminded of this recently while reading Ted Neward&amp;#8217;s &lt;a href="http://www.ibm.com/developerworks/views/java/libraryview.jsp?search_by=scala+neward"&gt;series of articles on Scala&lt;/a&gt;. Scala is a &lt;span class="caps"&gt;JVM&lt;/span&gt; language that provides first-class support for &lt;a href="http://en.wikipedia.org/wiki/Functional_programming"&gt;functional programming&lt;/a&gt; and object-oriented design refinements like &lt;a href="http://www.iam.unibe.ch/~scg/Research/Traits/"&gt;traits&lt;/a&gt;, which provide &lt;a href="http://c2.com/cgi/wiki?MixIn"&gt;mixin&lt;/a&gt; behavior.&lt;/p&gt;


	&lt;p&gt;While you can write Java-like code in Scala, Neward demonstrates how exploiting Scala features can result in very different code for many problems. The Scala examples are simpler, but sometimes that simplicity only becomes apparent after you grasp the underlying design principle in use, like closures or functional idioms.&lt;/p&gt;


	&lt;p&gt;One of the best pieces of advice in the &lt;a href="http://www.pragprog.com/the-pragmatic-programmer"&gt;Pragmatic Programmer&lt;/a&gt; is to learn a new language every year. You should pick a language that is very different from what you know already, not one that is fundamentally similar. Even if you won&amp;#8217;t use that language in your professional work, understanding its principles, patterns, and idioms will inform your work in whatever languages you actually use.&lt;/p&gt;


	&lt;p&gt;For example, there is a lot of &lt;a href="http://www.technologyreview.com/Infotech/17682/page1/"&gt;fretting&lt;/a&gt; these days about concurrent programming, given the rise of multi-core CPUs and multiprocessor computers.  We know &lt;a href="http://www.javaconcurrencyinpractice.com/"&gt;how to write concurrent programs&lt;/a&gt; in our most popular &lt;em&gt;imperative&lt;/em&gt; languages, like Java and C++, but that knowledge is somewhat specialized and not widely known in the community. This is the main reason that &lt;a href="http://en.wikipedia.org/wiki/Functional_programming"&gt;functional programming&lt;/a&gt; is suddenly interesting again. It is inherently easier to write concurrent applications using side-effect-free code. I expect that we will fail to meet the concurrency challenge if we rely exclusively on the mechanisms in our imperative languages.&lt;/p&gt;


	&lt;p&gt;So, you could adopt a functional language for all or part of your concurrent application. Or, if you can&amp;#8217;t use Scala (or Haskell or Erlang or &amp;#8230;) you could at least apply functional idioms, like  side-effect-free functions, avoidance of mutable objects, &lt;em&gt;etc.&lt;/em&gt; in your current imperative language. However, even that won&amp;#8217;t be an option unless you understand those principles in the first place.&lt;/p&gt;


	&lt;p&gt;Learning a new language is more than learning a new vocabulary. It&amp;#8217;s even more than learning new design techniques. It&amp;#8217;s also learning to see common things from a fresh perspective, with greater clarity.&lt;/p&gt;</description>
      <pubDate>Sat, 03 May 2008 09:48:57 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:d5cda248-84da-418d-81ae-5419241465a0</guid>
      <author>Dean Wampler</author>
      <link>http://blog.objectmentor.com/articles/2008/05/03/what-we-can-learn-from-the-ojibwe-language</link>
      <category>Dean's Deprecations</category>
      <category>Design Principles</category>
      <category>Clean Code</category>
      <category>languages</category>
      <category>polyglot</category>
      <category>programming</category>
      <category>multilingual</category>
      <category>design</category>
    </item>
    <item>
      <title>VIM as a Diff/Merge Tool</title>
      <description>&lt;p&gt;Do you need a really quick, clean, powerful diff/merge tool that you can use in windows, mac, and various Unixen?  As a happy and pround &lt;a href="http://vim.org"&gt;vim&lt;/a&gt; user, I have been enjoying &lt;a href="http://www.vim.org/htmldoc/diff.html"&gt;vimdiff&lt;/a&gt; for a number of years.&lt;/p&gt;


&lt;pre&gt;
        &amp;gt; gvim -d file1 file2
        &amp;gt; vimdiff file1 file2
&lt;/pre&gt;

	&lt;p&gt;(G)vimdiff is wonderful. You can move changes between two versions of a file with
great ease (if you know vim) and amazing speed. It can handle files of any size and does a fine job of syncing up both versions.&lt;/p&gt;


	&lt;p&gt;Vim can do just about anything. I have learned that no matter how much I use and study Vim I still am just scratching the surface of what the editor can do.  I find little tricks and configuration options, new keystrokes, and fun little bits of minutae.  I think it&amp;#8217;s all new.  With my memory, sometimes I just &lt;strong&gt;think&lt;/strong&gt; something is new, and have to go check my &lt;a href="http://tottinge.blogsome.com/use-vim-like-a-pro/"&gt;past notes&lt;/a&gt; to see if I already knew it.&lt;/p&gt;


Today I (re)learned about diffopt, which makes gvimdiff more wonderful. 
&lt;pre&gt;
    :set diffopt=filler
&lt;/pre&gt;
By default, diffopt is set to &amp;#8220;filler&amp;#8221;.  Filler doesn&amp;#8217;t do much, it
just adds vertical spaces to keep the text of the left and right
pane aligned.  It&amp;#8217;s a good setting, and I don&amp;#8217;t much like working
without it.  But there are other settings which are overlooked, 
even by experts.
&lt;pre&gt;
    : set diffopt+=iwhite
&lt;/pre&gt;
My second favorite is &amp;#8216;iwhite&amp;#8217;, which stands for &amp;#8220;ignore whitespace&amp;#8221;.
It makes gvimdiff ignore leading, trailing, and embedded spaces so
that simple acts like retabbing or deleting vertical spaces won&amp;#8217;t 
obscure actual changes.   It really helps you to merge changes in 
situations where you&amp;#8217;ve adopted code that was built to entirely different
standards. 
&lt;pre&gt;
    :set diffopt+=icase
&lt;/pre&gt;
iCase ignores capitalization, which is not as useful as the other options, since programmers are normally interested in case, but it may be handy when someone has corrected and reformatted &lt;span class="caps"&gt;SQL&lt;/span&gt;.  I don&amp;#8217;t expect to use it much.
&lt;pre&gt;
    :set diffopt+=horizontal
&lt;/pre&gt;
The last interesting bit is the choice between vertical splits (the normal case) and horizontal splits (for very long lines on cinema-aspect screens).  I hope to never  need this option again, but I have needed to deal with absurdly long lines.

	&lt;p&gt;If you can use &lt;span class="caps"&gt;VIM&lt;/span&gt; at all, you will find vim&amp;#8217;s diffmode to be a very powerful and  useful tool.  If you can&amp;#8217;t use vim already, then maybe vimdiff will be the reason you will learn vim.&lt;/p&gt;</description>
      <pubDate>Wed, 30 Apr 2008 21:24:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:87ede884-c19a-4ab9-9a04-9b074bb32c86</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2008/04/30/vim-as-a-diff-merge-tool</link>
      <category>Tim's Tepid Torrent</category>
      <category>vim</category>
      <category>diff</category>
      <category>vimdiff</category>
      <category>diffopt</category>
    </item>
    <item>
      <title>Magic Funnel, Part 3: Covey's Miracle</title>
      <description>&lt;p&gt;We had a team of surrogate stakeholders in the room, and all the very most important stories (as far as we could tell) on a table in front of us.&lt;/p&gt;


	&lt;p&gt;&amp;#8220;These are the most important?&amp;#8221; Heads nodded. &amp;#8220;Then,&amp;#8221; I asked, &amp;#8220;what makes them important?&amp;#8221;  Brows furrowed, and well-considered answers poured forth.&lt;/p&gt;


	&lt;p&gt;I collected their reasons for importance.  Some were about keeping promises, some were about providing increased quality (uptime, correct function), and there were other kinds of importance.  We wrote them on a 3&amp;#215;5 card. Ultimately, we realized that the company&amp;#8217;s reputation is their source of importance.  Users needed to know that the company will do the right things, and provide software that worked and kept them working. I thought it was a good criteria.&lt;/p&gt;


	&lt;p&gt;Next I explained that urgency is different from importance.  There may be a hot demand for some cosmetic changes that don&amp;#8217;t really impact the company&amp;#8217;s reputation one way or another. There may be some changes that in the direction we want to go.  These may be hot topics, but may not be truly important.&lt;/p&gt;


	&lt;p&gt;We could see a difference between the forces of urgency and the force of importance, but there is gray area as a sufficient pent-up demand for otherwise unimportant changes could in fact effect our reputation for service. Still, we could usually see a crisp-enough boundary for any given user story.&lt;/p&gt;


	&lt;p&gt;I then (re-)introduced the team to &lt;a href="http://en.wikipedia.org/wiki/First_Things_First_%28book%29"&gt;Stephen Covey&amp;#8217;s four-quadrant system&lt;/a&gt;.  It has two axes.  The vertical is importance (important at the top, unimportant below).  The horizontal is urgency with urgent things to the left and non-urgent on the right:&lt;/p&gt;


&lt;table border=1px align=center&gt;
&lt;tr&gt;&lt;td&gt;Q1&lt;br&gt;Important and Urgent &lt;/td&gt;&lt;td&gt;Q2&lt;br&gt;Important, not Urgent&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Q3&lt;br&gt;Unimportant and Urgent &lt;/td&gt;&lt;td&gt;Q4&lt;br&gt;Neither important nor urgent&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;

	&lt;p&gt;We took our set of cards and the team determined groupings.  Was this a quadrant one activity? Quadrant 3? Quadrant 2?  There were some real surprises, especially when we realized our &amp;#8220;most important&amp;#8221; bit of work was not urgent and should wait until quadrant one activities were finished.&lt;/p&gt;


	&lt;p&gt;Covey&amp;#8217;s recommendation is that we tackle first those items that are both important and urgent.  When we knock that stack down, we move on to those that are important but not urgent.  If we have time left, those non-important-but-urgent items can &amp;#8220;fly standby&amp;#8221; in our sprint.  We reordered the priorities in accordance with Covey&amp;#8217;s recommendation.&lt;/p&gt;


	&lt;p&gt;We had no cards that were both unimportant and non-urgent.&lt;/p&gt;


	&lt;p&gt;At this point in time, we had what looked very much like a magic funnel. Ideas came in from everywhere, and the items that moved from the planning team to the developers came out in the &amp;#8220;magically correct&amp;#8221; order.  We agreed that the selection and the ordering were the best we could do at the time.&lt;/p&gt;


	&lt;p&gt;Our next sprint planning meeting was remarkably efficient.&lt;/p&gt;</description>
      <pubDate>Thu, 17 Apr 2008 22:15:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:92b17688-ec1a-4306-ace5-fe791fb36966</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2008/04/17/magic-funnel-part-3-coveys-miracle</link>
      <category>Tim's Tepid Torrent</category>
      <category>covey</category>
      <category>FIRST</category>
      <category>Things</category>
      <category>Quadrants</category>
      <category>important</category>
      <category>Urgent</category>
      <category>prioritizing</category>
      <category>magic</category>
      <category>funnel</category>
    </item>
    <item>
      <title>Building Magic Funnels, Part 2: Pragmatic Pedantry</title>
      <description>&lt;p&gt;The middle of the funnel we started on needed work. While it is a simple idea that the single, most important thing in the funnel is the first to emerge from the bottom, it is a multi-flavored affair to try to manage for real.&lt;/p&gt;


	&lt;p&gt;My first strategy was to get the right people in a room and have them fight it out.  I think that the prioritization process should be a lot like local government (maybe a school board?) in that people should argue and complain and push and eventually settle on compromises and deals. Ultimately, I believe that people who have a strong interest in the company can make the right decisions. At least they can be right enough for the next 5 days.  When you have one-week iterations, the next chance to change the agenda is never far away.&lt;/p&gt;


	&lt;p&gt;This first strategy didn&amp;#8217;t work out, and so we went to a backup plan.  &lt;span class="caps"&gt;A C&lt;/span&gt; level manager said he knew what we should do, and so we scheduled an hour or so with him, myself, our priority manager (&amp;#8220;funnel guy&amp;#8221;) and the senior technical developer.&lt;/p&gt;


	&lt;p&gt;Our guys used the sticky post-it 3&amp;#215;5 cards and papered the &lt;span class="caps"&gt;CIO&lt;/span&gt;&amp;#8217;s windows and whiteboards.  They listed the various categories of work from the various stakeholders and pasted them up in priority order.&lt;/p&gt;


	&lt;p&gt;I asked my first pedantic question: &amp;#8220;What is the single most important thing we can work on?  If you had only one story that you knew for sure would be finished this week, which would it be?&amp;#8221;   That led to a nice discussion.&lt;/p&gt;


	&lt;p&gt;When they placed the card on the table, signifying that it was definitely in the build, I asked again if there was any one card anywhere else in the room more important. I asked if that was really the single most important one.&lt;/p&gt;


	&lt;p&gt;When the answer was &amp;#8220;yes, absolutely&amp;#8221; I was ready for my second pedantic question: &amp;#8220;Now that this card is off the board, what is the single most important card left for us to do, if only two stories were guaranteed to be done.&amp;#8221;  Now the pedantry was fully exposed, but the idea had carried.  The team collected all the most important stories and placed them in order on the table.&lt;/p&gt;


	&lt;p&gt;Now I was ready for my next round of pedantry.&lt;/p&gt;</description>
      <pubDate>Thu, 17 Apr 2008 22:00:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:ae6af373-160c-4076-9dd4-1c08c43893b2</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2008/04/17/building-magic-funnels-part-2-pragmatic-pedantry</link>
      <category>Tim's Tepid Torrent</category>
      <category>backlog</category>
      <category>management</category>
      <category>iteration</category>
      <category>planning</category>
      <category>importance</category>
      <category>magic</category>
      <category>funnel</category>
      <category>pedantry</category>
      <category>most</category>
      <category>important</category>
      <category>question</category>
    </item>
    <item>
      <title>Building Magic Funnels, Part 1</title>
      <description>&lt;p&gt;The idea of a magic funnel, as you may remember, is that there is some kind of organizational structure where many ideas and proposals and issues go into the top.  Through some magic, the item that emerges from the bottom of the funnel (to go to the development team) is the single most important thing they could work on next.&lt;/p&gt;


	&lt;p&gt;This is all just backlog management and prioritization, of course. But I think it can be simpler than I&amp;#8217;ve seen it in the past, and that real people working without magic can approximate it.&lt;/p&gt;


	&lt;p&gt;Recently, I&amp;#8217;ve been working to establish another magic funnel. One of the first things we did was to find the person who formerly handed out work to the developers and made him a single point of contact. In our case this is not the scrum master, but is another trusted line-manager type. He has been given a number of people to work with on the Customer side of the house and also works with technical people.&lt;/p&gt;


	&lt;p&gt;We have tried to establish story feeds from all the various stakeholders.  Developers, operations people, technical writers, customers, sales people, marketing people, inside security consultants, and others have been feeding their ideas in to our point-of-contact man.  This part of the funnel is working fairly well.&lt;/p&gt;


	&lt;p&gt;The next thing we have tried to do is to match the feed of work to the rate at which work can be done. This has created a fair amount of back-pressure on the stakeholders (which I believe to be healthy).&lt;/p&gt;


	&lt;p&gt;We have also worked on making the bottom of the funnel narrow, meaning that our guy doesn&amp;#8217;t scatter new work to the team, but feeds it through the scrum master who protects the team&amp;#8217;s productivity and keeps the work flow and tasks visible on the status board. He makes sure that the team is not expected to &amp;#8220;absorb&amp;#8221; changes, but that adding two points of work to the iteration results in two points of unstarted work coming off.  This also creates a healthy back-pressure.&lt;/p&gt;


	&lt;p&gt;As a pun on &amp;#8220;in-flight&amp;#8221;, I named another area of the board &amp;#8220;flying standby&amp;#8221;. This is for stories that aren&amp;#8217;t important enough to swap a story off the board (or for stories that are displaced by more important ones).  If the developers finish more work than they expected, there are stories that can be picked up even though they&amp;#8217;re not a scheduled part of the iteration.  Stakeholders are told that there is no guarantee of these stories being picked up at all in this iteration, but there is some small chance that it could happen if the team discovers that it has overestimated some other stories.&lt;/p&gt;


	&lt;p&gt;The bottom of the funnel is working pretty well.&lt;/p&gt;


	&lt;p&gt;What&amp;#8217;s missing is the &amp;#8220;magic&amp;#8221; bit.&lt;/p&gt;</description>
      <pubDate>Thu, 17 Apr 2008 21:38:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:ad130f5c-1cbc-4c34-8f1a-62a84f2a150b</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2008/04/17/building-magic-funnels-part-1</link>
      <category>Tim's Tepid Torrent</category>
      <category>magic</category>
      <category>funnel</category>
      <category>XP</category>
      <category>agile</category>
      <category>backlog</category>
      <category>management</category>
      <category>negotiation</category>
      <category>planning</category>
    </item>
    <item>
      <title>The Magic Funnel</title>
      <description>&lt;p&gt;At a planning meeting, the developers on the team offer up some amount of work they are able to do. This capacity is termed velocity.  The customer part of the team then selects enough user stories to consume all of the offered capacity. This is simple negotiation, but that hardly tells the story.  What is happening on the customer side is a magic funnel.&lt;/p&gt;


	&lt;p&gt;All kinds of stories come pouring into the customer group.  Some are from actual users in the field who want improvements to existing features. Some suggest entirely new areas of functionality into which the program could expand to good effect.  Some are from the operations group, generally describing ways to make the product more reliable, configurable, or manageable. Some are from the developers who realized that some small changes in code could provide large changed in capability or usability.  Some are from external regulatory bodies, some are from quality control, but for the most part they&amp;#8217;re all good ideas and many have urgency.&lt;/p&gt;


	&lt;p&gt;When the magic funnel is working, we pour all these stories into the top, and the thing that falls out the bottom is the single most important, urgent task we could possibly do.  When it comes time for a new iteration, we fill in our allotted space with whatever comes out the end of the funnel.  Whatever we start doing on Monday, it is the best thing we could possibly start doing.  We know that it is true because it came out of the funnel that way.&lt;/p&gt;


	&lt;p&gt;Sadly, magic funnels are hard to come by.  We approximate them with human beings in multi-disciplinary small groups.  If we leave the funnel purely in the hands of operations, then operational stories are the first to come out.  If we leave the funnel in the hands of marketing people, we tend to do things that are more speculative even though the product users don&amp;#8217;t really need them right now.   If it&amp;#8217;s sales, then whatever will sell more product this month will be the first thing out of the funnel. Give control to customer support and we find ourselves constantly appeasing customers and not moving forward on larger issues. If we leave it to developers, it will tend to turn out those stories that improve the experience of developing the application.  Of course the problem is about conflicting perspectives (all of them right!) with competing desires being processed in fixed time.&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;m not an expert in creating magic funnels, though it would be a very interesting direction to take at this point in my agile coaching career.  I believe that the answer is ultimately to be found in people working together, well-informed people arguing and debating and even trading favors.&lt;/p&gt;


	&lt;p&gt;I think that part of the answer is Covey-style prioritizing  to select the urgent and important (Q1), then the important items that aren&amp;#8217;t urgent (Q2), and holding all unimportant work until there is nothing better to do.&lt;/p&gt;


	&lt;p&gt;Importance in this case relates to how much the change will affect the future of the product and the company.  This is not just a matter of closing a contract or soothing an angry customer.  It may be that the future is larger and brighter than our immediate concerns.   Immediacy is &#8220;urgency&#8221;, but the leverage to create a more greater future is &#8220;importance&#8221;.  I had to read Covey&amp;#8217;s &lt;i&gt;First Things First&lt;/i&gt; several times to really understand the difference, as may the kind reader.  But I did manage to absorb the fact that until you know what you want your future to be, you don&amp;#8217;t know what is important.&lt;/p&gt;


	&lt;p&gt;But imagine how great it will be when you have established your magic funnel, and the work being assigned to each iteration really is the most important and valuable thing that you could do next. Imagine what it would be like if you really were building the future you would like to live in.&lt;/p&gt;</description>
      <pubDate>Wed, 09 Apr 2008 13:18:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:baedf2ab-c088-43c0-bebc-3dc2cf9536cc</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2008/04/09/the-magic-funnel</link>
      <category>Tim's Tepid Torrent</category>
      <category>planning</category>
      <category>funnel</category>
      <category>coordination</category>
      <category>cooperation</category>
      <category>importance</category>
      <category>urgency</category>
      <category>covey</category>
    </item>
    <item>
      <title>Clean Code.  Whew!</title>
      <description>&lt;p&gt;I&amp;#8217;ve been working on this book for several years now.  After a flurry of effort (you might have noticed I&amp;#8217;ve been quiet lately) I&amp;#8217;m very pleased to say that I&amp;#8217;m done with the writing and am preparing the manuscript for production. See &lt;a href="http://www.pearsonhighered.com/educator/academic/product/1,3110,0132350882,00.html"&gt;The Prentice Hall Listing&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://vig-fp.prenhall.com/bigcovers/0132350882.jpg" alt="" /&gt;&lt;/p&gt;


&lt;pre&gt;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
&lt;/pre&gt;</description>
      <pubDate>Tue, 08 Apr 2008 00:10:16 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:0280362f-4830-42b9-84db-edaa724b41b1</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2008/04/08/clean-code-whew</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Clean Code</category>
    </item>
    <item>
      <title>Your Attitude is Affecting Other Departments</title>
      <description>&lt;p&gt;The &lt;span class="caps"&gt;CIO&lt;/span&gt; looked into the eyes of his agile development staff last Friday. &amp;#8220;Your attitude is affecting other departments&amp;#8221; he said.&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;ve heard a lot of department-level speeches start this way, and in relatively small companies it is not unheard-of for a C-level manager to address attitudes of development teams.&lt;/p&gt;


	&lt;p&gt;The group has been working to stabilize and improve a product that was developed by a tiger team of outsider contractors and handed over to the in-house team post-facto. The developers had to overcome many obstacles to come up to speed on the code, to learn the new programming languages and tools, and to try to keep the feature set moving forward.  None of them had been involved in the original design, but it was now their product, and its problems were their problems.&lt;/p&gt;


	&lt;p&gt;At the time of this meeting, I was one part of a coaching team which had introduced a great many changes.   We were trying to help the organization to build a &amp;#8220;whole team&amp;#8221; mentality that encompassed documentation, security, systems administration, QA, customer representatives, and developers alike.  We&amp;#8217;d attacked the problem of matrix management.  We reorganized the seating floorplan.  I think at some point we&amp;#8217;d been an inconvenience to just about everybody. The developers were in the middle of their second two-week iteration.&lt;/p&gt;


	&lt;p&gt;On this occasion, the team was in the midst of a recurring production difficulty, and had been gathered into the &lt;span class="caps"&gt;CIO&lt;/span&gt;&amp;#8217;s office to work through a top-20 list of problems to solve.&lt;/p&gt;


	&lt;p&gt;&amp;#8220;Your attitude has been affecting other departments&amp;#8221;, he said. &amp;#8220;And I want to thank you for it.&amp;#8221;&lt;/p&gt;</description>
      <pubDate>Sat, 05 Apr 2008 21:17:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:293e08d9-74d8-475a-b2aa-a66c2c1a1436</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2008/04/05/your-attitude-is-affecting-other-departments</link>
      <category>Tim's Tepid Torrent</category>
      <category>Schuchert&#8217;s Scattered Synapses </category>
      <category>XP</category>
      <category>transitions</category>
      <category>attitude</category>
    </item>
    <item>
      <title>Velocity is Just Capacity</title>
      <description>&lt;p&gt;I don&amp;#8217;t know why, but somehow &lt;i&gt;velocity&lt;/i&gt; as a term really bothers me.&lt;/p&gt;


	&lt;p&gt;We always want higher velocity, and that&amp;#8217;s a good thing.  But with the term velocity, we think that we can create velocity with greater pressure (thrust?).  Doesn&amp;#8217;t it make sense that with a really hard push you can get greater velocity?&lt;/p&gt;


	&lt;p&gt;I guess I get hung up on words.  Essentially, &amp;#8220;velocity&amp;#8221; is fine.  It is the rate at which we&amp;#8217;re &amp;#8220;burning through&amp;#8221; our stories.  We use &amp;#8220;yesterday&amp;#8217;s weather&amp;#8221; to set our level, and we are always seeking any sustainable way to increase our velocity.  Why would we produce only 12 points when we could produce 20?  As motivated developers, we aren&amp;#8217;t yearning to accomplish less. But somehow this doesn&amp;#8217;t tell the right story.&lt;/p&gt;


	&lt;p&gt;When our velocity is decreased, it always seems like a tragedy.  We have all felt it when our 23-point iteration is followed by a 21-point iteration.  We can justify it a lot of different ways, but it always feels tragic.  Worse, hitting any kind of plateau seems frustrating.&lt;/p&gt;


	&lt;p&gt;You increase &lt;i&gt;velocity&lt;/i&gt; by pushing harder. If you push harder, and the numbers come up, then you&amp;#8217;ve successfully increased the velocity and that seems to be intuitively all there is to it.&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;ve reflected about this for a few years before I realized that I really like the term &lt;i&gt;capacity&lt;/i&gt; much more.  It is also accurately describing the rate at which we can truly complete stories.  Since we use yesterday&amp;#8217;s weather, we can even use the term &amp;#8220;proven capacity&amp;#8221; to describe that we&amp;#8217;ve demonstrated the speed. But it also says some other things.&lt;/p&gt;


	&lt;p&gt;Intuitively it seems that we know that you don&amp;#8217;t push your people beyond their capacity to get work done.  Instead, you want to increase their capacity.  When we talk about longer hours, it is still obvious that working people harder diminishes their capacity.  Instead, we want to be working at capacity on the one hand, and increasing our capacity on the other.&lt;/p&gt;


	&lt;p&gt;Increasing the capacity sounds like the right problem.  To improve capacity, you want fresh workers working hard, pairing and communicating, building and/or using better tools (or using tools more capably), using more powerful hardware, learning, and performing the kind of housekeeping that keeps the team productive. Life balance enters into it.  Sufficient team size enters into it so you&amp;#8217;re not so small you&amp;#8217;re short-handed, yet not so plentiful you trip over each other.&lt;/p&gt;


	&lt;p&gt;I don&amp;#8217;t suppose that anyone is going to rename standardized eXtreme Programming terms like &amp;#8220;velocity&amp;#8221; just because some guy from Indiana says to, but I wonder if maybe we can&amp;#8217;t rephrase the problem in such a way that we are intuitively driven toward more reasonable solutions.  Maybe we should explain that velocity is just capacity, and then work from that point onward.&lt;/p&gt;</description>
      <pubDate>Wed, 02 Apr 2008 19:23:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:e325ba21-c7f5-4973-a85f-517ba5c697e1</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2008/04/02/velocity-is-just-capacity</link>
      <category>Tim's Tepid Torrent</category>
      <category>Velocity</category>
      <category>capacity</category>
      <category>agility</category>
      <category>XP</category>
      <category>balance</category>
      <category>humanity</category>
    </item>
    <item>
      <title>Musing over Mutation</title>
      <description>&lt;p&gt;I read a mailing list entry in which one fellow (who? I can&amp;#8217;t remember!) asked another &lt;i&gt;&amp;#8220;Do you want to get better at what you&amp;#8217;re doing, or find a better way to get the results you want?&amp;#8221;&lt;/i&gt;&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;m a sucker for a good one-liner.  That one had me thinking, and as I&amp;#8217;ve had other conversations about innovation, I keep coming back to that line.&lt;/p&gt;


	&lt;p&gt;In our Agile practices, we work really hard for a week or two, and then hold a retrospective.  The purpose of the retrospective is to find ways to work more effectively for the next two weeks. As we develop better software, we also evolve a better team.  We use &amp;#8220;tricks&amp;#8221; such as tracking our velocity and recording blockages on our &amp;#8216;waste snake&amp;#8217; to provide data for our decisions, and we use gut feel to evaluate those things that feel like collateral effort to us.&lt;/p&gt;


	&lt;p&gt;If the practice works, we will see incremental improvement in the team.  We will develop ways of avoiding special variations, and we will learn to accept our normal variations. It will make us better at the way we do things now.&lt;/p&gt;


	&lt;p&gt;XP didn&amp;#8217;t come from a series of incremental improvements to the waterfall technology.  I wasn&amp;#8217;t there when it happened, but it seems that they took on an change in axioms.  They didn&amp;#8217;t strengthen the contracts between groups, but pulled all the decision-makers onto the same team.  They didn&amp;#8217;t find more careful ways to examine the code they were changing, but rather decided to lean radically on volumes of tests.  They didn&amp;#8217;t build practices to improve their anticipatory design, they decided instead not to anticipate at all and simplify their design to allow future change. At the time, this was radical stuff.&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;m sure there have been many other less-successful process mutations, but there is no evolution without mutation.&lt;/p&gt;


	&lt;p&gt;The man behind the iPod, iPhone, and MacBookPro has had some less-successful product ideas, too.  Some exciting high-concept products didn&amp;#8217;t make it in the wild. But then some new ideas become category killers.&lt;/p&gt;


	&lt;p&gt;How do we learn to make the axiomatic changes that lead us to radically better ways to get what we want?&lt;/p&gt;</description>
      <pubDate>Thu, 20 Mar 2008 22:25:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:aa6972db-849e-4c91-8a47-a2568b8173af</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2008/03/20/musing-over-mutation</link>
      <category>Tim's Tepid Torrent</category>
    </item>
    <item>
      <title>TDD on Three Index Cards</title>
      <description>&lt;p&gt;I had the opportunity to talk to a fellow who missed part of a class on &lt;span class="caps"&gt;TDD&lt;/span&gt;. I told him that I could give him a 15-minute overview, and give him all the essentials of &lt;span class="caps"&gt;TDD&lt;/span&gt; on three index cards.&lt;/p&gt;


	&lt;p&gt;Yes, I know that volumes have been written about &lt;span class="caps"&gt;TDD&lt;/span&gt; and &lt;span class="caps"&gt;BDD&lt;/span&gt;, and that it&amp;#8217;s a large topic with many many branches of application, but I didn&amp;#8217;t have time for that. I had time for three index cards.  I figure that an index card is a token, and it represents a conversation, and that one can always dig deeper later.&lt;/p&gt;


	&lt;p&gt;They looked more or less like this:&lt;/p&gt;


&lt;hr&gt;
Card 1: Uncle Bob&amp;#8217;s Three Laws (Object Mentor)
&lt;ol&gt;
&lt;li&gt;Write no production code except to pass a failing test.&lt;/li&gt;
&lt;li&gt;Write only enough of a test to demonstrate a failure.&lt;/li&gt;
&lt;li&gt;Write only enough production code to pass the test.&lt;/li&gt;
&lt;/ol&gt;

&lt;hr&gt;
Card 2: &lt;span class="caps"&gt;FIRST&lt;/span&gt; Principles (Brett and Tim at Object Mentor)
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;F&lt;/i&gt;ast: Mind-numbingly fast, as in hundreds or thousands per second.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;I&lt;/i&gt;solated: The test isolates a fault clearly.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;R&lt;/i&gt;epeatable: I can run it repeatedly and it will pass or fail the same way each time.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;S&lt;/i&gt;elf-verifying: The test is unambiguously pass-fail.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;T&lt;/i&gt;imely: Produced in lockstep with tiny code changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;hr&gt;
Card 3: Flow (using the famous three-node circle diagram) &amp;#8211; origin unknown.
&lt;ul&gt;
&lt;li&gt;Red: test fails&lt;/li&gt;
&lt;li&gt;Green: test passes&lt;/li&gt;
&lt;li&gt;Refactor: clean code and tests&lt;/li&gt;
&lt;/ul&gt;

	&lt;p&gt;Sure there is plenty more, but I didn&amp;#8217;t know how I could provide significantly less. As is, I&amp;#8217;m pretty happy with the exercise. Now I am wondering if I couldn&amp;#8217;t produce most of the important information I wish to convey as a series of index cards. Would that be cool or what?&lt;/p&gt;</description>
      <pubDate>Thu, 06 Mar 2008 19:39:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:a7002e7d-5f30-481f-8792-20f01b2e731f</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2008/03/06/tdd-on-three-index-cards</link>
      <category>Tim's Tepid Torrent</category>
      <category>testing</category>
      <category>TDD</category>
      <category>three</category>
      <category>index</category>
      <category>cards</category>
      <category>reminders</category>
      <category>simplified</category>
    </item>
    <item>
      <title>Clues For Reading New Code</title>
      <description>&lt;p&gt;Okay, somebody just handed you a new chunk of code to work on.  Your first though on opening the file is &amp;#8220;Why, dear God, why?&amp;#8221;.  How do you get a handle on this masterpiece of clever programming?  Let&amp;#8217;s look for a few clues.&lt;/p&gt;


	&lt;p&gt;Where to start?&lt;/p&gt;


&lt;h2&gt;Documents&lt;/h2&gt;

	&lt;p&gt;Why not look at the documentation? &amp;lt;&lt;strong&gt;laughs&lt;/strong&gt;&amp;gt; Just kidding.  You know there&amp;#8217;s no documentation, and it&amp;#8217;s probably not useful.&lt;/p&gt;


&lt;h2&gt;People and Interactions&lt;/h2&gt;

	&lt;p&gt;You need a partner who is familiar with the code. Having a guide is better than having a map. Not only will you know where to go, but you&amp;#8217;ll know &amp;#8217;&amp;#8217;how&amp;#8217;&amp;#8217; to go and where not to step. Other people are a wonderful resource. Just don&amp;#8217;t settle for someone doing the work in front of you&amp;#8230; the goal is to learn as much as to do.&lt;/p&gt;


&lt;h2&gt;No, really, documents!&lt;/h2&gt;

	&lt;p&gt;&lt;span class="caps"&gt;OTOH&lt;/span&gt;, if you have somethng in the way of a summary or architectural overview, that might help. I&amp;#8217;d read the abstract and look at the pictures.  We&amp;#8217;re after big-picture, so &lt;strong&gt;read&lt;/strong&gt; it only, don&amp;#8217;t &lt;strong&gt;trust&lt;/strong&gt; it. Documents are seldom accurate, and seldom for long.  It might be good preparation for your partner&amp;#8217;s visit.&lt;/p&gt;


&lt;h2&gt;Use The Tests, Luke&lt;/h2&gt;

	&lt;p&gt;Do you have tests?  If you are in a test-driven shop, looking at unit tests is a good idea. If they&amp;#8217;re written well, they are specifications (by example) of the system.  If they&amp;#8217;re written poorly, you know where to start your work at least. Your partner could do a great service by helping clean up the code instead of explaining it.&lt;/p&gt;


	&lt;p&gt;No tests? Uh, oh.  No tests &lt;strong&gt;and&lt;/strong&gt; no doc?  Now you&amp;#8217;re in trouble.&lt;/p&gt;


&lt;h2&gt;Scan the File Space&lt;/h2&gt;

	&lt;p&gt;Are the classes well-named? Do you know where to begin working? If you can find code by looking at file names then you&amp;#8217;ve got the handle you need.  Your partner can help improve file naming if you find the code you&amp;#8217;ve been handed is in ill-named files.&lt;/p&gt;


	&lt;p&gt;So you&amp;#8217;re in a file, you have a mission.  Either you have tests, or you&amp;#8217;re ready to write some.&lt;/p&gt;


&lt;h2&gt;Sense Of Smell&lt;/h2&gt;

	&lt;p&gt;What if the code is still not obvious?  You have one more resource before you have to print out the listing and break out the markers to reverse-engineer your way out of code hell.  You have your nose and your refactoring editor.  You can use refactorings such as &amp;#8216;rename&amp;#8217;, &amp;#8216;extract method&amp;#8217;, and &amp;#8216;introduce variable&amp;#8217; to clarify an existing method. You can spot duplication and eliminate it.  Maybe you can bring it to a point of clarity, and then you will know&lt;/p&gt;


&lt;h2&gt;Deep Code Spelunking&lt;/h2&gt;

	&lt;p&gt;It&amp;#8217;s time to pour a really big cup of tea, get some food, take a couple of preemptive aspirin, and make sure your printer has paper.&lt;/p&gt;


	&lt;p&gt;Sometimes, you will have to reverse-engineer some of the code you were handed. Your only hope may be to rebuild it from the inside-out.&lt;/p&gt;


	&lt;p&gt;You might want to either copy the code to a scratch space to do this.  Maybe you want to branch the project in version control.  You want to be free to dig in an learn this the hard way, and make it better as you emerge from the depths.&lt;/p&gt;


	&lt;p&gt;You still can/must use refactoring tricks to capture the knowledge you gain, but you may need to take the code off line. And look for new partners.&lt;/p&gt;</description>
      <pubDate>Wed, 05 Mar 2008 19:27:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:5a6bcbe7-686d-4cf3-8b45-6eb95e45c65e</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2008/03/05/clues-for-reading-new-code</link>
      <category>Tim's Tepid Torrent</category>
    </item>
    <item>
      <title>Turn Back The Dial</title>
      <description>&lt;p&gt;The coolest thing just happened! I broke the glass cover off of my watch.  At first I thought it was awful, but then I realized that I could turn the hands.&lt;/p&gt;


	&lt;p&gt;Imagine my joy as I realized that I could make it 11:30 again, and go enjoy another lunch.  Meeting at 3:30? No problem, just turn the hour hand up to 6:00 and go home! I can sleep as long as I want as long as I turn it back to 8:00 when I get to the office. All my work estimates are now &amp;#8220;five minutes&amp;#8221;, and I complete them every time.&lt;/p&gt;


	&lt;p&gt;My coworkers have no idea the awesome power that I&amp;#8217;ve gained with this one happy accident.  They ask &amp;#8220;what time is it?&amp;#8221; and I say &amp;#8220;what time would you like it to be.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;Of course the above is a total fabrication. Pretending it&amp;#8217;s 6:00pm when it&amp;#8217;s 8:00am isn&amp;#8217;t going to do anybody any good at all, and is likely to make a mess of things for me.&lt;/p&gt;


	&lt;p&gt;But people still try to mandate velocity.&lt;/p&gt;</description>
      <pubDate>Wed, 05 Mar 2008 19:16:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:3dc25ff8-864f-4286-bafb-0fa71c9895cf</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2008/03/05/turn-back-the-dial</link>
      <category>Tim's Tepid Torrent</category>
      <category>Velocity</category>
      <category>agile</category>
      <category>measurement</category>
      <category>metrics</category>
    </item>
    <item>
      <title>Discipline often directed at the symptom, not the cause</title>
      <description>Have you ever heard something like?
&lt;blockquote&gt;
If the developer just had a little discipline and did it the right way, we would not have this problem.
&lt;/blockquote&gt;

	&lt;p&gt;That&amp;#8217;s often a sign that the way something is getting done is hard to do, not supported well or just plain works against against you.&lt;/p&gt;


	&lt;p&gt;Here&amp;#8217;s an example I recently came across&amp;#8230;&lt;/p&gt;


In a particular organization, part of their build system produces &amp;#8220;project&amp;#8221; information to allow for development on multiple platforms and with different C++ compilers. That&amp;#8217;s excellent, it sounds like a great tool. For a developer to get started, he/she:
	&lt;ul&gt;
	&lt;li&gt;Checks out the source tree&lt;/li&gt;
		&lt;li&gt;Runs the script&lt;/li&gt;
		&lt;li&gt;Starts working&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;So far, everything is great and this part of their build system is essential to their environment &amp;#8211; and good in general.&lt;/p&gt;


	&lt;p&gt;Here&amp;#8217;s the next part&amp;#8230;&lt;/p&gt;


To add a file to the system you have to:
	&lt;ul&gt;
	&lt;li&gt;Create the file&lt;/li&gt;
		&lt;li&gt;Update project information&lt;/li&gt;
		&lt;li&gt;Rerun the script to regenerate project information.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;When I asked how long it takes to add a class, I was told about 5 minutes. So if I want to add a header file and source file, it takes 5 minutes. That&amp;#8217;s a big problem. Why?&lt;/p&gt;


	&lt;p&gt;After this discussion, I heard one of the senior people lamenting that a developer had put another class in an existing file rather than creating a second file. He said something like &amp;#8220;If the developer just had discipline, he&amp;#8217;d to the right thing.&amp;#8221; Those darn developers.&lt;/p&gt;


	&lt;p&gt;It takes 5 minutes to add a few files to a build. That does not include build time. That&amp;#8217;s just the time to configure the build information.&lt;/p&gt;


	&lt;p&gt;Does 5 minutes seem like very much time?&lt;/p&gt;


Here are a few more thins I noticed(before I knew about the build system):
	&lt;ul&gt;
	&lt;li&gt;Some header files defined multiple classes&lt;/li&gt;
		&lt;li&gt;Some source files had the methods for those multiple classes&lt;/li&gt;
		&lt;li&gt;Some of the header files had names that did not match any of the classes defined in that header file&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;So is this a problem?&lt;/p&gt;


Here&amp;#8217;s an important rule from Jerry Weinberg:
&lt;blockquote&gt;
Nothing + Nothing + Nothing eventually equals something
&lt;/blockquote&gt;

	&lt;p&gt;5 minutes may not seem like a lot of time, and if it were isolated, then it&amp;#8217;s probably not a problem. On the other hand, when you multiply it by a team and time, you end up with big problems.&lt;/p&gt;


	&lt;p&gt;Imagine, you need to use class X. Its header file is actually named Q.h and by the way, classes &lt;span class="caps"&gt;T U&lt;/span&gt; and L are defined in that file &amp;#8211; none of which you want to know about.&lt;/p&gt;


	&lt;p&gt;So your class now has phantom dependencies on T, U and L. Also, how did you find the right header file? A quick search (time wasted). Someone changed U, so you end up having to recompile even though you don&amp;#8217;t care about nor use (wasted time). I&amp;#8217;m sure you can come up with a few things on your own.&lt;/p&gt;


	&lt;p&gt;So what do you do about it?&lt;/p&gt;


OK, first, do not throw the baby out with the bathwater. The original tool solved an important problem. But the first rule of problem solving, again from Jerry Weinberg:
&lt;blockquote&gt;
Every solution introduces problems
&lt;/blockquote&gt;

The problems include (but are not limited to):
	&lt;ul&gt;
	&lt;li&gt;Time wasting adding files&lt;/li&gt;
		&lt;li&gt;It requires discipline to add new files, so it doesn&amp;#8217;t always happen&lt;/li&gt;
		&lt;li&gt;A name is wrong, but it&amp;#8217;s a pain to update the build configuration, so it doesn&amp;#8217;t happen &amp;#8211; not all the time, just every so often&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Little by little, things get a bit more chaotic.&lt;/p&gt;


	&lt;p&gt;So now that we&amp;#8217;ve observed a problem &amp;#8211; some waste, we need to find a way to remove the need to update the build information and regenerate to even work.&lt;/p&gt;


I don&amp;#8217;t know what&amp;#8217;s going to happen with this group. They are hoping to perform some refactorings. Their system has quite a bit of coupling. One thing we can do to reduce coupling is:
	&lt;ul&gt;
	&lt;li&gt;Introduce interfaces&lt;/li&gt;
		&lt;li&gt;Inversion of Control&lt;/li&gt;
		&lt;li&gt;Identify seams and use some of Feather&amp;#8217;s stuff to introduce them&lt;/li&gt;
		&lt;li&gt;Etc., the usual stuff to introduce seams and break dependencies.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;But many of the refactorings they&amp;#8217;ll want to use will involve creating new classes. Since that takes a little bit longer, it will slow everything down &amp;#8211; or seem so daunting, it might not happen at all.&lt;/p&gt;


	&lt;p&gt;Here&amp;#8217;s a personal example. A few years ago, I built the security system for one applications and then a suite of applications with single sign on. When I initially introduced the security system, many people wrote tests that would forget to log out, causing problems in both the real system and the simulator.&lt;/p&gt;


	&lt;p&gt;I kept grumbling. I though, &amp;#8220;if people would just do it right, there wouldn&amp;#8217;t be a problem.&amp;#8221; If they just had a little discipline.&lt;/p&gt;


Independent of whose fault it was, it ended up being my problem &amp;#8211; and, quite frankly, it was my fault as well. The solution was actually pretty easy:
	&lt;ul&gt;
	&lt;li&gt;Create an abstract test base&lt;/li&gt;
		&lt;li&gt;Change tests to use it&lt;/li&gt;
		&lt;li&gt;In the setup, the base logged in&lt;/li&gt;
		&lt;li&gt;In the teardown, the base logged out&lt;/li&gt;
	&lt;/ul&gt;


You might think, &amp;#8220;Duh!&amp;#8221; and in retrospect, so did I. But that few minutes of effort:
	&lt;ul&gt;
	&lt;li&gt;Reduced code duplication&lt;/li&gt;
		&lt;li&gt;Increased the stability of the tests&lt;/li&gt;
		&lt;li&gt;Made it hard for people to mess up (so long as they used the correct test base &amp;#8211; and I updated all of the tests that needed it, so going forward, people had correct examples upon which to base their work).&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Ultimately, this removed a lot of my wasted time&lt;/p&gt;


	&lt;p&gt;Detecting waste is the first thing. Until you know it is a problem, you cannot do anything about it.&lt;/p&gt;


So, the next time you think something like:
	&lt;ul&gt;
	&lt;li&gt;If that person was only following &amp;#8220;the rules&amp;#8221; &lt;/li&gt;
		&lt;li&gt;If he/she just had a little more discipline&lt;/li&gt;
		&lt;li&gt;Stupid user, they should not have done that&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Ask yourself if it&amp;#8217;s possible that those statements are directed at the symptom, not the problem.&lt;/p&gt;</description>
      <pubDate>Sat, 01 Mar 2008 16:18:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:83bf0f26-2d34-4f54-bc32-b4487c1224ac</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2008/03/01/discipline-often-directed-at-the-symptom-not-the-cause</link>
      <category>Schuchert&#8217;s Scattered Synapses </category>
      <category>lean</category>
      <category>waste</category>
      <category>refactoring</category>
    </item>
    <item>
      <title>Writing Java Aspects ... with JRuby and Aquarium!</title>
      <description>&lt;p&gt;&lt;a href="http://aquarium.rubyforge.org"&gt;Aquarium&lt;/a&gt; V0.4.0, my &lt;span class="caps"&gt;AOP&lt;/span&gt; library for Ruby, now supports &lt;a href="http://jruby.codehaus.org/"&gt;JRuby&lt;/a&gt;. Not only do the regular &amp;#8220;pure Ruby&amp;#8221; Aquarium specs run reliably under JRuby (V1.1RC2), but you can now write aspects for Java types with Aquarium!&lt;/p&gt;


	&lt;p&gt;There are some &lt;strong&gt;important&lt;/strong&gt; limitations, though. Cartographers of old would mark dangerous or unknown territory on their maps with &lt;a href="http://en.wikipedia.org/wiki/Here_be_dragons"&gt;&lt;em&gt;hic sunt dracones&lt;/em&gt;&lt;/a&gt; (&amp;#8220;here be dragons&amp;#8221;), a reference to the old practice of adorning maps with serpents around the edges.&lt;/p&gt;


	&lt;p&gt;This is true of Aqurium + Java types in JRuby, too, at least for now.&lt;/p&gt;


	&lt;p&gt;Aquarium uses Ruby&amp;#8217;s metaprogramming &lt;span class="caps"&gt;API&lt;/span&gt; extensively and the JRuby team has done some pretty sophisticated work to integrate Java types with Ruby. Hence, it&amp;#8217;s not too surprising there are some &lt;em&gt;gotchas&lt;/em&gt;. Hopefully, workarounds will be possible for all of them.&lt;/p&gt;


	&lt;p&gt;The details are discussed on the &lt;a href="http://aquarium.rubyforge.org/jruby.htm"&gt;JRuby page&lt;/a&gt;, the &lt;a href="http://aquarium.rubyforge.org/rdoc/files/README.html"&gt;&lt;span class="caps"&gt;README&lt;/span&gt;&lt;/a&gt; on the Aquarium site, and of course the &amp;#8220;specs&amp;#8221; in the distribution&amp;#8217;s &lt;code&gt;jruby/spec&lt;/code&gt; directory. I&amp;#8217;ll summarize them here, after discussing the pros and cons of Aquarium &lt;em&gt;vs.&lt;/em&gt; the venerable &lt;a href="http://www.aspectj.org"&gt;AspectJ&lt;/a&gt; and showing you an example of using Aquarium for Java.&lt;/p&gt;


	&lt;p&gt;Briefly, Aquarium&amp;#8217;s advantages over AspectJ are these:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;You can add &lt;strong&gt;and&lt;/strong&gt; remove advice dynamically at runtime. You can&amp;#8217;t remove AspectJ advice.&lt;/li&gt;
		&lt;li&gt;You can advise &lt;span class="caps"&gt;JDK&lt;/span&gt; types easily with Aquarium. AspectJ won&amp;#8217;t do this by default, but this is really more of a legacy licensing issue than a real technical limitation.&lt;/li&gt;
		&lt;li&gt;You can advise individual &lt;em&gt;objects&lt;/em&gt;, not just types.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;Aquarium&amp;#8217;s disadvantages compared to AspectJ include:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Aquarium will be slower than using AspectJ (although this has not been studied in depth yet).&lt;/li&gt;
		&lt;li&gt;Aquarium&amp;#8217;s pointcut language is not as full-featured as AspectJ&amp;#8217;s.&lt;/li&gt;
		&lt;li&gt;There are the bugs and limitations I mentioned above in this initial V0.4.0 release, which I&amp;#8217;ll elaborate shortly.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;Here is an example of adding tracing calls to a method &lt;code&gt;doIt&lt;/code&gt; in all classes that implement the Java interface &lt;code&gt;com.foo.Work&lt;/code&gt;.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
Aspect.new :before, :calls_to =&amp;gt; [:doIt, :do_it], :in_types_and_descendents =&amp;gt; Java::com.foo.Work do |jp, obj, *args|
  log "Entering: #{jp.target_type.name}##{jp.method_name}: object = #{object}, args = #{args.inspect}" 
end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;There are two important points to notice in this example:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;You can choose to refer to the method as &lt;code&gt;do_it&lt;/code&gt; (Ruby style) or &lt;code&gt;doIt&lt;/code&gt;, but these variants are effectively treated as &lt;strong&gt;separate&lt;/strong&gt; methods; advice on one will not affect invocations of the other. So, if you want to be sure to catch &lt;strong&gt;all&lt;/strong&gt; invocations, use &lt;strong&gt;both&lt;/strong&gt; forms. There is a bug (18326) that happens in certain conditions if you use just the Java naming convention.&lt;/li&gt;
		&lt;li&gt;If the type is an interface, you must use &lt;code&gt;:types_and_descendents&lt;/code&gt; (or one of the supported variants on the word &lt;code&gt;types&lt;/code&gt;...). Since interfaces don&amp;#8217;t have method implementations, you will match no join points unless you use the &lt;code&gt;_and_descendents&lt;/code&gt; clause. (By default, Aquarium warns you when no join points are matched by an aspect.) However, there is a bug (18325) with this approach if Java types are subtyped in Ruby.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;h4&gt;Limitations and Bugs&lt;/h4&gt;


	&lt;p&gt;Okay, here&amp;#8217;s the &amp;#8220;fine print&amp;#8221;...&lt;/p&gt;


	&lt;p&gt;In this (V0.4.0) release, there are some important limitations.&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Aquarium advice on a method in a Java type will &lt;strong&gt;only&lt;/strong&gt; be invoked when the method is called &lt;strong&gt;directly&lt;/strong&gt; from Ruby.&lt;/li&gt;
		&lt;li&gt;To have the advice invoked when the method is called from &lt;strong&gt;either&lt;/strong&gt; Java &lt;strong&gt;or&lt;/strong&gt; Ruby, it is necessary to create a Ruby subclass of the Java type and override the method(s) you want to advise. These overrides can just call &lt;code&gt;super&lt;/code&gt;. Note that it will also be necessary for &lt;strong&gt;instances&lt;/strong&gt; of this Ruby type to be used throughout the application, in both the Java and Ruby code. So, you&amp;#8217;ll have to instantiate the object in your Ruby code.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;Yea, this isn&amp;#8217;t so great, but if you&amp;#8217;re motivated&amp;#8230; ;)&lt;/p&gt;


	&lt;p&gt;There are also a few outstanding Aquarium bugs (which could actually be JRuby bugs or quirks of the Aquarium-JRuby &amp;#8220;interaction&amp;#8221;; I&amp;#8217;m not yet sure which).&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;&lt;strong&gt;Bug #18325&lt;/strong&gt;: If you have Ruby subclasses of Java types &lt;strong&gt;and&lt;/strong&gt; you advise a Java method in the hierarchy using &lt;code&gt;:types_and_descendents =&amp;gt; MyJavaBaseClassOrInterface&lt;/code&gt; &lt;strong&gt;and&lt;/strong&gt; you call unadvise on the aspect, the advice &amp;#8220;infrastructure&amp;#8221; is not correctly removed from the Ruby types. Workaround: Either don&amp;#8217;t &amp;#8220;unadvise&amp;#8221; such Ruby types or only advise methods in such Ruby types where the method is explicitly overridden in the Ruby class. (The spec and the &lt;a href="http://rubyforge.org/tracker/index.php?func=detail&amp;#38;aid=18325&amp;#38;group_id=4281&amp;#38;atid=16494"&gt;Rubyforge bug report&lt;/a&gt; provide examples.)&lt;/li&gt;
		&lt;li&gt;&lt;strong&gt;Bug #18326&lt;/strong&gt;: Normally, you can use either Java- or Ruby-style method names (&lt;em&gt;e.g.,&lt;/em&gt; &lt;code&gt;doSomething&lt;/code&gt; vs. &lt;code&gt;do_something&lt;/code&gt;), for Java types. However, if you write an aspect using the Java-style for a method name and a Ruby subclass of the Java type where the method is actually defined (i.e., the Ruby class doesn&amp;#8217;t override the method), Aquarium acts like the JoinPoint is advised, but the advice is never actually called. Workaround: Use the Ruby-style name in this scenario.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;So, there is still some work to do, but it&amp;#8217;s promising that you can use an aspect framework in one language with another. A primary goal of Aquarium is to make it easy to write simple aspects. My hope is that people who might find AspectJ daunting will still give Aquarium a try.&lt;/p&gt;</description>
      <pubDate>Mon, 25 Feb 2008 22:10:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:4645fddb-ba4f-4e8d-8283-7732439d017f</guid>
      <author>Dean Wampler</author>
      <link>http://blog.objectmentor.com/articles/2008/02/25/writing-java-aspects-with-jruby-and-aquarium</link>
      <category>JRuby</category>
      <category>aquarium</category>
      <category>Java</category>
      <category>aspects</category>
      <category>AOP</category>
      <category>AOSD</category>
    </item>
    <item>
      <title>The Quality of TDD</title>
      <description>&lt;p&gt;Kieth Braithwaite has made an interesting observation &lt;a href="http://peripateticaxiom.blogspot.com/2006/05/complexity-and-test-first-0.html"&gt;here.&lt;/a&gt;  The basic idea is that code that has been written with &lt;span class="caps"&gt;TDD&lt;/span&gt; has a lower Cyclomatic Complexity per function compared to code that has not been written with &lt;span class="caps"&gt;TDD&lt;/span&gt;.  If this is true then it could imply lower defects because of &lt;a href="http://www.enerjy.com/blog/?p=241"&gt;this.&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Kieth&amp;#8217;s metric takes in the code for an entire project and boils it down to a single number.  His hypothesis is that a system written with &lt;span class="caps"&gt;TDD&lt;/span&gt; will always measure above a certain threshold, indicating very low CC; whereas systems written without &lt;span class="caps"&gt;TDD&lt;/span&gt; may or may not measure above that threshold.&lt;/p&gt;


	&lt;p&gt;Kieth has built a tool that you can get &lt;a href="http://www.keithbraithwaite.demon.co.uk/professional/software/measure/measure0.1.zip"&gt;here&lt;/a&gt; that will generate this metric for most java projects.  He and others have used this tool to measure many different systems.  So far the hypothesis seems to hold water.&lt;/p&gt;


	&lt;p&gt;The metric can&amp;#8217;t tell you if &lt;span class="caps"&gt;TDD&lt;/span&gt; was used; but it might just be able to tell you that it &lt;em&gt;wasn&amp;#8217;t used&lt;/em&gt;.&lt;/p&gt;</description>
      <pubDate>Sat, 16 Feb 2008 20:23:44 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:f69b083c-7868-4d59-84e6-b9185d82f7b8</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2008/02/16/the-quality-of-tdd</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Agile Methods</category>
    </item>
    <item>
      <title>Crash Test Dummies</title>
      <description>&lt;p&gt;Even the most dedicated TDDer would not write a unit test for &amp;#8220;Hello, world.&amp;#8221;  Even the most fervent FitNesse wonk would not write an acceptance test for a program that prints the first 10 squares.  This implies that there are programs too simple for &lt;span class="caps"&gt;TDD&lt;/span&gt;.  So where do we draw the line?&lt;/p&gt;


	&lt;h2&gt;Accellerating towards a brick wall.&lt;/h2&gt;


	&lt;p&gt;The issue, of course, is speed.  For projects that are too simple to require unit tests, or acceptance tests, you can go a lot faster by not writing them.  I can write HelloWorld or SquaresOfIntegers in much less than half the time that it would take me to write unit and acceptance tests for those programs.  And I know they work because I can run them and manually validate them almost instantly.&lt;/p&gt;


	&lt;p&gt;For large projects the opposite is true; unit tests and acceptance tests make us go faster.  The increase in speed comes from reduced debugging time and reduced ambiguity.  When programmers follow the three laws of &lt;span class="caps"&gt;TDD&lt;/span&gt;, writing tests and code in a very short cycle, they reduce their debugging time by perhaps as much as 90%.  Code written this way is much easier to understand since the tests act as little code examples.  It is also much easier to change since the suite of tests act as instant fault detection.&lt;/p&gt;


	&lt;p&gt;Acceptance tests act as executable requirements.  When Business Analysts and QA staff write these tests at the beginning of an iteration, they are producing unambiguous requirements.  Programmers cannot help but implement the features as specified, since the tests will fail otherwise.  So there is much less requirements thrashing and rework.&lt;/p&gt;


	&lt;p&gt;The cutoff for unit tests is probably around 10 lines of code.  That is, it is probably faster to write 10 lines of code by writing unit tests first, than to just write the 10 lines and hope for the best.  As an example of this, I recently wrote a dumb stack class.  I found that I had to write the simple unit tests first in order to be sure that I had properly implemented the algorithm.  Writing the stack without tests just left too much room for something to go wrong.&lt;/p&gt;


	&lt;p&gt;Acceptance tests are another matter.  You don&amp;#8217;t really feel the benefit of acceptance tests for projects below a few thousand lines of code.
The problem is that in such projects manual testing is cheap.  The programmers and customers can just run the program for 15 minutes and prove that it works.  Any team caught in a project of this size will immediately feel the drag imposed by writing automated acceptance tests.  They&amp;#8217;ll look at how much they could get done without them.  They&amp;#8217;ll envy the time lost to those tests.  And they may make an obvious, but possibly catastrophic choice.&lt;/p&gt;


	&lt;p&gt;The problem is that as the project grows, the manual testing time gets longer.  It gets harder and harder to remember everything that needs to be tested.  So manual test plans have to be written.  Following those plans becomes ever more tedious and time consuming, so customers hand this off to a QA team.&lt;/p&gt;


	&lt;p&gt;The QA team requires staffing; and as the project grows that staffing must increase.  Test time also increases, from minutes to days to weeks.  Eventually the cost of running manual QA tests becomes significant enough to be a large number on the project cost spreadsheet.  Managers resist the addition of more QA staff and suggest working &amp;#8220;smarter&amp;#8221;.&lt;/p&gt;


	&lt;p&gt;With staffing throttled, QA gets ever more stressed.  Development seldom delivers builds on time, yet the release date cannot move; so QA must make up the slack.  They do this by choosing which tests to run and which tests to assume still work.  They must quickly execute thousands of horribly tedious manual tests and interpret the results.  Under pressure to deliver, the choices they make inevitably, and ironically, reduce the quality of the result.  &lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;* *&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;The name of this blog is a metaphor for a team on a smallish project who decides that they can go faster if they don&amp;#8217;t write automated acceptance tests.   They&amp;#8217;re right&amp;#8212;for now.&lt;/p&gt;</description>
      <pubDate>Mon, 11 Feb 2008 14:25:41 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:4c85ca47-2702-4d2c-9782-0bb50042d93c</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2008/02/11/crash-test-dummies</link>
    </item>
    <item>
      <title>Unit Testing C and C++ ... with Ruby and RSpec!</title>
      <description>&lt;p&gt;If you&amp;#8217;re writing C/C&amp;#043;&amp;#043; code, it&amp;#8217;s natural to write your unit tests in the same language (or use C&amp;#043;&amp;#043; for your C test code). All the well-known unit testing tools take this approach.&lt;/p&gt;


	&lt;p&gt;I think we can agree that neither language offers the best developer productivity among all the language choices out there. Most of us use either language because of perceived performance requirements, institutional and industry tradition, &lt;em&gt;etc.&lt;/em&gt;&lt;/p&gt;


	&lt;p&gt;There&amp;#8217;s growing interest, however, in mixing languages, tools, and &lt;em&gt;paradigms&lt;/em&gt; to get the best tool for a particular job. &amp;lt;shameless-plug&amp;gt;I&amp;#8217;m giving a talk March 7&lt;sup&gt;th&lt;/sup&gt; at &lt;a href="https://www.cmpevents.com/SDw8/a.asp?option=C&amp;#38;V=11&amp;#38;SessID=6102"&gt;SD West&lt;/a&gt; on this very topic, called &lt;a href="https://www.cmpevents.com/SDw8/a.asp?option=C&amp;#38;V=11&amp;#38;SessID=6102"&gt;Polyglot and Poly-Paradigm Programming&lt;/a&gt; &amp;lt;/shameless-plug&amp;gt;.&lt;/p&gt;


	&lt;p&gt;So, why not use a more productive language for your C or C&amp;#043;&amp;#043; unit tests? You have more freedom in your development chores than what&amp;#8217;s required for production. Why not use Ruby&amp;#8217;s &lt;a href="http://rspec.info/"&gt;RSpec&lt;/a&gt;, a &lt;a href="http://behaviour-driven.org/"&gt;Behavior-Driven Development&lt;/a&gt; tool for acceptance and unit testing? Or, you could use Ruby&amp;#8217;s version of &lt;a href="http://www.junit.org"&gt;JUnit&lt;/a&gt;, called &lt;a href="http://ruby-doc.org/stdlib/libdoc/test/unit/rdoc/classes/Test/Unit.html"&gt;Test::Unit&lt;/a&gt;. The hard part is integrating Ruby and C/C&amp;#043;&amp;#043;. If you&amp;#8217;ve been looking for an excuse to bring Ruby (or Tcl or Python or Java or&amp;#8230;) into your C/C&amp;#043;&amp;#043; environment, starting with development tasks is usually the path of least resistance.&lt;/p&gt;


	&lt;p&gt;I did some experimenting over the last few days to integrate &lt;a href="http://rspec.info/"&gt;RSpec&lt;/a&gt;  using &lt;a href="http://www.swig.org"&gt;&lt;span class="caps"&gt;SWIG&lt;/span&gt;&lt;/a&gt; (Simplified Wrapper and Interface Generator), a tool for bridging libraries written in C and C&amp;#043;&amp;#043; to other languages, like Ruby. The &lt;a href="http://www.swig.org/Doc1.3/Ruby.html"&gt;Ruby section&lt;/a&gt; of the &lt;span class="caps"&gt;SWIG&lt;/span&gt; manual was very helpful.&lt;/p&gt;


	&lt;h2&gt;My Proof-of-Concept Code&lt;/h2&gt;


	&lt;p&gt;Here is a zip file of my experiment: &lt;a href="http://blog.objectmentor.com/files/rspec_for_cpp.zip" title="rspec_for_cpp.zip"&gt;rspec_for_cpp.zip&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;This is far from a complete and working solution, but I think it shows promise. See the &lt;strong&gt;Current Limitations&lt;/strong&gt; section below for details.&lt;/p&gt;


	&lt;p&gt;Unzip the file into a directory. I&amp;#8217;ll assume you named it &lt;code&gt;rspec_for_cpp&lt;/code&gt;. You need to have &lt;code&gt;gmake&lt;/code&gt;, &lt;code&gt;gcc&lt;/code&gt;, &lt;span class="caps"&gt;SWIG&lt;/span&gt; and Ruby installed, along with the RSpec &amp;#8220;gem&amp;#8221;. Right now, it only builds on &lt;span class="caps"&gt;OS X&lt;/span&gt; and Linux (at least the configurations on my machines running those OS&amp;#8217;s &amp;#8211; see the discussion below). To run the build, use the following commands:&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
        $ cd rspec_for_cpp/cpp
        $ make 
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;You should see it finish with the lines&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
        ( cd ../spec; spec *_spec.rb )
        .........

        Finished in 0.0***** seconds

        9 examples, 0 failures
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Congratulations, you&amp;#8217;ve just tested some C and C&amp;#043;&amp;#043; code with RSpec! (Or, if you didn&amp;#8217;t succeed, see the notes in the &lt;code&gt;Makefile&lt;/code&gt; and the discussion below.)&lt;/p&gt;


	&lt;h2&gt;The Details&lt;/h2&gt;


	&lt;p&gt;I&amp;#8217;ll briefly walk you through the files in the zip and the key steps required to make it all work.&lt;/p&gt;


	&lt;h3&gt;&lt;code&gt;cexample.h&lt;/code&gt;&lt;/h3&gt;


	&lt;p&gt;Here is a simple C header file.&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
        /* cexample.h */
        #ifndef CEXAMPLE_H
        #define CEXAMPLE_H
        #ifdef __cplusplus
         extern "C" {
        #endif
        char* returnString(char* input);
        double returnDouble(int input);
        void  doNothing();

        #ifdef __cplusplus
         }
        #endif
        #endif
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Of course, in a pure C shop, you won&amp;#8217;t need the &lt;code&gt;#ifdef __cplusplus&lt;/code&gt; stuff. I found this was essential in my experiment when I mixed C and C&amp;#043;&amp;#043;, as you might expect.&lt;/p&gt;


	&lt;h3&gt;&lt;code&gt;cpp/cexample.c&lt;/code&gt;&lt;/h3&gt;


	&lt;p&gt;Here is the corresponding C source file.&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
        /* cexample.h */

        char* returnString(char* input) {
            return input;
        }

        double returnDouble(int input) {
            return (double) input;
        }

        void  doNothing() {}
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;h3&gt;&lt;code&gt;cpp/CppExample.h&lt;/code&gt;&lt;/h3&gt;


	&lt;p&gt;Here is a C&amp;#043;&amp;#043; header file.&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
        #ifndef CPPEXAMPLE_H
        #define CPPEXAMPLE_H

        #include &amp;lt;string&amp;gt;

        class CppExample 
        {
        public:
            CppExample();
            CppExample(const CppExample&amp;#38; foo);
            CppExample(const char* title, int flag);
            virtual ~CppExample();

            const char* title() const;
            void        title(const char* title);
            int         flag() const;
            void        flag(int value);

            static int countOfCppExamples();
        private:
            std::string _title;
            int         _flag;
        };

        #endif
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;h3&gt;&lt;code&gt;cpp/CppExample.cpp&lt;/code&gt;&lt;/h3&gt;


	&lt;p&gt;Here is the corresponding C&amp;#043;&amp;#043; source file.&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
        #include "CppExample.h" 

        CppExample::CppExample() : _title("") {}
        CppExample::CppExample(const CppExample&amp;#38; foo): _title(foo._title) {}
        CppExample::CppExample(const char* title, int flag) : _title(title), _flag(flag) {}
        CppExample::~CppExample() {}

        const char* CppExample::title() const { return _title.c_str(); }
        void        CppExample::title(const char* name) { _title = name; }

        int  CppExample::flag() const { return _flag; }
        void CppExample::flag(int value) { _flag = value; }

        int CppExample::countOfCppExamples() { return 1; }
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;h3&gt;&lt;code&gt;cpp/example.i&lt;/code&gt;&lt;/h3&gt;


	&lt;p&gt;Typically in &lt;span class="caps"&gt;SWIG&lt;/span&gt;, you specify a &lt;code&gt;.i&lt;/code&gt; file to the &lt;code&gt;swig&lt;/code&gt; command to define the &lt;em&gt;module&lt;/em&gt; that wraps the classes and global functions, which classes and functions to expose to the target language (usually all in our case), and other assorted customization options, which are discussed in the &lt;a href="http://www.swig.org/Doc1.3"&gt;&lt;span class="caps"&gt;SWIG&lt;/span&gt; manual&lt;/a&gt;. I&amp;#8217;ll show the &lt;code&gt;swig&lt;/code&gt; command in a minute. For now, note that I&amp;#8217;m going to generate an &lt;code&gt;example_wrap.cpp&lt;/code&gt; file that will function as the bridge between the languages.&lt;/p&gt;


	&lt;p&gt;Here&amp;#8217;s my &lt;code&gt;example.i&lt;/code&gt;, where I named the module &lt;code&gt;example&lt;/code&gt;.&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
        %module example
        %{
            #include "cexample.h" 
            #include "CppExample.h"    
        %}
        %include "cexample.h" 
        %include "CppExample.h" 
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;It looks odd to have header files appear twice. The code inside the &lt;code&gt;%{...%}&lt;/code&gt; (with a &amp;#8217;#&amp;#8217; before each &lt;code&gt;include&lt;/code&gt;) are standard C and C&amp;#043;&amp;#043; statements, &lt;em&gt;etc.&lt;/em&gt; that will be inserted verbatim into the generated &amp;#8220;wrapper&amp;#8221; file, &lt;code&gt;example_wrap.cpp&lt;/code&gt;, so that file will compile when it references anything declared in the header files. The second case, with a &amp;#8217;%&amp;#8217; before the &lt;code&gt;include&lt;/code&gt; statements&lt;sup&gt;&lt;a href="#fn1"&gt;1&lt;/a&gt;&lt;/sup&gt;, tells &lt;span class="caps"&gt;SWIG&lt;/span&gt; to make all the declarations in those header files available to the target language. (You can be more selective, if you prefer&amp;#8230;)&lt;/p&gt;


	&lt;p&gt;Following Ruby conventions, the Ruby plugin for &lt;span class="caps"&gt;SWIG&lt;/span&gt; automatically names the module with an upper case first letter (&lt;code&gt;Example&lt;/code&gt;), but you use &lt;code&gt;require 'example'&lt;/code&gt; to include it, as we&amp;#8217;ll see shortly.&lt;/p&gt;


	&lt;h3&gt;Building&lt;/h3&gt;


	&lt;p&gt;See the &lt;code&gt;cpp/Makefile&lt;/code&gt; for the gory details. In a nutshell, you run the &lt;code&gt;swig&lt;/code&gt; command like this.&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
        swig -c++ -ruby -Wall -o example_wrap.cpp example.i
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Next, you create a dynamically-linked library, as appropriate for your platform, so the Ruby interpreter can load the module dynamically when required. The &lt;code&gt;Makefile&lt;/code&gt; can do this for Linux and &lt;span class="caps"&gt;OS X&lt;/span&gt; platforms. See the &lt;a href="http://www.swig.org/Doc1.3/Ruby.html"&gt;Ruby section&lt;/a&gt; of the &lt;span class="caps"&gt;SWIG&lt;/span&gt; manual for Windows specifics.&lt;/p&gt;


	&lt;p&gt;If you test-drive your code, which tends to drive you towards minimally-coupled &amp;#8220;modules&amp;#8221;, then you can keep your libraries and build times small, which will make the build and test cycle very fast!&lt;/p&gt;


	&lt;h3&gt;&lt;code&gt;spec/cexample_spec.rb&lt;/code&gt; and &lt;code&gt;spec/cppexample_spec.rb&lt;/code&gt;&lt;/h3&gt;


	&lt;p&gt;Finally, here are the RSpec files that exercise the C and C&amp;#043;&amp;#043; code. (Disclaimer: these aren&amp;#8217;t the best spec files I&amp;#8217;ve ever written. For one thing, they don&amp;#8217;t exercise all the &lt;code&gt;CppExample&lt;/code&gt; methods! So sue me&amp;#8230; :)&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
        require File.dirname(__FILE__) + '/spec_helper'
        require 'example'

        describe "Example (C functions)" do
          it "should be a constant on Module" do
            Module.constants.should include('Example')
          end
          it "should have the methods defined in the C header file" do
            Example.methods.should include('returnString')
            Example.methods.should include('returnDouble')
            Example.methods.should include('doNothing')
          end
        end

        describe Example, ".returnString" do
          it "should return the input char * string as a Ruby string unchanged" do
            Example.returnString("bar!").should == "bar!" 
          end  
        end

        describe Example, ".returnDouble" do
          it "should return the input integer as a double" do
            Example.returnDouble(10).should == 10.0
          end
        end

        describe Example, ".doNothing" do
          it "should exist, but do nothing" do
            lambda { Example.doNothing }.should_not raise_error
          end
        end
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;and&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
    require File.dirname(__FILE__) + '/spec_helper'
    require 'example'

    describe Example::CppExample do
      it "should be a constant on module Example" do
        Example.constants.should include('CppExample')
      end
    end

    describe Example::CppExample, ".new" do
      it "should create a new object of type CppExample" do
        example = Example::CppExample.new("example1", 1)
        example.title.should == "example1" 
        example.flag.should  == 1
      end
    end

    describe Example::CppExample, "#title(value)" do
      it "should set the title" do
        example = Example::CppExample.new("example1", 1)
        example.title("title2")
        example.title.should == "title2" 
      end
    end

    describe Example::CppExample, "#flag(value)" do
      it "should set the flag" do
        example = Example::CppExample.new("example1", 1)
        example.flag(2)
        example.flag.should == 2
      end
    end
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;If you love RSpec like I do, this is a very compelling thing to see!&lt;/p&gt;


	&lt;p&gt;And now for the small print:&lt;/p&gt;


	&lt;h2&gt;Current Limitations&lt;/h2&gt;


	&lt;p&gt;As I said, this is just an experiment at this point. Volunteers to make this &lt;em&gt;battle-ready&lt;/em&gt; would be most welcome!&lt;/p&gt;


	&lt;h3&gt;General&lt;/h3&gt;


	&lt;h4&gt;The Example &lt;code&gt;Makefile&lt;/code&gt; File&lt;/h4&gt;


	&lt;p&gt;&lt;strong&gt;It Must Be Hand Edited for Each New or Renamed Source File&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;You&amp;#8217;ve probably already solved this problem for your own make files. Just merge in the example &lt;code&gt;Makefile&lt;/code&gt; to pick up the &lt;span class="caps"&gt;SWIG&lt;/span&gt;- and RSpec-related targets and rules.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;It Only Knows How to Build Shared Libraries for Mac &lt;span class="caps"&gt;OS X&lt;/span&gt; and Linux (and Not Very Well)&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Some definitions are probably unique to my &lt;span class="caps"&gt;OS X&lt;/span&gt; and Linux machines. Windows is not supported at all. However, this is also easy rectify. Start with the notes in the &lt;code&gt;Makefile&lt;/code&gt; itself.&lt;/p&gt;


	&lt;h4&gt;The &lt;code&gt;module.i&lt;/code&gt; File Must Be Hand Edited for Each File Change&lt;/h4&gt;


	&lt;p&gt;Since the format is simple, a make task could fill a template file with the changed list of source files during the build.&lt;/p&gt;


	&lt;h4&gt;Better Automation&lt;/h4&gt;


	&lt;p&gt;It should be straightforward to provide scripts, &lt;span class="caps"&gt;IDE&lt;/span&gt;/Editor shortcuts, &lt;em&gt;etc&lt;/em&gt;. that automate some of the tasks of adding new methods and classes to your C and C&amp;#043;&amp;#043; code when you introduce them  &lt;i&gt;first&lt;/i&gt; in your &amp;#8220;spec&amp;#8221; files. (The true &lt;span class="caps"&gt;TDD&lt;/span&gt; way, of course.)&lt;/p&gt;


	&lt;h3&gt;Specific Issues for C Code Testing&lt;/h3&gt;


	&lt;p&gt;I don&amp;#8217;t know of any other C-specific issues, so unit testing with Ruby is most viable today for C code. Although I haven&amp;#8217;t experimented extensively, C functions and variables are easily mapped by &lt;span class="caps"&gt;SWIG&lt;/span&gt; to a Ruby module. The &lt;a href="http://www.swig.org/Doc1.3/Ruby.html"&gt;Ruby section&lt;/a&gt; of the &lt;span class="caps"&gt;SWIG&lt;/span&gt; manual discusses this mapping in some detail.&lt;/p&gt;


	&lt;h3&gt;Specific Issues for C&amp;#043;&amp;#043; Code Testing&lt;/h3&gt;


	&lt;p&gt;More work will be required to make this viable. It&amp;#8217;s important to note that &lt;span class="caps"&gt;SWIG&lt;/span&gt; cannot handle all C&amp;#043;&amp;#043; constructs (although there are workarounds for most issues, if you&amp;#8217;re committed to this approach&amp;#8230;). For example, namespaces, nested classes, some template and some method overloading scenarios are not supported. The &lt;a href="http://www.swig.org/Doc1.3"&gt;&lt;span class="caps"&gt;SWIG&lt;/span&gt; manual&lt;/a&gt; has details.&lt;/p&gt;


	&lt;p&gt;Also, during my experiment, &lt;span class="caps"&gt;SWIG&lt;/span&gt; didn&amp;#8217;t seem to map &lt;code&gt;const std::string&amp;#38;&lt;/code&gt; objects in C&amp;#043;&amp;#043; method signatures to Ruby strings, as I would have expected (&lt;code&gt;char*&lt;/code&gt; worked fine).&lt;/p&gt;


	&lt;h2&gt;Is It a Viable Approach?&lt;/h2&gt;


	&lt;p&gt;Once the &lt;strong&gt;General&lt;/strong&gt; issues listed above are handled, I think this approach would work very well for C code. For C&amp;#043;&amp;#043; code, there are more issues that need to be addressed, and programmers who are committed to this strategy will need to tolerate some issues (or just use C&amp;#043;&amp;#043;-language tools for some scenarios).&lt;/p&gt;


	&lt;h2&gt;Conclusions: Making It Development-Team Ready&lt;/h2&gt;


	&lt;p&gt;I&amp;#8217;d like to see this approach pushed to its logical limit. I think it has the potential to really improve the productivity of C and C&amp;#043;&amp;#043; developers and the quality of their test coverage, by leveraging the productivity and power of dynamically-typed languages like Ruby. If you prefer, you could use Tcl, Python, even Java instead.&lt;/p&gt;


	&lt;h3&gt;License&lt;/h3&gt;


	&lt;p&gt;This code is complete open and free to use. Of course, use it at your own risk; I offer it without warranty, &lt;em&gt;etc.&lt;/em&gt;, &lt;em&gt;etc&lt;/em&gt;. When I polish it to the point of making it an &amp;#8220;official&amp;#8221; project, I will probably release under the Apache license.&lt;/p&gt;


	&lt;p id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; I spent a lot of time debugging problems because I had a &amp;#8217;#&amp;#8217; where I should have had a &amp;#8217;%&amp;#8217;! &lt;em&gt;Caveat emptor&lt;/em&gt;!&lt;/p&gt;</description>
      <pubDate>Mon, 04 Feb 2008 22:08:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:cba4dc23-cbce-4173-be6f-14c7847dcfea</guid>
      <author>Dean Wampler</author>
      <link>http://blog.objectmentor.com/articles/2008/02/04/unit-testing-c-and-c-with-ruby-and-rspec</link>
      <category>Embedded</category>
      <category>Dean's Deprecations</category>
      <category>Dynamic Languages</category>
      <category>Agile Methods</category>
      <category>c</category>
      <category>RSpec</category>
      <category>Ruby</category>
      <category>TDD</category>
      <category>testing</category>
    </item>
    <item>
      <title>The Post-it&#174; Notes Test for UML Diagrams</title>
      <description>&lt;p&gt;A lot of teams require their developers to document their designs in &lt;span class="caps"&gt;UML&lt;/span&gt;, using Visio or another tool, before they can start coding.&lt;/p&gt;


	&lt;p&gt;Of course, this is not at all Agile. For one thing, the design is likely to change quite a bit as you learn while coding. Hardly anyone returns to the diagrams and updates them. Now they are &lt;em&gt;lies&lt;/em&gt;, because they make claims about the designs that aren&amp;#8217;t true.&lt;/p&gt;


	&lt;p&gt;&lt;span class="caps"&gt;UML&lt;/span&gt; still has a place in agile projects, of course. It&amp;#8217;s a great tool for brainstorming design ideas. So, how do you decide when a diagram is worth keeping and therefore, worth maintaining? Here&amp;#8217;s a little strategy that I recommend.&lt;/p&gt;


	&lt;p&gt;Draw the diagram during those brainstorming sessions on a white board or a poster-sized Post-it&amp;reg; Note. Drawing it this way means you have invested almost no additional effort, beyond the brainstorming itself, to create the diagram. Also, you won&amp;#8217;t feel bad about lost work if you eventually throw it away.&lt;/p&gt;


	&lt;p&gt;Leave the diagram on the wall for everyone to see while they implement the design.&lt;/p&gt;


	&lt;p&gt;By the time the note is falling off the wall or the dry-erase marker is wearing off the white board, you&amp;#8217;ll know if the ideas are still relevant or completely obsolete.&lt;/p&gt;


	&lt;p&gt;If they are obsolete, you can erase the board or toss the paper. If they are still relevant, and probably changed somewhat, you now know that the diagram is worth preserving. Go ahead and spend the time to create an updated, more permanent version in your drawing tool (but don&amp;#8217;t spend too much time!).&lt;/p&gt;</description>
      <pubDate>Tue, 22 Jan 2008 15:58:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:de899b11-fd88-4157-965b-f36aa7682fdd</guid>
      <author>Dean Wampler</author>
      <link>http://blog.objectmentor.com/articles/2008/01/22/the-post-it-reg-notes-test-for-uml-diagrams</link>
      <category>Agile Methods</category>
      <category>Design Principles</category>
      <category>design</category>
      <category>UML</category>
    </item>
    <item>
      <title>Generated Tests and TDD</title>
      <description>&lt;p&gt;&lt;span class="caps"&gt;TDD&lt;/span&gt; has become quite popular, and many companies are attempting to adopt it.  However, some folks worry that it takes a long time to write all those unit tests and are looking to test-generation tools as a way to decrease that burden.&lt;/p&gt;


	&lt;p&gt;The burden is not insignificant.  FitNesse, an application created using &lt;span class="caps"&gt;TDD&lt;/span&gt;, is comprised of 45,000 lines of Java code, 15,000 of which are unit tests.  Simple math suggests that &lt;span class="caps"&gt;TDD&lt;/span&gt; increases the coding burden by a full third!&lt;/p&gt;


	&lt;p&gt;Of course this is a naive analysis.  The &lt;em&gt;benefits&lt;/em&gt; of using &lt;span class="caps"&gt;TDD&lt;/span&gt; are significant, and far outweigh the burden of writing the extra code.  But that 33% still feels &amp;#8220;extra&amp;#8221; and tempts people to find ways to shrink it without losing any of the benefits.&lt;/p&gt;


	&lt;h1&gt;Test Generators.&lt;/h1&gt;


	&lt;p&gt;Some folks have put their hope in tools that automatically generate tests by inspecting code.  These tools are very clever.  They generate random calls to methods and remember the results.  They can automatically build mocks and stubs to break the dependencies between modules.  They use remarkably clever algorithms to choose their random test data.  They even provide ways for programmers to write plugins that adjust those algorithms to be a better fit for their applications.&lt;/p&gt;


	&lt;p&gt;The end result of running such a tool is a set of &lt;em&gt;observations&lt;/em&gt;.  The tool observes how the instance variables of a class change when calls are made to its methods with certain arguments.  It notes the return values, changes to instance variables, and outgoing calls to stubs and mocks.  And it presents these observations to the user.&lt;/p&gt;


	&lt;p&gt;The user must look through these observations and determine which are correct, which are irrelevant, and which are bugs.  Once the bugs are fixed, these observations can be checked over and over again by re-running the tests.  This is very similar to the record-playback model used by &lt;span class="caps"&gt;GUI&lt;/span&gt; testers.  Once you have registered all the correct observations, you can play the tests back and make sure those observations are still being observed.&lt;/p&gt;


	&lt;p&gt;Some of the tools will even write the observations as JUnit tests, so that you can run them as a standard test suite.  Just like &lt;span class="caps"&gt;TDD&lt;/span&gt;, right?  Well, not so fast&amp;#8230;&lt;/p&gt;


	&lt;p&gt;Make no mistake, tools like this can be very useful.  If you have a wad of untested legacy code, then generating a suite of JUnit tests that verifies some portion of the behavior of that code can be a great boon!&lt;/p&gt;


	&lt;h2&gt;The Periphery Problem&lt;/h2&gt;


On the other hand, no matter how clever the test generator is, the tests it generates will always be more naive than the tests that a human can write.  As a simple example of this, I have tried to generate tests for the bowling game program using two of the better known test generation tools.  The interface to the Bowling Game looks like this:
&lt;code&gt;&lt;pre&gt;
  public class BowlingGame {
    public void roll(int pins) {...}
    public int score() {...}
  }
&lt;/pre&gt;&lt;/code&gt;
The idea is that you call roll each time the balls gets rolled, and you call score at the end of the game to get the score for that game.  

	&lt;p&gt;The test generators could not randomly generate valid games.  It&amp;#8217;s not hard to see why.  A valid game is a sequence of between 12 and 21 rolls, all of which must be integers between 0 and 10.  What&amp;#8217;s more, within a given frame, the sum of rolls cannot exceed 10.  These constraints are just too tight for a random generator to achieve within the current age of the universe.&lt;/p&gt;


	&lt;p&gt;I could have written a plugin that guided the generator to create valid games; but such an algorithm would embody much of the logic of the BowlingGame itself, so it&amp;#8217;s not clear that the economics are advantageous.&lt;/p&gt;


	&lt;p&gt;To generalize this, the test generators have trouble getting &lt;em&gt;inside&lt;/em&gt; algorithms that have any kind of protocol, calling sequence, or state semantics.  They can generate tests around the &lt;em&gt;periphery&lt;/em&gt; of the classes; but can&amp;#8217;t get into the guts without help.&lt;/p&gt;


	&lt;h2&gt;&lt;span class="caps"&gt;TDD&lt;/span&gt;?&lt;/h2&gt;


	&lt;p&gt;The real question is whether or not such generated tests help you with Test Driven Development.  &lt;span class="caps"&gt;TDD&lt;/span&gt; is the act of using tests as a way to drive the development of the system.  You write unit test code first, and then you write the application code that makes that code pass.  Clearly generating tests from existing code violates that simple rule.  So in some philosophical sense, using test generators is &lt;em&gt;not&lt;/em&gt; TDD.  But who cares so long as the tests get written, right?  Well, hang on&amp;#8230;&lt;/p&gt;


	&lt;p&gt;One of the reasons that &lt;span class="caps"&gt;TDD&lt;/span&gt; works so well is that it is similar to the accounting practice of dual entry bookkeeping.  Accountants make every entry twice; once on the credit side, and once on the debit side.  These two entries follow separate mathematical pathways. In the end a magical subtraction yields a zero if all the entries were made correctly.&lt;/p&gt;


	&lt;p&gt;In &lt;span class="caps"&gt;TDD&lt;/span&gt;, programmers state their intent twice; once in the test code, and again in the production code.  These two statements of &lt;em&gt;intent&lt;/em&gt; verify each other.  The tests, test the intent of the code, and the code tests the intent of the tests.  This works because it is a &lt;em&gt;human&lt;/em&gt; that makes both entries!  The human must state the intent twice, but in two complementary forms.  This vastly reduces many kinds of errors; as well as providing significant insight into improved design.&lt;/p&gt;


	&lt;p&gt;Using a test generator breaks this concept because the generator writes the test using the production code as input.  The generated test is not a human restatement, it is an automatic translation.  The human states intent only once, and therefore does not gain insights from restatement, nor does the generated test check that the &lt;em&gt;intent&lt;/em&gt; of the code was achieved.  It is true that the human must verify the observations, but compared to &lt;span class="caps"&gt;TDD&lt;/span&gt; that is a far more passive action, providing far less insight into defects, design and intent.&lt;/p&gt;


	&lt;p&gt;I conclude from this that automated test generation is neither equivalent to &lt;span class="caps"&gt;TDD&lt;/span&gt;, nor is it a way to make &lt;span class="caps"&gt;TDD&lt;/span&gt; more efficient.  What you gain by trying to generate the 33% test code, you lose in defect elimination, restatement of intent, and design insight. You also sacrifice depth of test coverage, because of the periphery problem.&lt;/p&gt;


	&lt;p&gt;This does not mean that test generators aren&amp;#8217;t useful.  As I said earlier, I think they can help to partially characterize a large base of legacy code.  But these tools are not &lt;span class="caps"&gt;TDD&lt;/span&gt; tools. The tests they generate are not equivalent to tests written using &lt;span class="caps"&gt;TDD&lt;/span&gt;.  And many of the benefits of &lt;span class="caps"&gt;TDD&lt;/span&gt; are not achieved through test generation.&lt;/p&gt;</description>
      <pubDate>Thu, 10 Jan 2008 13:59:30 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:8528afa6-7e1b-406d-ab72-18557ff0912c</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2008/01/10/generated-tests-and-tdd</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Agile Methods</category>
    </item>
    <item>
      <title>So just what does synchronized do?</title>
      <description>&lt;p&gt;&lt;b&gt;Synopsis&lt;/b&gt;
&lt;Blockquote&gt;Using synchronized turns a huge state space into a comparatively small one.
&lt;/blockquote&gt;
&lt;p&gt;Normally, the light from a star radiates out in all directions. But what happens when a star collapses? There are several possibilities depending on the mass of the star. Our sun will turn into a red giant and then later turn into a white dwarf, giving out light from its accumulated heat for many years after living on Earth has become unbearable; mostly because of all the traffic.&lt;/p&gt;&lt;/p&gt;


&lt;p&gt;If the mass of the star is around 10x our star, its destiny is just a bit different. It will begin to collapse. Along the way, it will probably have some temporary reprieves from its ultimate fate, to become a Neutron star, by consuming other heavier elements such as carbon and helium . However, the writing is on the wall. The center of star, already an extreme environment, becomes even more so; eventually, the pressure from the collapsing of material into the center of the star results in a massive explosion known as a nova or super nova &amp;#8211; depending on the mass of the star. What is left is a neutron star. A neutron star is the heart of a pulsar, able to spin at amazing rates without pulling itself apart.&lt;/p&gt;

&lt;P&gt;Another option is a black hole. A black hole is an often used metaphor for either the effort expended on support/fixing/updating a big ball of mud or what the development effort appears to be in most of the time. Either way, it is not considered a good thing if you&amp;#8217;re anywhere in the vicinity.&lt;/P&gt;

&lt;p&gt;I&amp;#8217;m a pessimist by nature. I see a project in decline, sucking in other resources, like a black holes eating neighboring galaxies, snuffing the light out of stars, just like projects can suck the life force out of individuals.&lt;/P&gt;

&lt;P&gt;However, energy can escape from a black hole, eventually leading to the demise of the black hole. Energy can escape along the axis of rotation in either direction. In a sense, if we see the expansion of the black hole as a bad thing, anything that diminishes a black hole is a good thing. Stephen Hawking theorized that at the event horizon of black holes, fluctuations in the space can cause the spontaneous creations of pairs of particles and their anti particles. This is another way it can appear that a black hole is losing energy since it gives off particles while the opposite particle goes into the black hole.&lt;/P&gt;

	&lt;p&gt;Now I&amp;#8217;m off track. I wanted to talk about how synchronized give a similar effect as the massive gravity of black hole. But instead of curving space-time, they invert the possible state space of code in the presence of threads. Let&amp;#8217;s take a look.&lt;/p&gt;


Here&amp;#8217;s a simple class:
&lt;FONT style="line-height:95%"&gt;&lt;code&gt;&lt;pre&gt;
public class X {
   int value;

   public synchronized void incrementValue() {
        ++value;
    }
}&lt;/pre&gt;&lt;/code&gt;&lt;/FONT&gt;
Let&amp;#8217;s say, for the sake of argument, two threads are trying to execute the single method in this class. If the method is written like this:
&lt;FONT style="line-height:95%"&gt;&lt;code&gt;&lt;pre&gt;
   public synchronized void incrementValue() {
        ++value;
    }
&lt;/pre&gt;&lt;/code&gt;&lt;/FONT&gt;
&lt;P&gt;Then there are only two orderings, Thread 1/Thread 2, or Thread 2/Thread 1. All of those paragraphs at the top were to make this analogy.&lt;/p&gt;

&lt;P&gt;OK, so if we use synchronized that that&amp;#8217;s the black hole. The number of possible paths through the code for N threads is N!. What&amp;#8217;s the opposite? What happens if we take off the keyword and then run two threads through it? In how many ways can that single line of code get executed?&lt;/P&gt;

	&lt;p&gt;Are you ready for it?&lt;/p&gt;


&lt;B&gt;&lt;Blockquote&gt;3,432 different ways&lt;/blockquote&gt;&lt;/B&gt;

	&lt;p&gt;Really? Well at least conceptually. In practice, the Just In Time compiler will probably turn the &lt;span class="caps"&gt;JVM&lt;/span&gt; instructions into native code, so the actual number of individual steps will probably be less. But there really are that many paths through the system. You might ask how?&lt;/p&gt;


	&lt;p&gt;That single line of code is represented in byte code as 7 lines. I could show you the disassembly, but really, it&amp;#8217;s 7. You can convince yourself by having a look at the byte-code using a nice &lt;a href="http://download.forge.objectweb.org/eclipse-update/"&gt; byte-code viewer&lt;/a&gt; plug-in for eclipse.&lt;/p&gt;


	&lt;p&gt;What happens if we change the int to a long? We still have 7 lines of byte-code, but with different instructions. We have a total of 4 long reads/writes. Each long read/write requires two individual 32-bit operations &amp;#8211; or at lest the &lt;span class="caps"&gt;JVM&lt;/span&gt; can implement it that way. The actual number of atomic operations after the Just In Time compiler has had its way with your byte-code will probably be less, but if we stick to byte-codes and the Java memory model, the number 3,432 is now a whopping 705,432!&lt;/p&gt;


	&lt;p&gt;Let&amp;#8217;s extend that just a bit more. What if you have several lines of code? Each line of Java results in many more lines of byte-code. What if we have have 3 lies of Java? We probably have something like 21 lines of byte-code. How many paths of execution would 21 lines of byte-code executed by two threads have? 538,257,874,440!&lt;/p&gt;


	&lt;p&gt;Where the first program ended up being a white dwarf, the version using longs was a nova. I&amp;#8217;m not sure what to call the thee line Java method, maybe a hyper-nova?&lt;/p&gt;


	&lt;p&gt;In practice, the actual number of paths through a method will end up being smaller. And, most of the paths do not have any negative side-effects. The problem, however, is that there are a small number of hard to find paths of execution that do cause problems and finding them is like looking for a needle in a haystack.&lt;/p&gt;


	&lt;p&gt;Remember what adding the keyword synchronized did? If we use it on a three line method, it turns 538,257,874,440 into 2. It collapses the number of paths into 2 for two threads. And 2 is less than 538,257,874,440, for even vary large values of 2.&lt;/p&gt;


	&lt;p&gt;How did I derive at these magic numbers? Two ways.&lt;/p&gt;


	&lt;p&gt;I wanted to know how many possible orderings there were for 7 instructions and two threads. I knew it had to do with combinations and permutations but I just wasn&amp;#8217;t smart enough to figure it out. Searching on Google didn&amp;#8217;t do much for me either. So I decided to write a program to numerically derive the result. I tested my way into a program that would calculate the result.&lt;/p&gt;


The basic algorithm is:
&lt;ol&gt;
&lt;li&gt;Determine all possible orderings of each of the unique &amp;#8220;nodes&amp;#8221; in a system. For example, if I have 2 threads and 2 instructions, I can generate a natural key (ugh!) to represent each of the different combinations of threads and instructions: &lt;span class="caps"&gt;T1S1 T1S2 T2S1 2S2&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;Produce all valid permutations of these four &amp;#8220;nodes&amp;#8221;.&lt;/li&gt;
&lt;li&gt;Remove any that have invalid orderings.&lt;/li&gt;
&lt;li&gt;Count the results.&lt;/li&gt;
&lt;/ol&gt;

	&lt;p&gt;Many of my first implementations for some of these steps were exercises in writing really inefficient code! But having those tests made it really easy to swap out better algorithms when my brain caught up with what I was doing.&lt;/p&gt;


	&lt;p&gt;What is an invalid ordering? The code generated by the single line using the pre increment operator has 7 steps. Those 7 steps are in a single sequence with no looping and no conditionals. That&amp;#8217;s like saying A is always before B. So if we generate a list of orderings that end up including that combination, we&amp;#8217;ve generated an ordering that cannot happen.&lt;/p&gt;


So you can describe your possible state space in a few steps:
&lt;ol&gt;
&lt;li&gt;Register a node for each thread, step combination. 7 threads, 4 steps = 28 nodes.&lt;/li&gt;
&lt;li&gt;Register dependences between steps. For example, if I have seven steps and two threads executing the same sequence, I could describe this as: &lt;span class="caps"&gt;T1S1&lt;/span&gt; -&amp;gt; &lt;span class="caps"&gt;T1S2&lt;/span&gt; -&amp;gt; &lt;span class="caps"&gt;T1S3&lt;/span&gt;, etc. And for the second thread: &lt;span class="caps"&gt;T2S1&lt;/span&gt; -&amp;gt; &lt;span class="caps"&gt;T2S2&lt;/span&gt; -&amp;gt; T2&amp;gt;S3. Since the name is arbitrary, I just used letters, so in fact I had: a -&amp;gt; b -&amp;gt; c -&amp;gt; d -&amp;gt; e -&amp;gt; f -&amp;gt; g for one set of dependencies and h -&amp;gt; i -&amp;gt; j -&amp;gt; k -&amp;gt; l -&amp;gt; m -&amp;gt; o
&lt;/ol&gt;
&lt;p&gt;In fact, here&amp;#8217;s the test I used to describe that exact space:&lt;/P&gt;
&lt;FONT style="line-height:95%"&gt;&lt;code&gt;&lt;pre&gt;
    @Test
    public void twoThreadsAndSevenSteps() {
        calculator = new PathCalculator(14);
        createLine('a', 'b', 'c', 'd', 'e', 'f', 'g');
        createLine('h', 'i', 'j', 'k', 'l', 'm', 'n');
        start();
        int totalPaths = calculator.totalPaths();
        stop(2, 4, totalPaths);
    }
&lt;/pre&gt;&lt;/code&gt;&lt;/FONT&gt;

&lt;P&gt;By the time I got to this point, I wrote some &amp;#8220;tests&amp;#8221; using JUnit as a harness to run my code and display timing information and a summary of the &lt;results. The output looked like this.&lt;/p&gt;
&lt;FONT style="line-height:95%"&gt;&lt;code&gt;&lt;pre&gt;
Time:        4ms -- Threads:  3, Opcodes:  2, Total paths:      90
Time:        1ms -- Threads:  2, Opcodes:  3, Total paths:      20
Time:       54ms -- Threads:  4, Opcodes:  2, Total paths:    2520
Time:        3ms -- Threads:  2, Opcodes:  4, Total paths:      70
Time:       61ms -- Threads:  2, Opcodes:  5, Total paths:     252
Time:     1248ms -- Threads:  2, Opcodes:  6, Total paths:     924
Time:    12819ms -- Threads: 10, Opcodes:  1, Total paths: 3628800
&lt;/pre&gt;&lt;/code&gt;&lt;/FONT&gt;

I then used this information to fit a cure to my data and derive a formula for various combinations. For 2 threads, I came up with the following formula. If you let N be the number of steps:
&lt;blockquote&gt;Total Paths = 252 * 3.6667 &lt;sup&gt;N-5&lt;/sup&gt; &lt;/blockquote&gt;

&lt;P&gt;The morning after, Uncle Bob sent an email, showing me his work on how he calculated.&lt;/P&gt;

If you let:
&lt;ol&gt;
&lt;li&gt;T be the number of threads&lt;/li&gt;
&lt;li&gt;N be the number of steps&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;Total = (N*T)! &amp;nbsp; / &amp;nbsp; N! &lt;sup&gt;T&lt;/sup&gt;&lt;/blockquote&gt;

	&lt;p&gt;When I plugged numbers into his formula, they fit my formula. His formula generated an exact result as opposed to my estimate based on fitting a curve. Another thing his solution has going for it is the algorithm I came up with, I believe, is NP-complete. The net effect was I that while I was able to calculate result for 2 threads and 6 steps, 2 threads and 7 steps took a long time before running out of memory with a 2GB heap space. Bob&amp;#8217;s formula gave me a so-called verifier (as did my formula &amp;#8211; only Bob&amp;#8217;s was better) and the algorithm seems to grow based on factorials and not polynomials.&lt;/p&gt;


&lt;p&gt;What&amp;#8217;s the point of all of this? The single, one-line program, is a demonstration of why going from one thread to two threads makes writing/debugging/testing programs so much harder. It also numerically demonstrates &lt;b&gt;why&lt;/b&gt; the single responsibility principle is even more important when we start writing concurrent programs. The more you put in one place, the large the state space. Larger state spaces:
&lt;ol&gt;
&lt;li&gt;Make it harder to find that one or few number of paths that can cause your program to die, under load, in production, while you are on vacation&lt;/li&gt;
&lt;li&gt;Make your efforts to test (which is a sampling technique anyway) for concurrency issues all the more difficult&lt;/li&gt;
&lt;li&gt;Make it harder to find what might actually have caused a failure once you&amp;#8217;ve notice it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In a later post, I&amp;#8217;ll describe how we can improve our chances of covering this huge space of potential orderings.&lt;/P&gt;

&lt;p&gt;If you&amp;#8217;ve made it this far, wow! Congratulations!&lt;/P&gt;</description>
      <pubDate>Thu, 03 Jan 2008 21:27:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:5b8ba16d-124b-4957-a36a-eb8359b589c0</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2008/01/03/so-just-what-does-synchronized-do</link>
      <category>Schuchert&#8217;s Scattered Synapses </category>
      <category>threading</category>
      <category>concurrency</category>
      <category>testing</category>
      <category>NP</category>
      <category>complete</category>
    </item>
    <item>
      <title>Generic Java Agent Registry</title>
      <description>&lt;p&gt;I&amp;#8217;m writing a Java Agent for the first time. Why? I&amp;#8217;m interested in using this tool called &lt;a href="http://www.haifa.ibm.com/projects/verification/contest/index