<?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: Category Tim's Tepid Torrent</title>
    <link>http://blog.objectmentor.com/articles/category/tims-tepid-torrent</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description></description>
    <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>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>Shoveling Code</title>
      <description>&lt;p&gt;I was ill when the first snow fell last weekend, and didn&amp;#8217;t get out and scrape the drive and sidewalks.  Sadly, neither did I bundle up my kids and send them out with shovels.  As a result, the snow melted and refroze.  When I left home on sunday morning, clearing the snow was frustrated by the presence of hard, packed ice under the snow.&lt;/p&gt;


	&lt;p&gt;Now I have to be very careful when moving in the drive or sidewalk because of the black ice in some places and thick lumpy stuff in others.  I could choose to leave it that way and just walk carefully and try to avoid the area, but I really don&amp;#8217;t want it to be like this all winter.&lt;/p&gt;


	&lt;p&gt;Instead, I bundled up and spent several painful hours trying to clear not only the six to eight inches of new snow, but the ice under it.  Clearing the fresh stuff is tough because the rough and lumpy ice is under it.  The ice snags the shovel and hurts my elbows and shoulders.  I use the metal edge of the shovel to plane off the ice so that it&amp;#8217;s not quite so difficult, and the work gets a little easier.&lt;/p&gt;


	&lt;p&gt;Smooth, planed ice is not a solution.  It is actually going to be more slippery and dangerous when the sun hits it and it melts a little.  It will then refreeze to an even smoother and slicker sheen.  I can&amp;#8217;t ignore the problem, and I can&amp;#8217;t smooth it over and leave it at that.&lt;/p&gt;


	&lt;p&gt;I invested in some complicated salt product to lower the melting point of the ice so I can scrape it away.  It wasn&amp;#8217;t enough, but now there are some safe areas in my driveway.  I continue to scrape it and hope that I can get it all squared away so that my wife and kids have safe passage, though it is tedious and unpleasant work.&lt;/p&gt;


	&lt;p&gt;Yes, it&amp;#8217;s my fault.  I should have bundled up my sick self or my children and taken care of this when the first snow fell, back when it was easy.&lt;/p&gt;


	&lt;p&gt;Then it dawned on me that my driveway is a lot like source code.  If I always take care of it when it&amp;#8217;s relatively easy and not too polluted, it will remain easier to deal with in the longer term.  The more unsafe and ugly it is, the more important it is to clean it up.  It won&amp;#8217;t do to smooth it out a little or to leave it be.  It needs to be safe for me and my team.&lt;/p&gt;


	&lt;p&gt;And I guess that&amp;#8217;s my parable for today.&lt;/p&gt;</description>
      <pubDate>Thu, 06 Dec 2007 12:56:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:ae89090e-70ae-4a59-b25b-befd7ecb2a18</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2007/12/06/shoveling-code</link>
      <category>Tim's Tepid Torrent</category>
      <category>snow</category>
      <category>code</category>
      <category>cleaning</category>
      <category>smoothing</category>
      <category>avoid</category>
      <category>trouble</category>
      <category>parable</category>
      <category>ottinger</category>
    </item>
    <item>
      <title>Naming: A Word To The Wise</title>
      <description>&lt;p&gt;Please pronounce your variable names as words, even if they are merely abbreviations.  The phonemes indicated by your spelling may correspond to an existing word with an entrenched meaning. It may be one that you do not intend to communicate.&lt;/p&gt;</description>
      <pubDate>Tue, 27 Nov 2007 20:50:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:b90134fd-a901-4af6-91b0-6c4e65e4b5b6</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2007/11/27/naming-a-word-to-the-wise</link>
      <category>Tim's Tepid Torrent</category>
      <category>naming</category>
      <category>clever</category>
      <category>clear</category>
      <category>code</category>
      <category>style</category>
    </item>
    <item>
      <title>On Being Stupid</title>
      <description>&lt;blockquote&gt;
This was posted originally to a mailing list, but is reproduced here essentially unchanged by request of a friend. 
&lt;/blockquote&gt;

	&lt;p&gt;I frequently see code (written by others) that is completely
double-spaced, heavily commented, loaded with many abbreviated or meaningless variable names, and hundreds of lines long.
In order to read the function and understand what it&amp;#8217;s doing, poor Tim
must wear out a mouse, skip comments, and track the variables on
paper.  A &amp;#8220;smarter&amp;#8221; programmer could just load it into his head, I
suppose, but not the simpleton who writes this email.&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;m not smart enough to just read it from top to bottom and
understand it. Sadly, when I read through and understand what in the
heck the thxIniFvt variable is doing, I will forget it by the time I
figure out the purpose(es) of pszVbt.  I can spend all day, or even a
few days to figure out a method, and that&amp;#8217;s an admission of
feeble-mindedness to be sure.  I guess I&amp;#8217;m not up to the level of some
of the rapid hackers. That&amp;#8217;s a limitation I face most days.&lt;/p&gt;


	&lt;p&gt;I find that I can sometimes understand a method like that only  if I just delete all the blank lines and comments first, then reformat to break lines, then inline all methods with seven or more parameters, and then start renaming variables, extracting explanatory variables, and
extracting explanatory methods. I may have to break the method into
classes even.   I guess I&amp;#8217;m not one of the smart kids.&lt;/p&gt;


	&lt;p&gt;I used to be one of the smart kids.  I once built a module so complex and fragile that nobody but me could figure out what to do with it.  It was all tables and indicators, and stunningly clever.  I am so ashamed that I wrote it. It was such a mistake that they eventually disabled it rather than field it in such a state. That was years ago, but so memorable to me. Other programmers said it was like the inside of a swiss watch, all
delicate and perfectly balanced, and scary to mess with unless you first knew exactly what each part was doing, and why.&lt;/p&gt;


	&lt;p&gt;I would like to be faster than I am both mentally and in the sense
of quickly producing code. I&amp;#8217;d like to be a little less intimidated at
the start of a project. .But I would not want those things if it meant
building crap that people who are not appreciably more talented than
myself would trip over every day.  Instead, I sometimes wish I could
teach the really fast, smart kids how to dumb down the code for the
rest of us morons to read.&lt;/p&gt;


	&lt;p&gt;The funny thing is that dumbing code to my level doesn&amp;#8217;t make it
harder for the smart kids to use it, and sometimes allows a compiler
to do a better job with it.  I guess stupid isn&amp;#8217;t so stupid after all.&lt;/p&gt;</description>
      <pubDate>Mon, 10 Sep 2007 10:16:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:0b06c5f0-9426-40f9-add4-95c9b20a56ac</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2007/09/10/on-being-stupid</link>
      <category>Tim's Tepid Torrent</category>
      <category>naming</category>
      <category>dumb</category>
      <category>moron</category>
      <category>clever</category>
      <category>refactoring</category>
      <category>comments</category>
      <category>coding</category>
      <category>Fast</category>
      <category>whitespace</category>
      <category>dumbing</category>
      <category>down</category>
      <category>code</category>
    </item>
    <item>
      <title>Not A Task, But An Approach</title>
      <description>&lt;p&gt;Transitions are tough. It seems that lately I&amp;#8217;ve been getting a lot of contact from frustrated people who don&amp;#8217;t really have a good handle on the &amp;#8220;drive&amp;#8221; part of Test Driven Development.  A question heard frequently is: &amp;#8220;I&amp;#8217;ve almost completed the coding, can you help me write the &lt;span class="caps"&gt;TDD&lt;/span&gt;?&amp;#8221;&lt;/p&gt;


	&lt;p&gt;It seems like Test Driven Development is taken backward, that the &lt;em&gt;developers&lt;/em&gt; are &lt;em&gt;driven&lt;/em&gt; to write &lt;em&gt;tests&lt;/em&gt;.  The practitioner winces, realizing that he again faces The Great Misunderstanding of &lt;span class="caps"&gt;TDD&lt;/span&gt;.&lt;/p&gt;


	&lt;p&gt;&lt;span class="caps"&gt;TDD&lt;/span&gt; stands for Test-Driven Development, which is not as clear as &lt;span class="caps"&gt;TFD&lt;/span&gt; (Test-First Development). If the consultant would strive to always say the word &amp;#8220;first&amp;#8221; in association with testing, most people would more surely grasp the idea.  In fact, I&amp;#8217;ve begun an experiment in which I will not say the word &amp;#8220;test&amp;#8221; without the word &amp;#8220;first&amp;#8221; in close approximation. I&amp;#8217;ll let you know how that works out for me.&lt;/p&gt;


	&lt;p&gt;If the tests are providing nothing more than reassurance on the tail end of a coding phase, then the tests aren&amp;#8217;t driving the development.  They are like &lt;em&gt;riders&lt;/em&gt; instead of &lt;em&gt;drivers&lt;/em&gt;.  Test-Ridden Development (TRD)[1] would be a better term for such a plan. Even though it is better to have those tail-end tests than to have no automated testing, it misses the point and could not be reasonably be called &lt;span class="caps"&gt;TDD&lt;/span&gt;.&lt;/p&gt;


	&lt;p&gt;An old mantra for &lt;span class="caps"&gt;TDD&lt;/span&gt; and &lt;span class="caps"&gt;BDD&lt;/span&gt; is &amp;#8220;it&amp;#8217;s not about testing&amp;#8221;. The term &lt;span class="caps"&gt;BDD&lt;/span&gt; was invented largely to get the idea of &amp;#8220;testing&amp;#8221; out of the way.  People tend to associate &amp;#8220;test&amp;#8221; as a release-preparation activity rather than an active approach to programming. &lt;span class="caps"&gt;BDD&lt;/span&gt; alleviates some of that cognitive dissonance.&lt;/p&gt;


	&lt;p&gt;In &lt;span class="caps"&gt;TDD&lt;/span&gt;, tests come first. Each unit test is written as it is needed by the programmer.  Tests are just-in-time and are active in shaping the code. Acceptance Tests likewise tend to precede programming by some short span of time.  [2]&lt;/p&gt;


Through months of repetition I have developed the mantra:
&lt;blockquote&gt;
&lt;span class="caps"&gt;TDD&lt;/span&gt; isn&amp;#8217;t a task. It is not something you do.  It is an approach.  It is how you write your programs.
&lt;/blockquote&gt;

	&lt;p&gt;I wonder if we shouldn&amp;#8217;t resurrect the term Test-First Programming or Test-First Development for simple evocative power. Admittedly there are some who would see that as a phase ordering, but maybe enough people would get the right idea.&lt;/p&gt;


	&lt;p&gt;Brett Schuchert(with some trivial aid from your humble blogger) has worked up an acronym to help socialize the basic concepts which are somehow being lost in translation to the corporate workplace.&lt;/p&gt;


	&lt;p&gt;The teaser:
    Fast, Isolated, Repeatable, Self-validating, and Timely.&lt;/p&gt;


	&lt;p&gt;As a reader of this blog, you are probably very familiar with all of the terminology and concepts behind &lt;span class="caps"&gt;TDD&lt;/span&gt;. I beg of you, socialize the idea that testing comes first and drives the shape of the code.  If we can just get this one simple idea spread into programming dens across our small spheres of influence, then we will have won a very great victory over Test-Ridden Development.&lt;/p&gt;


	&lt;p&gt;&amp;#8220;And there was much rejoicing.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;&lt;small&gt;
1 Jeff Langr will refer to this &lt;span class="caps"&gt;TRD&lt;/span&gt; concept as &amp;#8220;Test-After-Development&amp;#8221;, which he follows with a chuckle and a twinkle, &amp;#8220;which is a &lt;span class="caps"&gt;TAD&lt;/span&gt; too late.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;2 Of course, one still needs QC testing as well, however &lt;span class="caps"&gt;TDD&lt;/span&gt; is about driving development, not testing its quality post-facto.
&lt;/small&gt;&lt;/p&gt;</description>
      <pubDate>Thu, 02 Aug 2007 22:14:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:bd848598-96fa-4e15-84e8-ccba83ab4325</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2007/08/02/not-a-task-but-an-approach</link>
      <category>Tim's Tepid Torrent</category>
      <category>FIRST</category>
      <category>testing</category>
      <category>mentoring</category>
      <category>TDD</category>
      <category>TRD</category>
      <category>TAD</category>
      <category>Fast</category>
      <category>Isolated</category>
      <category>Repeatable</category>
      <category>Self</category>
      <category>validating</category>
      <category>Timely</category>
    </item>
    <item>
      <title>Tuple Madness and STL in C++</title>
      <description>&lt;p&gt;I have already complained about &lt;a href="http://blog.objectmentor.com/articles/2007/02/13/tuple-madness"&gt;Tuple Madness&lt;/a&gt; with reference to Python and Ruby, and UncleBob has seen &lt;a href="http://butunclebob.com/ArticleS.UncleBob.RubarianNotation"&gt;the same problem&lt;/a&gt; and noted it on the old blog. I have come to realize that the same problems appear in modern C++ code.&lt;/p&gt;


	&lt;p&gt;I have always looked at the &lt;span class="caps"&gt;STL&lt;/span&gt; as a way of implementing a class, but never as a replacement for &amp;#8220;real&amp;#8221; classes with named member values.  In some ways, I think that templates have made our C++ code worse.&lt;/p&gt;


For instance, I need a two-member structure. Say I am going to store Name and Address.  Now, those with C background would immediately think along these lines:
&lt;pre&gt;
    struct name_and_address { char name[34]; struct address address; };
    struct name_and_address get_name_and_address(void);
    // blah blah blah

    struct name_and_address x = get_name_and_address();
    printf("%s", x.name );
    printf("%s", x.address.line1);
    // ... and so on...
    printf("%05d", x.address.zip);
&lt;/pre&gt;

	&lt;p&gt;Got to love those old C programmers. There is a nice, primitive struct, maybe with a nice, primitive struct embedded in it.  Look at the &lt;a href="http://tottinge.blogsome.com/meaningfulnames/"&gt;clear names of those variables&lt;/a&gt;.  It is even pretty efficient to copy these things. With a Plain Old Data Object, the compiler knows what you&amp;#8217;re doing and can do block copies instead of memberwise copies. That can be very efficient, enough that you can often pass structures around by value instead of by reference. That&amp;#8217;s kinda cool. That same efficiency also applies to plain old data classes in C++, but a lot of people don&amp;#8217;t know it.&lt;/p&gt;


	&lt;p&gt;Sadly, a modern C++ developer does what? Yeah, he returns a pair.  This is annoying because when I call my function, I have to know that the name is now called &amp;#8220;first&amp;#8221; and the address is called &amp;#8220;second&amp;#8221;.  But that is only for &lt;em&gt;this&lt;/em&gt; pair-returning function.  In another pair-returning function, &amp;#8220;first&amp;#8221; means birthday and &amp;#8220;second&amp;#8221; is account number.   Of course the prototype is not always in view, so I have to have more tiles in my window to check my work as I code.&lt;/p&gt;


	&lt;p&gt;Pair is named well enough for an arbitrary pair of primitive values, but frankly it makes no sense for x,y coordinates or names and address, or for the rolls of two twenty-sided dice.  Wait.  For the dice, it works just fine.  After all, what would you call them? Dice1 and Dice2?  But I digress.  The point is that for most two-member structures, a two-member structure with named members is probably a better choice.&lt;/p&gt;


Now pair is not alone (oh look, a pun). Even when we are dealing with collections, the interface to a vector, map, or set is unlikely to be the right set of names and semantics for our problem domain objects.  Maybe our property should be listed, and not push_back()-ed.  Maybe we care about a policy, that:
&lt;pre&gt;
        policy.covers(theCar)
&lt;/pre&gt;
Maybe we&amp;#8217;re not so interested in whether list&lt;Insurable&gt; x will:
&lt;pre&gt;
        x.find(z.first) != x.end()
&lt;/pre&gt;

	&lt;p&gt;The fascination with exposing &lt;span class="caps"&gt;STL&lt;/span&gt; containers (combined with unfortunate naming, as given here for effect) is hurting readability. It also is a very unfortunate form of &lt;a href="http://sis36.berkeley.edu/projects/streek/agile/bad-smells-in-code.html#Primitive+Obsession"&gt;primitive obsession&lt;/a&gt; and a violation of the &lt;a href="http://www.google.com/url?sa=t&amp;#38;ct=res&amp;#38;cd=1&amp;#38;url=http%3A%2F%2Fwww.objectmentor.com%2Fresources%2Farticles%2Fdip.pdf&amp;#38;ei=LDGgRr-EDIySgATvodT5DQ&amp;#38;usg=AFQjCNEpBGziZw6APHj0rMG9pp1LJt9FHA&amp;#38;sig2=39HJU1Vlx6jAawt9cM-0zw"&gt;Dependency Inversion Principle.&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;The people who work on your code with you should not have to &lt;em&gt;reverse&lt;/em&gt; &lt;em&gt;engineer&lt;/em&gt; your work in order to add new features or correct  bugs.  The code should be written so clearly that mistaken assumptions will be more obvious. They should not have to chase down typedefs and keep notes on paper to keep track of your structures. They should especially not have to look for data in obliquely named pairs of pairs (x.second.first means &amp;#8220;price&amp;#8221;? Or was that x.first.second? Or&amp;#8230;).&lt;/p&gt;


	&lt;p&gt;If you write your code with a pair programming partner, you should get plenty of feedback about the readability of your code.  Even if you do not work in pairs, you should read your tests when you get back from lunch or a meeting, and you should see if primitive containers, primitive member functions,  and template syntax are obscuring their purpose.  If your tests don&amp;#8217;t speak clearly, then none of the other users of your class can speak clearly.  Get the syntax out of their way by giving them reasonable wrapper functions.&lt;/p&gt;


	&lt;p&gt;You might think that wrapping your containers will cost you performance by adding dispatch here and there, but you might be surprised to find out that not wrapping it may cost you far more by concealing bugs and obscuring functionality than it ever save you in performance. A better policy is to keep your code obvious and simple, and try a little profiling and optimization where it really matters.&lt;/p&gt;


	&lt;p&gt;Of course, if one was worried about the cost of one dispatch for a named method v. an exposed container, there is always the option to build an inline member function in the header.&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;m mindful that this is not the time for me to rant about C++ programmers who never profile, and who manage performance by rule of thumb and old wives&amp;#8217; tales.  There are more of them than us, my dear reader, and I fear their wrath.  Maybe some day later, when I&amp;#8217;m feeling brave.&lt;/p&gt;


	&lt;p&gt;My roots run pretty deep into C++, and I appreciate how hard it is to produce a system.  I just want the guys who are now running with the ball right now to realize that it is far more valuable to be clear and obvious than they appreciate, and it is far less expensive to do so than they fear.&lt;/p&gt;


	&lt;p&gt;I guess the points are:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Don&amp;#8217;t be afraid to write small classes and structs.&lt;/li&gt;
		&lt;li&gt;Don&amp;#8217;t be afraid to wrap your containers.&lt;/li&gt;
		&lt;li&gt;Don&amp;#8217;t be afraid to use abstraction.&lt;/li&gt;
		&lt;li&gt;Everything does not have to be written in templates.  &lt;/li&gt;
		&lt;li&gt;Be afraid to write test code that doesn&amp;#8217;t tell a story.&lt;/li&gt;
		&lt;li&gt;Be afraid to give too much access to your data by exposing containers.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Adjust your values accordingly.&lt;/p&gt;</description>
      <pubDate>Thu, 19 Jul 2007 22:21:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:ceb08ca2-cc05-4ebb-b74d-d0be19b32d26</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2007/07/19/tuple-madness-and-stl-in-c</link>
      <category>Tim's Tepid Torrent</category>
    </item>
    <item>
      <title>Testing Will Challenge Your Conventions</title>
      <description>&lt;p&gt;If you are doing test-first development, you are likely to find your old coding conventions are no longer valid.  There are a few changes you will need to make to your coding standards and practices.&lt;/p&gt;


	&lt;p&gt;1. Interfaces suddenly seem like a really good idea when you have to start introducing test doubles of various flavors (mocks, etc).  You will find yourself creating interfaces in places where you probably would not have created them before.  You&amp;#8217;ve always known that you shouldn&amp;#8217;t depend or derive from concrete classes, and now you are feeling the pain of non-trivial concrete classes. You are forced, more or less, to comply with the Dependency Inversion Principle. Abstraction becomes a way of life.&lt;/p&gt;


	&lt;p&gt;2. Singletons and static methods no longer seem like a great way to do work (esp in C++) because you can&amp;#8217;t easily isolate a module that makes use of them.  The exception is when a static method is totally self-contained and testable, and does not use resources like a database, file system, etc. Only the very trivial can be static. Test doubles matter that much. Suddenly substitutability is a primary measure of code goodness.&lt;/p&gt;


	&lt;p&gt;3. Private makes less sense than it used to.  You can&amp;#8217;t test anything that&amp;#8217;s private.  You need to have ways to sense that your tests are working as intended, and you have to be able to test any method that is interesting. That means less private and more accessors.  Get used to living in a more public world.  If you need to hide something from users, don&amp;#8217;t include it in the interface or abstract base class. &amp;#8220;Implements&amp;#8221;/&amp;#8221;public inheritance&amp;#8221; is the new &amp;#8220;private&amp;#8221;.&lt;/p&gt;


	&lt;p&gt;4. You need to be able to pass a class everything it might need at construction time, so that you can pack it a stubbed logger and a faked database access  module. Otherwise, you will not have the isolation you need to write good unit tests. Calling a concrete class constructor inside the body of a method now makes you cringe, because you realize you&amp;#8217;ve missed an opportunity for abstraction, and limited the isolation of your method.   The fat constructor argument list is a concession to the need for isolation and testing with mocks (and fakes, and stubs).&lt;/p&gt;


	&lt;p&gt;5. Smaller methods are the norm. It is hard to test a two-hundred line method.  It&amp;#8217;s far harder than testing a many smaller, equivalent methods. Whatever is easier to test is easier to write. Large is bad. This has always been so, since optimizers love simple functions, but now it&amp;#8217;s real to you as well.&lt;/p&gt;


	&lt;p&gt;6. You hate inheriting code without tests, because you don&amp;#8217;t want to reverse-engineer what the other programmer was thinking.  In fact, you find yourself looking at tests before you look at code, because you know the tests are better than comments. Testing becomes a kind of &amp;#8220;code clarity&amp;#8221; mechanism.  The profound bit is that code is more clear if it is more testable, even if you have to &amp;#8220;pollute&amp;#8221; the class to make it testable by moving variables and methods out of the private space or by creating interfaces, or by using fat constructor argument lists.  Testability is the new legibility.&lt;/p&gt;


	&lt;p&gt;7. Hard-to-use class interfaces are now hard for you to use, not just hard for other people. You have to write the tests, so you have to use the class. Usability determines how much you will like your own code, not cleverness.&lt;/p&gt;


	&lt;p&gt;8. Performance management by old wives tales is dead.  You will build for testability, and then use measurement tools to improve performance.  This is what the wizened greybeards have been telling us for a lot of years, and with &lt;span class="caps"&gt;TDD&lt;/span&gt; you start listening.  You stop avoiding trivial issues like copying &lt;span class="caps"&gt;PODS&lt;/span&gt; and virtual dispatches.  You pay attention to more important issues.  With optimization, &lt;span class="caps"&gt;YAGNI&lt;/span&gt; applies until it doesn&amp;#8217;t, and when it doesn&amp;#8217;t you need to know why and where.&lt;/p&gt;


	&lt;p&gt;9. You care deeply how long it takes to run the tests because you need to be able to run all of the tests all the time, after only a few lines of code are written, and after each refactoring.  If it&amp;#8217;s taking more than 20 or 30 seconds to run all your unit tests, you start looking for ways to speed it up.  You must maintain test performance, because it is key to productivity.&lt;/p&gt;


	&lt;p&gt;10. Dependency hurts.  You can&amp;#8217;t afford &amp;#8216;god classes&amp;#8217; and &amp;#8216;global hubs&amp;#8217;.  If test setup becomes a chore, you immediately start reaching for the axe.  You have to keep your modules isolated better than ever before.  Of course, you should have done this all along, but you never felt it this keenly.&lt;/p&gt;


	&lt;p&gt;11. &amp;#8220;Clever&amp;#8221; is dead. Clever is hard to refactor. Clever is hard to isolate, hard to internalize, hard to phrase in tests.  One point of &amp;#8220;obvious&amp;#8221; is worth two hundred points of &amp;#8220;clever&amp;#8221;.&lt;/p&gt;


	&lt;p&gt;12. Your &lt;span class="caps"&gt;IDE&lt;/span&gt; is good to the extent that it allows you to do quick write/build/test cycles.  You need to do several per minute.&lt;/p&gt;


	&lt;p&gt;For the most part, &lt;span class="caps"&gt;TDD&lt;/span&gt; forces you to start doing the things you always should have done, though it signals a change in values that should be reflected in your coding standards.&lt;/p&gt;


	&lt;p&gt;Maybe you should get a highlighter and mark each section of your coding standard  or architectural document that encourages any practice that in turn discourages testability.  The world has changed, values have shifted,  and your style guide needs to change if it is to remain relevant.&lt;/p&gt;</description>
      <pubDate>Tue, 17 Jul 2007 22:28:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:b84c2373-e256-429f-a7c2-2e16528c9d81</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2007/07/17/testing-will-challenge-your-conventions</link>
      <category>Tim's Tepid Torrent</category>
    </item>
    <item>
      <title>What I Don't Like About Python</title>
      <description>&lt;p&gt;I love &lt;a href="http//python.org"&gt;python&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;I love the simplicity, the nice data types, the strong dynamic typing, the significant indentation, the runtime flexibility, the list comps, the generators, they way that I can get work done in Python. I love the built-in help. I dig the Tao of Python.&lt;/p&gt;


	&lt;p&gt;There are still a few bits that seem artificial and clumsy.  I was told that you don&amp;#8217;t really know a language if there are not five things you hate about it. I have more than five, but these will do for now:&lt;/p&gt;


&lt;ol&gt;
&lt;li&gt;&lt;b&gt;&lt;dir&lt;/b&gt; Dir is not a very good name for the method that dumps the contents of an object.  I don&amp;#8217;t like the ruby alternative, where methods and members are separate, but I just don&amp;#8217;t like the naming here. A change would be possible. It would have to be grandfathered in, but it could happen.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;double-underscores&lt;/b&gt; annoy me.  I would like to see some other way of denoting operators and other magic functions. I suppose one could grandfather-in a decorator-based trick for defining operators. It would be a real compatibility breaker, but I really feel that &amp;#95;&amp;#95;getitem&amp;#95;&amp;#95; is probably not the best naming our guys could come up with.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&amp;#95;&amp;#95;name&amp;#95;&amp;#95;&lt;/b&gt; has always felt like a hack to me. Try explaining it to a novice programmer, or worse to someone who programs in perl or ruby or java for a living.  Comparing the magic variable &amp;#95;&amp;#95;name&amp;#95;&amp;#95; to the magic constant &amp;#8221;&amp;#95;&amp;#95;main&amp;#95;&amp;#95;&amp;#8221; feels doubly so.  I would rather have a convention such as naming a method &amp;#8220;main&amp;#8221; or maybe decorating with @script_main now that we have decorators.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Blocks&lt;/b&gt; give me of ruby envy or smalltalk envy.  I like local functions. Love them.  I tolerate lambda.  But I really, really would like to see a more rubyesque iterator setup where we pass a callable to the list, and the callable can be defined free-form inline. Python doesn&amp;#8217;t really do that and so it&amp;#8217;s less of a language lab than I might like.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Properties&lt;/b&gt; are unattractive, partly because of blocks being absent.  I don&amp;#8217;t really want to define a named parameter (with double-underscores, most likely) and then two named functions, and &lt;span class="caps"&gt;THEN&lt;/span&gt; declare a property.  That seems like so much work for such a simple situation. It is something I will only do if all other methods fail me, or if all other methods are overriding &amp;#95;&amp;#95;setattr&amp;#95;&amp;#95; and &amp;#95;&amp;#95;getattr&amp;#95;&amp;#95;.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Lack of recognition&lt;/b&gt; just kills me.  This is a wonderful little language with great libraries and tremendous capability.  Google, Eve, Nasa, a great many scientific efforts, a bunch of web sites, and a lot of Linux installers and configuration tools use python.  A number of very nice distributed version control tools are written in it. But still people seem to go deaf if anyone mentions python, as if we&amp;#8217;d mentioned &lt;span class="caps"&gt;JCL&lt;/span&gt; or something.  I don&amp;#8217;t get that.&lt;/li&gt;
&lt;li&gt;There is a very ugly &lt;b&gt;mutual-inclusion design bug bug&lt;/b&gt;. I spent time on it once and was very unhappy.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Self&lt;/b&gt; loathing takes over in my functions. I wish that I could refer to member variables without saying &amp;#8220;self.&amp;#8221; first. Testing would be easier if I could just import all my fixture variables into my local namespace&amp;#8212;or better if it were done for me automagically.  Typing &amp;#8220;self.&amp;#8221; doesn&amp;#8217;t kill me, but it doesn&amp;#8217;t help me.  Yes, I have an abbreviation in my editor, but it still bugs me.&lt;/li&gt;
&lt;/ol&gt;

	&lt;p&gt;Don&amp;#8217;t put me down as a complainer.  I really, really love working in python. But  There&amp;#8217;s a lot more love than hate here.&lt;/p&gt;


	&lt;p&gt;PS: Is it uncommonly sensible that &amp;#8220;not&amp;#8221; is spelled &amp;#8220;not&amp;#8221;, &amp;#8220;and&amp;#8221; is spelled &amp;#8220;and&amp;#8221; and &amp;#8220;or&amp;#8221; is spelled &amp;#8220;or&amp;#8221;?  I think so.  &amp;#38;&amp;#38; I&amp;#8217;m ! just kidding || something.&lt;/p&gt;</description>
      <pubDate>Tue, 17 Jul 2007 21:41:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:0709a2f0-37ac-4cec-b4ed-6b48b6098d9f</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2007/07/17/what-i-dont-like-about-python</link>
      <category>Tim's Tepid Torrent</category>
    </item>
    <item>
      <title>Dependency Broadcaster</title>
      <description>&lt;p&gt;I&amp;#8217;m not sure if there is already a code smell name for this situation. The idea is rather like &amp;#8220;Large Class&amp;#8221; or &amp;#8220;God Class&amp;#8221; but isn&amp;#8217;t really related to behaviour.  It&amp;#8217;s just a matter of dependency.&lt;/p&gt;


	&lt;p&gt;Michael Feathers refers to &amp;#8220;horrible include dependencies&amp;#8221;, and that&amp;#8217;s the right idea.&lt;/p&gt;


	&lt;p&gt;So what if you have a class file that includes (or forward-declares) a few hundred other classes, and that class is used by almost every other class in the system?&lt;/p&gt;


	&lt;p&gt;This is perhaps what comes from writing a very class-rich architectural layer as a single class.&lt;/p&gt;


	&lt;p&gt;Mainly the idea is that the class takes a lot of ugly dependencies and spreads them evenly over the application.  I would call that &amp;#8220;broadcasting&amp;#8221; although the correct agrarian term is &amp;#8220;manure spreader.&amp;#8221;  I will stick with the less evocative &amp;#8220;dependency broadcaster.&amp;#8221;&lt;/p&gt;</description>
      <pubDate>Mon, 16 Jul 2007 20:34:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:6cf4342a-6506-4112-b624-995e27368fc4</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2007/07/16/dependency-broadcaster</link>
      <category>Tim's Tepid Torrent</category>
    </item>
    <item>
      <title>Use VIM to do TUT Unit Testing</title>
      <description>&lt;p&gt;I&amp;#8217;m not crazy about &lt;span class="caps"&gt;TUT&lt;/span&gt;, but a customer is using it on a project and wanted to get a little assist from &lt;span class="caps"&gt;VIM&lt;/span&gt;.  I don&amp;#8217;t blame him. It&amp;#8217;s a pain to keep track of your test number and there&amp;#8217;s always more testing that we&amp;#8217;d like in our test frameworks.&lt;/p&gt;


	&lt;p&gt;So I scribbled up a little &lt;span class="caps"&gt;VIM&lt;/span&gt; script to handle some of the light housekeeping.  It&amp;#8217;s not a wonderful script, and I&amp;#8217;m betting the readers can give me some pointers (I&amp;#8217;ve only written a few other vimscripts ever). I&amp;#8217;m sure that I could do better if I reflected and refactored, but I haven&amp;#8217;t yet.&lt;/p&gt;


	&lt;p&gt;Maybe you know a good way to unit test vim scripts?.&lt;/p&gt;


	&lt;p&gt;My script hijacks your F5 key. You can change that easily enough.  Maybe I should have mapped it to \nt for &amp;#8220;new test&amp;#8221; or something.  Anyway, enjoy and comment please:&lt;/p&gt;


&lt;pre&gt;

function! NewTutTest()
    let s:testNumber = 0
    let s:newNumber = 0
    " Seek a higher number
    let s:list = getline("1","$")
    for s:line in s:list
        if s:line =~ 'test&amp;lt;'
            let s:newNumber =  0 + matchstr(s:line, '\d\+')
            if s:newNumber &amp;gt; s:testNumber
                let s:testNumber = s:newNumber
            endif
        endif
    endfor

    "Increment (tests are 1..n)
    let s:testNumber = s:testNumber + 1

    "Output the test values
    let s:line = line(".")
    let s:indent = repeat(" ", &amp;#38;shiftwidth)
    let result = append(s:line, s:indent . "template&amp;lt;&amp;gt;")
    let s:line = s:line + 1
    let result = append(s:line, s:indent . "template&amp;lt;&amp;gt;")
    let s:line = s:line + 1
    let result = append(s:line, s:indent . "void object::test&amp;lt;" . s:testNumber . "&amp;gt;()")
    let s:line = s:line + 1
    let result = append(s:line, s:indent . "{" )
    let s:line = s:line + 1
    let result = append(s:line, repeat(s:indent,2) )
    let s:line = s:line + 1
    let result = append(s:line, s:indent . "}" )
    call cursor(s:line, (&amp;#38;shiftwidth * 2))

endfunction

" Paste a version of this line into .vimrc to assign a keystroke (in this case F5)
" Comment-out this version if you do
" --------------------------------
map &amp;lt;F5&amp;gt; :call NewTutTest()&amp;lt;CR&amp;gt;Aset_test_name(" 

" Some helpful macros for command mode. Press \ten and it opens a new line
" and types ensure(" so you can fill in the string and the parameters.
" Overall, not too shabby.
map \tn oensure(" 
map \te oensure_equals(" 
map \td oensure_distance(" 
map \tf ofail(" 

" Abbreviations to help you in insert mode. Type the 
" two-letter name, followed by a quote.
ab tn ensure(
ab te ensure_equals(
ab td ensure_distance(
ab tf fail(

&lt;/pre&gt;</description>
      <pubDate>Wed, 11 Jul 2007 09:47:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:59fa76b6-51eb-4607-ad92-82e21bd54a70</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2007/07/11/use-vim-to-do-tut-unit-testing</link>
      <category>Tim's Tepid Torrent</category>
    </item>
    <item>
      <title>Revisit: The common subgroups</title>
      <description>&lt;p&gt;In cleaning up the code, I simplified the algorithm a very little and improved performance considerably.  Amazing how that works, how simpler equals faster for so much code.  Adding simple data structures, local explanatory functions, and the like often make code much faster.&lt;/p&gt;


	&lt;p&gt;What I&amp;#8217;m hoping is that I will use this in a few different and useful ways.&lt;/p&gt;


	&lt;p&gt;The first way is to look for interfaces where concrete classes are being used from many other classes.  You need to add an interface, but don&amp;#8217;t know who needs which part. The goal is to figure out a relatively small number of interfaces that satisfy a number of clients in a module.&lt;/p&gt;


	&lt;p&gt;The second use would be to look for common clumps of parameters when I&amp;#8217;m working in a large code base where the average number of arguments per function call does not remotely approach one.  I suspect that there are clumps of similarly-named variables being passed around, and that these are likely &amp;#8220;missed classes&amp;#8221;.  Sometimes these are obvious, but it would be good to see them in a nice list spit out from a nice tool.&lt;/p&gt;


	&lt;p&gt;So this is a hopeful start on a series of useful tools.&lt;/p&gt;


	&lt;p&gt;Code follows.&lt;/p&gt;


&lt;pre&gt;
import shelve
import sys

def find_groups(input):
    """ 
    Exhaustively searches for grouping of items in a map, such
    that an input map like this:
        "first":[1, 2, 3, 4],
        "second":[1,2,3,5,6],
        "third":[1,2,5,6]
    will result in:
        [1,2,3]: ["first","second"]
        [1,2]: ["first","second","third"]
        [5,6]: ["second","third"]

    Note that the return value dict is a mapping of frozensets to sets,
    not lists to lists as given above. Also, being a dict, the results
    are effectively unordered.
    """ 
    def tupleize(data):
        "Convert a set or frozenset or list to a tuple with predictable order" 
        return tuple(sorted(set(data)))

    def append_values(map, key, *values):
        key=tupleize(key)
        old_value = map.get(key,[])
        new_value = list(old_value) + list(values)
        new_value = tupleize(new_value)
        map[key] = new_value
        return key, new_value

    result = {}
    previously_seen = {}
    for input_identity, signatures in input.iteritems():
        input_signatures = set(signatures)
        for signature_seen, identities_seen in previously_seen.iteritems():
            common_signatures = set(signature_seen).intersection(input_signatures)
            if len(common_signatures) &amp;gt; 1:
                known_users = list(identities_seen) + [input_identity]
                append_values(result, common_signatures, *known_users)
        append_values(previously_seen, signatures, input_identity)
    return filter(result)

def filter(subsets):
    filtered = {}
    for key,value in subsets.iteritems():
        if (len(key) &amp;gt; 1) and (len(value) &amp;gt; 1):
            filtered[key] = set(value)
    return filtered

def display_groupings(groupings):
    "Silly helper function to print groupings" 
    keys = sorted(groupings.keys(), cmp=lambda x,y: cmp(len(x),len(y)))
    for key in keys:
        print "\n","-"*40
        for item in key:
            print item
        for item in sorted(groupings[key]):
            print "     ",item
        print

&lt;/pre&gt;</description>
      <pubDate>Tue, 03 Jul 2007 10:43:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:bda9c375-df64-42f1-9fe3-627b9d354ec1</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2007/07/03/revisit-the-common-subgroups</link>
      <category>Tim's Tepid Torrent</category>
      <category>python</category>
      <category>algorithm</category>
      <category>optimized</category>
      <category>clean</category>
    </item>
    <item>
      <title>Python Subgroup Detection and Optimization</title>
      <description>&lt;p&gt;I had a moderately interesting customer problem to work on.  I got acquainted with a bit of legacy code that is seriously in need of some interface segregation.  It&amp;#8217;s an entirely concrete class and used from all over the code base. The question is how to segregate, and that depends on what methods are called from which programs. We ran &amp;#8216;nm&amp;#8217; to extract the link table from our object files, saving me the trouble of parsing C++ (a scary thought) All that remained was for me to compare the method prototypes used by the object files and find the common sets.&lt;/p&gt;


	&lt;p&gt;Lacking better ideas, I decided to do this exhaustively in a brute-force kind of way.  It is only a few hundred files, so it shouldn&amp;#8217;t take too long. I was very wrong. It took a long time and eventually failed.&lt;/p&gt;


	&lt;p&gt;I had &lt;span class="caps"&gt;TDD&lt;/span&gt;-ed the code, so I had tests of correctness, and I relied on these as I added optimizations, but of course the performance problem occurred only under a real load.&lt;/p&gt;


	&lt;p&gt;I could have run a profiler on it (and probably should have) but instead I simply monitored my computer. I quickly saw that my time was going into memory allocation, which is also the reason it died after many minutes When I have python performance problems, this is usually the reason, and almost never &amp;#8220;interpreter drag&amp;#8221;.&lt;/p&gt;


	&lt;p&gt;My friend Norbert (a gentleman of many programming languages, including ruby) suggested that I wasn&amp;#8217;t interning my strings, and of course I was not.  I switched to interning strings, and noticed a little improvement which meant the program ran &lt;em&gt;longer&lt;/em&gt; before failing from memory problems. Well, the tests still passed, so I knew at least that the logic was still good even if the algorithm was primitive and Occam was spinning in his grave.&lt;/p&gt;


	&lt;p&gt;Next I realized that I am dealing with a lot of small groups of strings, and in a leap of optimism/faith/stupidity I decided to intern groups of strings. That helped very little, but it did help since my program was now running for the better part of an hour (!!!) and then failing. &amp;#8220;More of same&amp;#8221; without measurement is hardly a good recipe for optimization.&lt;/p&gt;


	&lt;p&gt;This is when I realized that I shouldn&amp;#8217;t be storing sets or frozensets, which are pretty heavyweight data structures. I had chosen them because I was really working with set intersections, but hadn&amp;#8217;t counted the in-memory storage cost. I converted the data structure used by the algorithm and added a local function to make tuples out of the sorted sets.&lt;/p&gt;


	&lt;p&gt;I was very glad to have my tests to catch me when I had some typing mistake or sloppy conversion.  My tests had to be edited, but the changes there were very lightweight, and caused me to abstract out some data comparisons that were (admittedly) repeated. It was all good.&lt;/p&gt;


	&lt;p&gt;When I ran the full program it completed so quickly that I was sure I&amp;#8217;d broken it.  It was running with sub-second time, including gathering data from various text files (nm output files).  I did a few spot-checks, and determined that it was indeed doing the right thing (as far as I know).&lt;/p&gt;


	&lt;p&gt;The data is moderately interesting, and I will be able to pick out some useful interfaces.  Better yet, I have a program that can pick out all the uses of my big, fat class and recommend interfaces to me.  This is all good.&lt;/p&gt;


Lessons learned:
&lt;ul&gt;
&lt;li&gt;The tests gave me peace of mind as I worked.  I would so hate to have done this &amp;#8220;naked&amp;#8221;.&lt;/li&gt;
&lt;li&gt;Python&amp;#8217;s speed is fine (even startling) if you aren&amp;#8217;t doing something wasteful and heavy-handed like storing hundreds or thousands of non-interned strings and heavyweight data structures&lt;/li&gt;
&lt;li&gt;I could have been done sooner if I&amp;#8217;d measured with hotshot instead of guessing. This is very clear to me, and I won&amp;#8217;t think I&amp;#8217;m too clever or my problem is too simple to do this ever again.&lt;/li&gt;
&lt;li&gt;Keep some ruby friends on hand. They come in handy.&lt;/li&gt;
&lt;li&gt;I didn&amp;#8217;t really need a cooler algorithm.  Brute force is sometimes enough.&lt;/li&gt;
&lt;/ul&gt;

	&lt;p&gt;I want to build a new wrapper for this code to compare parameter lists, to help find unrecognized classes in these same programs.  It shouldn&amp;#8217;t be too hard, but it will be a larger data set so I will probably need some more optimization or a cooler algorithm later. I think I see some waste in it now, but I guess I&amp;#8217;ll have to fix that after blogging.&lt;/p&gt;


	&lt;p&gt;Of course, I&amp;#8217;m not done learning.  I am sure there are a lot of ways to improve the core code. I also believe in other people, that I should make it available to criticism and suggestions.&lt;/p&gt;


	&lt;p&gt;Here it is:&lt;/p&gt;


&lt;h3&gt;Tests&lt;/h3&gt;
(Which, embarassingly, could use more refactoring)
&lt;pre&gt;
import unittest
import clumps

def keySet(someMap):
    return set(someMap.keys())

class ClumpFinding(unittest.TestCase):
    def testNoGroupsForSingleItem(self):
        input = { "OneGroup": [1,2] }
        actual = clumps.find_groups(input)
        self.assertEquals({}, actual)

    def testNoOverlapMeansNoGroups(self):
        input = {
            "first": [1,3],
            "second": [2,4]
        }
        actual = clumps.find_groups(input)
        self.assertEquals({}, actual)

    def testIgnoresSingleMatches(self):
        input = {
            "first": [1,3],
            "second": [1,4]
        }
        actual = clumps.find_groups(input)
        self.assertEquals({}, actual)

    def testTwoInterfaceMatches(self):because of
        group = (1,2)
        names = ("first","second")
        input = dict( [(name,group) for name in names])

        actual = clumps.find_groups(input)

        self.assertEquals(1, len(actual))
        [key] = actual.keys()
        self.contentMatch(group, key)
        self.contentMatch(input.keys(), actual[key])

    def contentMatch(self, left,right):
        left,right = map( frozenset, [left,right])
        self.assertEquals(left,right)

    def testFindsThreeGroupsMatchingExactly(self):
        group = [1,3,8]
        names = "one","two","three" 
        input = dict( [(name,group) for name in names ] )

        actual = clumps.find_groups(input)

        self.assertEquals(1, len(actual))
        [clump_found] = actual.keys()
        self.contentMatch(group, clump_found)
        self.contentMatch(names, actual[clump_found])

    def testFindsPartialMatchInThreeGroups(self):
        input = {
            "a":[1,2,3,4,5],
            "b":[1,4,5,6,8],
            "c":[0,1,4,5]
        }
        target_group = frozenset([1,4,5])
        names = input.keys()

        actual = clumps.find_groups(input)

        [key] = actual.keys()
        self.contentMatch(target_group, key)
        self.contentMatch(names, actual[key])

    def testFindsMultipleMatches(self):
        input = {
            "a":[1,2,3,4,5],
            "b":[1,4,5,6,8],
            "c":[0,1,4,5],
            "d":[1,2,3],
            "e":[1,3]
        }

        actual = clumps.find_groups(input)
        keys = actual.keys()

        self.assertEqual(3, len(actual))

        grouping = (1,2,3)
        referents = set(["a","d"])
        self.assert_(grouping in keys, "expect %s in %s" % (grouping,keys) )
        self.assertEqual(referents, actual[grouping])

        grouping = (1,4,5)
        referents = set(["a","b","c"])
        self.assert_(grouping in keys)
        self.assertEqual(referents, actual[grouping])

        grouping = (1,3)
        referents = set(["a","d","e"])
        self.assert_(grouping in keys)
        self.assertEqual(referents, actual[grouping])

if __name__ == "__main__":
    unittest.main()
&lt;/pre&gt;

&lt;h3&gt;The Code&lt;/h3&gt;

&lt;pre&gt;
import sys

def find_groups(named_groups):
    """ 
    Exhaustively searches for grouping of items in a map, such 
    that an input map like this:
          "first":[1, 2, 3, 4],
          "second":[1,2,3,5,6],
          "third":[1,2,5,6]
    will result in:
        [1,2,3]: ["first","second"]
        [1,2]: ["first","second","third"]
        [5,6]: ["second","third"]

    Note that the return value dict is a mapping of frozensets to sets,
    not lists to lists as given above. Also, being a dict, the results
    are effectively unordered.
    """ 
    def tupleize(data):
        "Convert a set or frozenset or list to a tuple with predictable order" 
        return tuple(sorted(list(data)))

    result = {}
    for name, methods_called in named_groups.iteritems():
        methods_group = frozenset(methods_called)
        methods_tuple = tupleize(methods_group)
        for stored_interface in result.keys():
            key_set = frozenset(stored_interface)
            common_methods = tupleize(key_set.intersection(methods_group))
            if common_methods:
                entry_as_list = list(result.get(common_methods,[]))
                entry_as_list.append(name)
                entry_as_list.extend( result[stored_interface] )
                result[common_methods] = tupleize(entry_as_list)

        full_interface_entry = result.setdefault(methods_tuple, [])
        if name not in full_interface_entry:
            full_interface_entry.append(name)
    return filter(result)

def filter(subsets):
    # Apology: I'm betting I can do this in a functional way.
    filtered = {}
    for key,value in subsets.iteritems():
        if (len(key) &amp;gt; 1) and (len(value) &amp;gt; 1):
            filtered[key] = set(value)
    return filtered

def display_groupings(groupings):
    "Silly helper function to print groupings" 
    keys = sorted(groupings.keys(), cmp=lambda x,y: cmp(len(x),len(y)))
    for key in keys:
        print "\n","-"*40
        for item in key:
            print item
        for item in sorted(groupings[key]):
            print "     ",item
        print

&lt;/pre&gt;</description>
      <pubDate>Wed, 27 Jun 2007 23:23:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:5615a4c9-4a82-447e-92e1-ff331d47a48f</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2007/06/27/python-subgroup-detection-and-optimization</link>
      <category>Tim's Tepid Torrent</category>
    </item>
    <item>
      <title>The Things That Pass For Simple I Can't Understand</title>
      <description>&lt;p&gt;(with apologies to Steely Dan for the nearly-lyrical title)&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;ve noticed that &amp;#8220;Do the simplest thing that might possibly work&amp;#8221; gets universal agreement in principle, and great divergence in practice.&lt;/p&gt;


	&lt;p&gt;Is a set of variables related by name prefix simpler than a named class containing the same variables?  In the &amp;#8220;fewest number of the fewest things&amp;#8221; sense, I see a group of variables as a lot more to manage than a class.  I can&amp;#8217;t understand why some people pass the same group of loose variables to a number of methods. Isn&amp;#8217;t a seven-argument method &amp;#8220;complex&amp;#8221;?&lt;/p&gt;


	&lt;p&gt;Is a custom exception &amp;#8220;fancy&amp;#8221; or &amp;#8220;trivial&amp;#8221;?  I&amp;#8217;ve had that discussion recently.  Some feel one way, some the other.  Is it more complex to throw a standard exception type and then try to figure out what it means elsewhere?&lt;/p&gt;


	&lt;p&gt;Is event-handling simpler than polling?  I&amp;#8217;ve heard this one too.  I don&amp;#8217;t know how other people see it.  I think events have more complex plumbing, but that polling has a greater run-time complexity because of failure modes (periodicity issues, race conditions, etc).  I think that it is simpler if you have fewer problems to look out for.&lt;/p&gt;


	&lt;p&gt;If you need a fixed set of java instances, is an enum simple or fancy?  Here you have a newer language feature, but it exists to simplify the management of a fixed set of instances, so it leaves you less to deal with, no?&lt;/p&gt;


	&lt;p&gt;Is &amp;#8220;more primitive&amp;#8221; simpler? How about if you use arrays and integer indices into a string rather than a list of strings? Is that simpler or more complex?  Is the Bowling Game &amp;#8220;simple&amp;#8221; because it uses a primitive array and a separate array counter instead of custom objects?&lt;/p&gt;


	&lt;p&gt;In C++, is it simpler to have a struct that contains two data members or to use the pair&amp;lt;&amp;gt; template?  Is it &amp;#8220;simpler&amp;#8221; that you have to refer to them as &amp;#8220;first&amp;#8221; an &amp;#8220;second&amp;#8221;?  Or is that just more obscure?  I think that &amp;#8220;obvious&amp;#8221; is more simple.&lt;/p&gt;


	&lt;p&gt;I am not sure how other people judge simple.  I think &amp;#8220;simple to use&amp;#8221;, &amp;#8220;less bookkeepping&amp;#8221;, &amp;#8220;harder to mess up&amp;#8221;, &amp;#8220;less setup to call&amp;#8221;, &amp;#8220;fewer parameters&amp;#8221; are simpler.  Other people seem to have contrary thoughts.&lt;/p&gt;


	&lt;p&gt;Clearly simple involves more than &amp;#8220;least thought&amp;#8221; or &amp;#8220;most primitive data components&amp;#8221;.  It should have something to do with the lack of effort in using something and the ease with which things can be used correctly.  Well, clearly to me.   And it should have to do with the least difficulty in reading the resulting code, and the least difficulty in changing it.&lt;/p&gt;


	&lt;p&gt;Unrelated to this, I find some tools that others find simple to be baffling, and some tools that are complex to others seem pretty easy to use to me.  I suppose that&amp;#8217;s a kind of &amp;#8220;personal taste&amp;#8221; but is there a more reliable rule to base &amp;#8220;simple&amp;#8221; on than personal choice? There should be if the rule is for us all to do the simplest thing that works, and to maintain the simplest design we can afford to build.&lt;/p&gt;


	&lt;p&gt;But I have unique viewpoints sometimes, and maybe simple to you isn&amp;#8217;t simple to me.  Personally, some of the things that are simple to you may be all but inscrutable to me.  I guess that happens.&lt;/p&gt;</description>
      <pubDate>Thu, 14 Jun 2007 00:19:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:38d1dd7b-6090-4f9d-aff6-f0ece6016e14</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2007/06/14/the-things-that-pass-for-simple-i-cant-understand</link>
      <category>Tim's Tepid Torrent</category>
    </item>
    <item>
      <title>Collateral Effort Revisited</title>
      <description>&lt;p&gt;One of the things I love about &lt;span class="caps"&gt;TDD&lt;/span&gt; is that it takes all the scaffolding and collateral effort for creating a class, all indications of bad coupling, and makes them entirely visible. This is also one thing that makes it very hard to start &lt;span class="caps"&gt;TDD&lt;/span&gt; in legacy system.&lt;/p&gt;


	&lt;p&gt;When you realize that it&amp;#8217;s very hard to test a class out-of-context, the right answer is to start decoupling each class so it can be run out-of-context. When we are successful here, tests run very very fast and are easily self-verifying and isolated.  It is a beautiful thing even if it follows many ugly hours of painstaking work.&lt;/p&gt;


	&lt;p&gt;The wrong answer, I&amp;#8217;m convinced, is to build a mega-framework for testing that allows you to test in-context. This type of framework typically creates a totally realistic runtime environment (complete with database, configuration files, directories, etc).  This approach allows you to think that you can ignore your dependency nightmare. You really can not Mega-test-frameworks take a such a long time to run that developers stop running all the tests all the time.  This is a far worse problem than breaking dependencies because it breaks the whole process.  Mega-frameworks don&amp;#8217;t solve the problem, they only defer the solution until the problem gets worse.&lt;/p&gt;


	&lt;p&gt;When you are faced this kind of collateral effort, the answer is to work through it, not to sweep it under a rug.  Working through it is work, indeed, but this is about doing the right thing not doing the easiest thing.&lt;/p&gt;</description>
      <pubDate>Mon, 11 Jun 2007 20:36:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:925c8e61-d709-4523-adaf-b2646602d831</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2007/06/11/collateral-effort-revisited</link>
      <category>Tim's Tepid Torrent</category>
      <trackback:ping>http://blog.objectmentor.com/articles/trackback/8778</trackback:ping>
    </item>
    <item>
      <title>The Myth of  Learning Compression</title>
      <description>&lt;p&gt;There is an odd idea that learning is compressible, that any training course of any length can be squeezed into a very small time box and delivered to any large number of people without significant loss.&lt;/p&gt;


	&lt;p&gt;As an educator and as a guy who has a pretty big learning load at any time, I know that this is a myth.  I can cover any topic much better if I am working with a handful of individuals over the course of a week or two.  If you double the number of attendees, then the interactivity is highly degraded, and discussions become time sinks.  If you half the time, then interactivity is likewise degraded, and material that might have been covered must be skipped or skimmed.&lt;/p&gt;


	&lt;p&gt;I have a joke with my coworkers that the ideal environment for some large corporations would be a three-train roller coaster.  The participants would buy a ticket, climb on board, sail past the materials at speeds in excess of 60 miles per hour, and would collect their certificate at the other end.  As one train is unloading, another is loading, and another is in progress so that we could cover many hundreds or thousands of students per day.  Of course, they would learn next to nothing and would not really participate at all.&lt;/p&gt;


	&lt;p&gt;But I respect my corporate customers, including the fact that they have much to do, and cannot easily afford a one-week work-stop for each dozen team members, all with consultant/trainer fees.  Some large organizations would have us on-site for years in a row before all their developers would be trained in any technology.  It&amp;#8217;s just not reasonable, and they push for a more feasible schedule.&lt;/p&gt;


	&lt;p&gt;It&amp;#8217;s a rock and a hard place, and people on both sides understand that it is so.&lt;/p&gt;


	&lt;p&gt;The good news is that compressibility is not a total myth.  There are techniques and tools that can make the training more effective, so that less time is necessary in class.  There is the idea of a jump-start, where a topic is introduced and discussed in a short time and students are given materials on which they can continue via self-training.  The compressibility myth drives us to more dense and useful presentation.   It is a valuable spur.&lt;/p&gt;


	&lt;p&gt;It also has the advantage of the time box.  If you have only three days to teach someone how to &lt;span class="caps"&gt;TDD&lt;/span&gt;, you have to choose the three most important days-worth of material to teach.  This kind of prioritization is the same thing that we demand of our product owners in a scrum, and is perfectly fair and reasonable.&lt;/p&gt;


	&lt;p&gt;Even though compressibility is a myth, it is a useful myth.&lt;/p&gt;


	&lt;p&gt;The only mythological part of the compression myth is the idea that it is lossless.   It is lossy compression.  But as is the case with audio and visual compression, compressed learning can be &amp;#8220;good enough.&amp;#8221;   If that&amp;#8217;s what we&amp;#8217;re after, it&amp;#8217;s all good.&lt;/p&gt;</description>
      <pubDate>Thu, 24 May 2007 13:56:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:c23ca614-9695-4be6-bcd7-1b698ceb5040</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2007/05/24/the-myth-of-learning-compression</link>
      <category>Tim's Tepid Torrent</category>
    </item>
    <item>
      <title>Unit Tests Coverage: Less Is More</title>
      <description>&lt;p&gt;In &lt;span class="caps"&gt;TDD&lt;/span&gt; a unit test has to be very small to isolate failures.  This does funny things to code coverage as a metric.  Each test should have a very small area of effect, and so each unit test should have a negligible effect on the overall code coverage statistic.  Bear with me here, see where I&amp;#8217;m missing out.&lt;/p&gt;


	&lt;p&gt;Say you have an existing (legacy) system with no coverage at all.  Zero percent.  If you start doing &lt;span class="caps"&gt;TDD&lt;/span&gt; today, the overall coverage percentage should barely change at all. If only the new code is test-driven, then the old code is not gaining coverage except where tests are necessary to ensure that the new code is being called.  The low coverage per test is a good thing because it shows that the unit tests have good isolation.  In such a situation, code coverage is really telling you the ratio of new code to old code.  Again, this is so obvious and logical to me that I must be missing some cool subtleties.&lt;/p&gt;


	&lt;p&gt;If all the code was test-driven from the beginning, you should have a very high coverage number, and writing a new unit test &lt;strong&gt;before&lt;/strong&gt; you add code should not impact that number.  You only write enough code to pass the test, so again you aren&amp;#8217;t getting much in the way of uncovered code. A lowering of the ratio might indicate a problem with test-to-production-code ratio.  This seems pretty simple and logical, so I&amp;#8217;m sure I&amp;#8217;m missing some interesting corner cases.&lt;/p&gt;


	&lt;p&gt;&lt;span class="caps"&gt;OTOH&lt;/span&gt;, system tests and integration tests paths through many components at once, and should have a more significant effect on coverage in a previously-untested system, though their job is to prove function points, not to raise the metrics.  These non-unit tests are the thing that boost your coverage of old code. That is also a good effect, because it is the goal of the system test to ensure that the parts work together.&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;m not saying that code coverage should be low, only that as we move incrementally, the unit tests we write should individually have negligible effect on our overall code coverage numbers&amp;#8230; a thought that intrigues me.&lt;/p&gt;</description>
      <pubDate>Mon, 07 May 2007 08:06:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:1bd6fe5d-c5ff-4269-a20d-87e7d57443d8</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2007/05/07/unit-tests-coverage-less-is-more</link>
      <category>Tim's Tepid Torrent</category>
    </item>
    <item>
      <title>CppUnit and Vim </title>
      <description>&lt;p&gt;I&amp;#8217;m playing with ways to make &lt;span class="caps"&gt;CPPUNIT&lt;/span&gt; and &lt;span class="caps"&gt;VIM&lt;/span&gt; a bit more agile for my C++ teams.&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;ve been hearing about great lengths people go to, flipping back and forth between .h and cpp for the tests or writing perl scripts to coalesce them together. I&amp;#8217;m too simple-minded for that.  I figure nobody wants to #include my tests, so I don&amp;#8217;t need a .h.  I do it all in the .cpp file, all inline.  It works fine.  This way, everything is in one place.  I don&amp;#8217;t have to jump up to the header file to add a protoype and then down to the implementation to add the &lt;span class="caps"&gt;CPPUNIT&lt;/span&gt;_TEST line, and then back down to my code to enter it.  I have no .h, so no prototype.  Inline makes it a bit more like pyunit or junit.&lt;/p&gt;


	&lt;p&gt;I grokked the CompilerOutputter  pretty quick.  If you use the quickfix mode (and esp if you use :cw) you will definitely want the CompilerOutputter.  I like the way it helps me move from testing error to testing error (err.. if there were ever more than one), just as it does with compile errors (errr.   if they happen.  They do).  I set up my makefiles to run the tests, so there&amp;#8217;s no additional step required.  That&amp;#8217;s handy.  I also have the makefile run ctags to make my navigation nice and easy.&lt;/p&gt;


	&lt;p&gt;Still, adding and removing tests takes some effort.  I figure &lt;span class="caps"&gt;VIM&lt;/span&gt; can take up the slack. I have macros to start up a new test file (F2), to add a test class(F11), to register a function(F12), and to delete a function and its &lt;span class="caps"&gt;CPPUNIT&lt;/span&gt;_TEST line (F9) .&lt;/p&gt;


	&lt;p&gt;I also abbreviate most of the macros that I would otherwise have to type.  I am thinking about remapping them maybe to more memorable values, but it helps.&lt;/p&gt;


	&lt;p&gt;There are probably a lot more elegant ways to do this.  I can&amp;#8217;t wait to hear about them.&lt;/p&gt;


&lt;pre&gt;
 " Add methods to help create CPPUNIT classes
function! NewCppUnitFile()
    call NewCppUnitClass()
    0r~/.cppunit_file_template.vim
endfunction

function! NewCppUnitClass() 
    r~/.cppunit_class_template.vim
    let name = input("Name your new test class: ")
    exec "%s/@@@NAMEHERE@@@/" . name . "/g" 
endfunction

nmap &amp;lt;F2&amp;gt; :call NewCppUnitFile()&amp;lt;CR&amp;gt;
nmap &amp;lt;F9&amp;gt;  ^f(b*ddN0d/{&amp;lt;CR&amp;gt;d%
nmap &amp;lt;F11&amp;gt; G:call NewCppUnitClass()&amp;lt;CR&amp;gt;
nmap &amp;lt;F12&amp;gt; ebmz"zyw?CPPUNIT_TEST_SUITE_END(&amp;lt;CR&amp;gt;OCPPUNIT_TEST(&amp;lt;C-R&amp;gt;z);&amp;lt;ESC&amp;gt;'z

" CPPUnit abbreviations
ab cas CPPUNIT_ASSERT
ab cam CPPUNIT_ASSERT_MESSAGE
ab cfa CPPUNIT_FAIL
ab caf CPPUNIT_FAIL
ab cae CPPUNIT_ASSERT_EQUAL
ab cat CPPUNIT_ASSERT_THROW
ab cde CPPUNIT_ASSERT_DOUBLES_EQUAL
&lt;/pre&gt;

	&lt;p&gt;The current rhythm is to open a new file and press F2.  F2 calls NewCppUnitFile, which sucks in my file header template.  It&amp;#8217;s pretty bare, but it can be edited to taste.  Mostly it helps me remember what to include.&lt;/p&gt;


&lt;pre&gt;
    #include &amp;lt;cppunit/TestFixture.h&amp;gt;
    #include &amp;lt;cppunit/extensions/HelperMacros.h&amp;gt;
&lt;/pre&gt;

	&lt;p&gt;Then I give the name of my first test class.  I get a starter class.  I can then add it to the makefile (note to self: automate the makefile bit).  the starter template I have has a dummy test, so  I can run it and see if it fails.  Failing means it&amp;#8217;s being built and run.&lt;/p&gt;


&lt;pre&gt;
    class @@@NAMEHERE@@@: public CPPUNIT_NS::TestFixture {
        CPPUNIT_TEST_SUITE(@@@NAMEHERE@@@);
        CPPUNIT_TEST(shouldFailAsEvidenceThisMethodIsRegistered);  // DELETEME?
        CPPUNIT_TEST_SUITE_END();

        public:
            void setUp() {
            }
            void tearDown() {
            }
        protected:
            void shouldFailAsEvidenceThisMethodIsRegistered() { // DELETEME?
                CPPUNIT_FAIL("This function is registered and can be deleted");
            }
    };
    CPPUNIT_TEST_SUITE_REGISTRATION(@@@NAMEHERE@@@);

&lt;/pre&gt;

	&lt;p&gt;Substitution is automagical.  the &lt;code&gt;@@NAMEHERE&lt;/code&gt;@@ is the magic pattern being replaced with test names.&lt;/p&gt;


	&lt;p&gt;A nice thing about macros is that they&amp;#8217;re atomic.  If I hate the name I gave my test, I press &amp;#8216;u&amp;#8217; for undo, and it vanishes.  Back to empty file. :-)&lt;/p&gt;


	&lt;p&gt;If the &amp;#8221;:mak&amp;#8221; works and I get the inevitable failure in the &amp;#8220;shouldFail&amp;#8221; method, I put my cursor on the &amp;#8220;void shouldFail&amp;#8230;&amp;#8221; line and press F9.  In the wink of an eye, the method and its &lt;span class="caps"&gt;CPPUNIT&lt;/span&gt;_TEST line both vanish.  Again, macros are atomic, so if I delete the wrong thing, I just press &amp;#8216;u&amp;#8217; for undo and both the function and its registration reappear.&lt;/p&gt;


	&lt;p&gt;No flipping between files, no scrolling up and down.  We have software to do that now.&lt;/p&gt;


	&lt;p&gt;I add a method under &amp;#8220;protected&amp;#8221;.  I put the mouse on the method name and press &lt;span class="caps"&gt;F12&lt;/span&gt; to add the &lt;span class="caps"&gt;CPPUNIT&lt;/span&gt;_TEST for it above.  I add some more text.  When I get to the part where I need to assert, I use one of the abbreviations.  If I&amp;#8217;m in insert mode and type &amp;#8220;cae(&amp;#8221; I get &amp;#8220;CPPUNIT_ASSERT_EQUALS(&amp;#8221;.  I don&amp;#8217;t have to remember whether it ends in an S or not.  I actually struggle with that, sad thing that I am.&lt;/p&gt;


	&lt;p&gt;I can press &lt;span class="caps"&gt;F11&lt;/span&gt; to create more test classes.  I like to keep a test class for every circumstance (setup) I am using.  I don&amp;#8217;t mind at all having multiple tests per .cpp file.   I like to group the tests together in files.  After all, quickfix knows where the code is.  This is actually one of the reasons I like to keep using CppUnit.   I&amp;#8217;ll have to tell the others someday.&lt;/p&gt;


	&lt;p&gt;Well, that&amp;#8217;s how I do it.  You don&amp;#8217;t have to, but you could try it.  If you find any errors, or glaring omissions, please mail them to me or comment here.  In return, I will claim my &lt;strong&gt;actual&lt;/strong&gt; scripts are perfect and blame it on the web master. ;-)&lt;/p&gt;</description>
      <pubDate>Thu, 03 May 2007 21:54:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:e25e9bd8-0a88-4875-8896-bcceff23ff03</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2007/05/03/cppunit-and-vim</link>
      <category>Tim's Tepid Torrent</category>
    </item>
    <item>
      <title>What Cant Who Do? </title>
      <description>&lt;p&gt;I have a fresh idea.  When someone is supposed to change their workstyle to do &lt;span class="caps"&gt;TDD&lt;/span&gt;, and they say &amp;#8220;we can&amp;#8217;t do that&amp;#8221;, how about we assume they&amp;#8217;re telling the truth.&lt;/p&gt;


	&lt;p&gt;The first word is &amp;#8220;we&amp;#8221;.  It may well be that the speaker and the people he represents might not be able to do the work.  They&amp;#8217;re not saying that it can&amp;#8217;t be done.  They&amp;#8217;re only saying that &lt;strong&gt;they&lt;/strong&gt; can&amp;#8217;t do it.&lt;/p&gt;


	&lt;p&gt;The next word is &amp;#8220;can&amp;#8217;t&amp;#8221; and that&amp;#8217;s an interesting word, too.  It might mean that they lack the ability or knowledge.  That&amp;#8217;s ideal, because such things can be taught and can be led. The other sense is that they are not allowed.   If it&amp;#8217;s like that, then there is going to be some political work going on.  But at least you know what you&amp;#8217;re getting into.&lt;/p&gt;


	&lt;p&gt;The other tell is the word &amp;#8220;that&amp;#8221;.  Maybe they should describe what it is that they can&amp;#8217;t do, and you can tell if the thing they can&amp;#8217;t do is the same thing that you are wanting them to do.   Sometimes it is not.&lt;/p&gt;</description>
      <pubDate>Tue, 01 May 2007 21:55:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:e4c17889-ba01-4ce2-8bf0-24bc5c2345af</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2007/05/01/what-cant-who-do</link>
      <category>Tim's Tepid Torrent</category>
    </item>
    <item>
      <title>Coercive Immediacy</title>
      <description>&lt;p&gt;I have been thinking a lot about the &amp;#8220;short reach&amp;#8221; idea, and tryng to reach beyond it to capture the thing that the good agile project teams have and several others are missing.  At the same time, I&amp;#8217;ve been reading up on some agile tools (including &lt;a href="http://explainpmt.com/"&gt;one by a guy I know&lt;/a&gt;) in my spare time.  In addition, I am on a mailing list for multisite agile development.  Finally, I have been pondering how to work this agile stuff when the developers cannot be co-located due to shortage of office space or shortage of common areas.&lt;/p&gt;


	&lt;p&gt;I realized that the whole &amp;#8220;short reach&amp;#8221; thing creates a kind of coercive immediacy.&lt;/p&gt;


	&lt;p&gt;The corkboard with all the story cards in their four columns has that kind of immediacy.  I can&amp;#8217;t walk past it without assessing how far we are in the current iteration.  I can certainly ignore a web page, or a display in some application on my computer.  I can&amp;#8217;t walk into the common area past that board without thinking.&lt;/p&gt;


	&lt;p&gt;Likewise, I could ignore an app that holds story status and backlog, but the cork board is where I go to show that I&amp;#8217;ve completed a task and to get the next task.  If my stories were assigned to me (rather than allowing self-organization) then I could neglect the corkboard too.  I would not have to look at it or think about it.  I could hold &amp;#8220;my&amp;#8221; story card at &amp;#8220;my&amp;#8221; desk until I decided I was done.  When we are self-organizing, we are always thinking about who could help us, when we can get done, and what is the best way to truly complete this story and move on.&lt;/p&gt;


	&lt;p&gt;A partner has coercive immediacy.  When you are programming in pairs, you don&amp;#8217;t answer the phone unless you have to.  IM and mail can wait.  Interruptions are less welcome.  Having two people on the story pushes one to focus.  Also, the pair partner is always there to catch the sloppy shortcut, the poor naming, the ill-considered algorithm.&lt;/p&gt;


	&lt;p&gt;The customer team member also participates, and both feeds and feels the coercive immediacy of the team.  Rather than make a guess, the programmer feels the nearness of the customer, and it&amp;#8217;s much easier to ask than guess.&lt;/p&gt;


	&lt;p&gt;I think that &lt;span class="caps"&gt;TDD&lt;/span&gt; shows this most of all.  I can&amp;#8217;t choose to ignore the red bar. I write a line of code or two, and now my tests pass. The immediacy would be gone with it, except that I know I have some cheesy, minimal-effort code and I can&amp;#8217;t leave it that way.  I need a better test.  When a test fails in some area where I&amp;#8217;m not working, I feel the immediacy.&lt;/p&gt;


	&lt;p&gt;With distribution, multi-site, tools, and the rest I fear that we lose the coercive immediacy of Agile development.  If we don&amp;#8217;t have a partner in our way/face, then we lose something.  If the status board is a tool somewhere, even a really nice tool, but I have to remember to ask for it to see it, then it is not in my way.  It doesn&amp;#8217;t inspire me.&lt;/p&gt;


	&lt;p&gt;My thought now is that an agile management tool won&amp;#8217;t help unless it is something we have to live with all the time, during pairing, as part of the test/code/refactor cycle.  It has to be in our faces, over our heads, and not just tickling the edge of our awareness like a more polite version of &amp;#8220;clippy&amp;#8221;.&lt;/p&gt;</description>
      <pubDate>Tue, 01 May 2007 20:13:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:210121b7-7793-4a88-9423-291ca8b069d5</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2007/05/01/coercive-immediacy</link>
      <category>Tim's Tepid Torrent</category>
    </item>
    <item>
      <title>Short Reach</title>
      <description>&lt;p&gt;I&amp;#8217;m always trying to find newer, better, shorter, more powerful ways to explain what Agile is about.  I suppose I&amp;#8217;m some kind of obsessive about expressive power and economy.&lt;/p&gt;


	&lt;p&gt;Finally I decided that Agile, as I understand it today, is about the &lt;i&gt;short reach&lt;/i&gt;.&lt;/p&gt;


	&lt;p&gt;It seems to me that all of the agile practices are about shortening our reach, the distance in time-and-space that one leaves an assumption, decision, or line of code untested and unconfirmed.  All the practices seem to follow this one rule.&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;The customer/analyst is keep in the same room, in the same short reach.&lt;/li&gt;
		&lt;li&gt;We feed back the iterations to the customer/analyst so that his every decision has a shorter reach. &lt;/li&gt;
		&lt;li&gt;We do iterations to ensure our planning has short reach.&lt;/li&gt;
		&lt;li&gt;We keep our teammates very close, in the same room, so that it&amp;#8217;s a shorter reach to them.&lt;/li&gt;
		&lt;li&gt;The test is written first, so that implementation has shorter feedback on correctness.&lt;/li&gt;
		&lt;li&gt;We compile/test frequently because our code time should have a short reach.&lt;/li&gt;
		&lt;li&gt;We pair so that our code is instantly vetted through a peer.  We don&amp;#8217;t pile it up and review it after the tests pass. &lt;/li&gt;
		&lt;li&gt;Our planning is based on &amp;#8220;yesterday&amp;#8217;s weather&amp;#8221;, data collected a very short time ago.&lt;/li&gt;
		&lt;li&gt;We don&amp;#8217;t plan the team structure and the assignments, we self-organize so that tasks are waiting for the shortest time possible.&lt;/li&gt;
		&lt;li&gt;We talk face-to-face, not across chat and email and official company documents.&lt;/li&gt;
		&lt;li&gt;Tell-dont-ask and the Law of Demeter guide us in keeping the reach of our objects very short.&lt;/li&gt;
		&lt;li&gt;We use unit tests to exercise a class directly, and we isolate with mocks to reduce the reach of our tests through the system. &lt;/li&gt;
		&lt;li&gt;Shared code ownership means that the guy sitting behind your keyboard has all the permission he needs to do excellent work, even if it impacts existing design.&lt;/li&gt;
		&lt;li&gt;Test-first development means that the guy who makes a change knows very quickly whether his change is safe or not.  He doesn&amp;#8217;t have to wait until the week before integration when the &amp;#8220;real&amp;#8221; tests are run.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Where does Agile run into logistical or operational difficulties? Wherever a long reach is required or imposed. Where an organization chooses to continue in waterfall-style management, where the team is distributed among managers with appointed &amp;#8220;point of contact&amp;#8221; and &amp;#8220;official channels&amp;#8221;, and where the developers are not placed in a common work area agility is very difficult.&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;m not saying that agile techniques can&amp;#8217;t work for large companies, but that is an area where a lot of experts are trying (maybe succeeding) to extend the agile techniques and where the average &amp;#8220;agilist&amp;#8221; finds challenges.  When it works, it is almost certain it will be because someone has found a way to shorten the reach of the teams so that all they need to know is never more than a few seconds or minutes away.&lt;/p&gt;


	&lt;p&gt;At least that&amp;#8217;s my half-baked observation of the day.  Let me know if I&amp;#8217;m wrong here. Or if I&amp;#8217;m more right than I think I am.&lt;/p&gt;</description>
      <pubDate>Mon, 23 Apr 2007 15:33:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:d2b41a9d-04ef-4fec-9e4c-332c956369cf</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2007/04/23/short-reach</link>
      <category>Tim's Tepid Torrent</category>
      <category>agile</category>
      <category>short</category>
      <category>reach</category>
      <category>philosophy</category>
    </item>
    <item>
      <title>Using VIM</title>
      <description>&lt;p&gt;It isn&amp;#8217;t done yet, but I figured I would post my work in progress in the meantime for feedback.  It&amp;#8217;s a little article about the &lt;a href="http://tottinge.blogsome.com/use-vim-like-a-pro"&gt;proper use of the &lt;span class="caps"&gt;VIM&lt;/span&gt; editor&lt;/a&gt;.  I tried to mix in some keystroke quick-reference with the philosophy of the tool in a way that might make it a bit more accessible.&lt;/p&gt;


	&lt;p&gt;When it&amp;#8217;s done (Ha!) I will probably find new places to store it, but for now it&amp;#8217;s at my personal blog.&lt;/p&gt;


	&lt;p&gt;Don&amp;#8217;t be afraid to offer corrective assistance, or to recommend sections.&lt;/p&gt;</description>
      <pubDate>Fri, 20 Apr 2007 01:19:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:f0b91d0a-527e-42b4-8579-781bb91ec465</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2007/04/20/using-vim</link>
      <category>Tim's Tepid Torrent</category>
    </item>
    <item>
      <title>The Two Things Agile</title>
      <description>&lt;p&gt;For Agile, maybe the &lt;a href="http://www.csun.edu/~dgw61315/thetwothings.html"&gt;Two Things&lt;/a&gt; are:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;We can do better/faster this week.&lt;/li&gt;
		&lt;li&gt;And this way next week will be better yet.&lt;/li&gt;
	&lt;/ul&gt;</description>
      <pubDate>Mon, 16 Apr 2007 22:07:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:c785d99a-bc43-49b6-9299-0d0340922748</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2007/04/16/the-two-things-agile</link>
      <category>Tim's Tepid Torrent</category>
    </item>
    <item>
      <title>Code is a Liability</title>
      <description>&lt;p&gt;I have thought for a long time that code is  liability, and that viewing code as a liability has the power to transform our art.  I read articles about code-as-a-corporate-asset and most of them are pretty good articles about wringing the value from the code you have, but I still feel that there&amp;#8217;s something essentially wrong about it.&lt;/p&gt;


	&lt;p&gt;Programs are a great means to an end. Don&amp;#8217;t get me wrong, I&amp;#8217;m in favor of having software and I&amp;#8217;m greatly in favor of writing software. I think we would be in pretty poor shape without it.  But I can&amp;#8217;t call code an asset.&lt;/p&gt;


	&lt;p&gt;Functionality is clearly an asset. When we can inter-operate with various services (possibly even web services) our businesses produce more business results more quickly. We use software to control machines and to increase public safety in more ways than most of us know (talk to the guys who write the software that controls your car, the over-the-road trucks, forklifts, industrial robots, and aircraft).  Software makes our life better and it&amp;#8217;s a wonderful thing.  I&amp;#8217;m all in favor of software functionality and you have to write code to get it.&lt;/p&gt;


	&lt;p&gt;Our bosses and clients will pay good money to get the functionality they want, and they want it right now!  If we could give them what they want without writing a line, it would be a tremendous win.  If we could do it with one line or two lines of well-considered code, we would be heroes!  Why is doing less so valuable if code is an asset? Clearly less code is better.&lt;/p&gt;


	&lt;p&gt;Sadly, most companies have to deal with heaping, shaggy mounds of code.  Code takes up time and space. It has to be managed. It has to be versioned.  It hast to be tracked, and planned. It has to be updated, and packaged, and revised. It needs backup to save us from having to reproduce it by hand.  It has to be reviewed (hopefully in an efficient way like pairing).  It often drives companies to expand staff and dedicate people to manage it (version control administrators, managers, build czars, consultants, contractors, metric-gathering tool specialists, etc).&lt;/p&gt;


	&lt;p&gt;Old code gets in the way of new code.  Having more code will typically slow development, and will certainly reduce your ability to incorporate new programmers.  Of course you&amp;#8217;ll need more programmers because you have all this code to deal with.  Size has a cost.&lt;/p&gt;


	&lt;p&gt;The problem doesn&amp;#8217;t go away if you artificially reduce the code.  Folding a lot of effects into few lines of code makes the code worse. Adding voluminous documentation makes the code worse.  Moving it into metadata and models and other forms doesn&amp;#8217;t make it any smaller, and often makes it worse.  Hand-crafted code is almost always more readable, smaller, more optimal, more focused, more literary in its style than generated code or funky data tables.  Since there has to be code, it might as well be the best code we can write. Coding well takes human beings who value minimalism.&lt;/p&gt;


	&lt;p&gt;It seems that the trick with the functionality/code game is in trying to maintain a positive balance.&lt;/p&gt;


	&lt;p&gt;We reach a point on some projects where we are producing a positive number of functions with a net loss in lines of code.  That&amp;#8217;s a wonderful time.  We reduce the line count by simplifying the code and eliminating duplication.  Sometimes we refactor our code into a more compact form and then only add a very few lines of code to produce a change. If code were an asset, then those moments would be failures instead of triumphs.&lt;/p&gt;


	&lt;p&gt;Code size reduction is a very good thing.  I want the simplest, the smallest, the least code possible, with the least risk of breaking something else in the system. I don&amp;#8217;t want big functions that touch everything in sight. I don&amp;#8217;t want long complicated blocks of if/else statements. I don&amp;#8217;t want monster functions which conglomerate dozens of operations in a single, fat interface.  Shallow is good. Short is good. Less code is good. More code is a liability. This isn&amp;#8217;t about typing less, it&amp;#8217;s about &lt;strong&gt;owning&lt;/strong&gt; less.&lt;/p&gt;


	&lt;p&gt;This is the point of view that makes test-first (TDD) so important.  &lt;span class="caps"&gt;TDD&lt;/span&gt;/BDD has us encode the functionality (the asset) first, and then write minimal code to realize the specified feature.  If code is a liability, and function is an asset, this is exactly the right way to do things.&lt;/p&gt;


	&lt;p&gt;And maybe, just maybe, it might explain why one might open-source less-important useful systems.&lt;/p&gt;</description>
      <pubDate>Mon, 16 Apr 2007 21:10:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:0af14e78-464c-4950-8e14-9a7b46ca08bd</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2007/04/16/code-is-a-liability</link>
      <category>Tim's Tepid Torrent</category>
    </item>
    <item>
      <title>It's a Poor Coach Who Slaps The Kids</title>
      <description>&lt;p&gt;Today I was remembering a bit of advice I received back in the late 80s when I started trying to work with people more.  I&amp;#8217;d been a programmer for a while, and mainly survived by reading a lot and practicing what I read.  I taught myself most of all the programming I knew (I did have some good mentoring peers). I wasn&amp;#8217;t much of a people person.&lt;/p&gt;


	&lt;p&gt;A fellow named Kevin worked on a project with me in the DC area.  One day he had the kindness to take me aside. He explained to me how to work with people.  He taught me that when someone had an error in their understanding I shouldn&amp;#8217;t tell them they were wrong, but rather tell them they were right &lt;strong&gt;except&lt;/strong&gt; for the part where there was an error.  He helped me more than he knows.  We only had the one project together, and he went on to a different employer and I went on to become me.&lt;/p&gt;


	&lt;p&gt;He told me that a good coach doesn&amp;#8217;t tear down his kids.  He doesn&amp;#8217;t tell they they stand like a sissy or throw like a girl.  Instead, a good coach will let them know what&amp;#8217;s right and what&amp;#8217;s valuable about what they&amp;#8217;re doing, and then explain what to add to their technique to get better results. And he doesn&amp;#8217;t tell them everything all at once.&lt;/p&gt;


	&lt;p&gt;Now I&amp;#8217;m a coach. I teach development methods, including agile methods, including &lt;span class="caps"&gt;TDD&lt;/span&gt;.  I  now work with people more than technology.  I also work with a lot of other coaches from time to time.  The best ones seem to intuitively understand when to criticize and how, and when to hold their tongues.&lt;/p&gt;


	&lt;p&gt;In the warm rush of enthusiasm and passion for the art of development, we coaches have to continually remind ourselves that it&amp;#8217;s the poor coach indeed who slaps the kids around.  We have to instead meet them where they are and look for ways to help them get the results they want.&lt;/p&gt;


	&lt;p&gt;Kevin&amp;#8217;s lesson continues to teach.&lt;/p&gt;</description>
      <pubDate>Mon, 16 Apr 2007 21:01:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:09d75df6-fcda-4c7d-9c54-467f1a357865</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2007/04/16/its-a-poor-coach-who-slaps-the-kids</link>
      <category>Tim's Tepid Torrent</category>
    </item>
    <item>
      <title>Single Ownership in C++ (intro to auto_ptr)</title>
      <description>&lt;p&gt;I find a lot of C++ programmers experience memory management differently than I do.  I used to have the same kinds of problems that they have, but I learned an important rule:  &lt;strong&gt;every heap object has exactly one owner, and &lt;i&gt;n&lt;/i&gt; borrowers.&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;The way that I realize this is using reference types.  Of course, all good  C++ programmers write their functions to use the canonical &amp;#8220;const T&amp;#38;&amp;#8221; parameters whenever possible.  Using a reference means that we have an actual object and not a null reference (side effect: no null checks) and we have simple dot notation (side effect: less typing), but I also use this to mean that we are borrowing the object, not owning it.   Likewise, if we have to drop the &amp;#8216;const&amp;#8217;, we are still borrowing.&lt;/p&gt;


What about passing by pointer? I only do that if I absolutely must accept 0 (null) as a possible value.  I always hate to do that.  I would rather have an object outright than a pointer that I dereference.  If the function is being called by a framework, I don&amp;#8217;t get a choice.  I might do something like this:
&lt;pre&gt;
     void functionName(const Snorkle* snorkleWithNull) {
             if (0 == snorkleWithNull) { 
                  throw SomeIdiotPassedMeANull();
            const Snorkle&amp;#38; snorkle = snorkleWithNull;

           // ... work with snorkle, ignore snorkleWithNull ... 

     }
&lt;/pre&gt;
However sick that seems (and it does) it reverts back to the const reference case quickly and I&amp;#8217;m left with a reference to a 