<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6278117270415743822</id><updated>2012-01-27T15:14:55.128-08:00</updated><category term='technical debt'/><category term='video'/><category term='industrial logic'/><category term='blog'/><category term='elearning'/><title type='text'>Exploring Agile Solutions</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>48</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-625570341854354393</id><published>2012-01-27T14:29:00.000-08:00</published><updated>2012-01-27T14:57:18.568-08:00</updated><title type='text'>Sleep Patterns</title><content type='html'>In &lt;a href="http://www.amazon.com/gp/product/0979777747/ref=as_li_qf_sp_asin_tl?ie=UTF8&amp;amp;tag=exploagilesol-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0979777747"&gt;Brain Rules&lt;/a&gt;, and other publications, we now know that people fall into various sleep patterns: "larks," who wake and are most active in early in the morning; "night-owls," who are most active at night; and the unnamed majority, who keep "normal" hours. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;In an internet search, I happened to find an introvert &lt;/span&gt;night owl&lt;span class="Apple-style-span"&gt; who now had the option to take meds to sleep at the same times her husband and children slept, but wanted to keep her late-night awake time as her "private time": free to write, meditate, and observe the quiet night.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;It sounds like a nice idea for a short story. Does she conform to normal hours, or stay a night-owl?&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-625570341854354393?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/625570341854354393/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2012/01/sleep-patterns.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/625570341854354393'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/625570341854354393'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2012/01/sleep-patterns.html' title='Sleep Patterns'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-2176207972624783576</id><published>2011-12-29T10:56:00.000-08:00</published><updated>2011-12-29T11:03:35.977-08:00</updated><title type='text'>A Link to my Resume</title><content type='html'>Normally I'd use the proper accents for Résumé, but just in case... &lt;a href="http://homepage.mac.com/keithray/resume_keithray2.pdf"&gt;my resume (pdf)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;I'm considering writing a book on Test-Driven Development in Objective-C (targeting MacOS X and iOS) and/or a book on TDD in C++ and Objective-C++ [with examples targeting Windows, Mac, and a cross-platform GUI.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-2176207972624783576?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/2176207972624783576/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2011/12/link-to-my-resume.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/2176207972624783576'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/2176207972624783576'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2011/12/link-to-my-resume.html' title='A Link to my Resume'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-4311576898146188929</id><published>2011-11-12T21:44:00.000-08:00</published><updated>2011-11-12T21:47:38.085-08:00</updated><title type='text'>Book Review: "The Unincorporated Man"</title><content type='html'>&lt;span class="Apple-style-span"   style="  line-height: 18px; font-family:arial, sans-serif;font-size:14px;"&gt;&lt;a href="http://www.amazon.com/Unincorporated-Man-Dani-Kollin/dp/B005DI93O8/"&gt;"The Unincorporated Man" by Dani Kollin and Eytan Kollin&lt;/a&gt; is a page-turner and a good example of realistic world-building. The main character is a very rich man from our time, revived 300 years from now in a society "in which every individual is formed into a legal corporation at birth, and spends many years trying to attain control over their own life by getting a majority of his or her own shares." Much of the conflict comes from the main character trying to keep himself "unincorporated" -- the only person in that society not owned by other people or corporations.&lt;br /&gt;&lt;br /&gt;There is a &lt;i&gt;little&lt;/i&gt; too much exposition in some places, and it may seem to have a libertarian agenda, though it shows that corporate power can be just as much of a threat to freedom as government power.&lt;br /&gt;&lt;br /&gt;The chapter about the VR Epidemic, and the VR Museum (which serves this society like "the Holocaust Museum" serves ours) warns that we could entertain ourselves to death, if our entertainment gets to be too good.&lt;br /&gt;&lt;br /&gt;I recommend this book.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-4311576898146188929?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/4311576898146188929/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2011/11/book-review-unincorporated-man.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/4311576898146188929'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/4311576898146188929'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2011/11/book-review-unincorporated-man.html' title='Book Review: &quot;The Unincorporated Man&quot;'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-7658740536699917989</id><published>2011-11-04T15:02:00.000-07:00</published><updated>2011-11-04T15:04:12.170-07:00</updated><title type='text'>changing directions</title><content type='html'>&lt;span class="Apple-style-span" style="color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 15px; font-weight: 300; line-height: 17px; "&gt;&lt;div class="comment-content" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; font-family: inherit; font-size: 15px; font-style: inherit; font-weight: inherit; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; outline-width: 0px; outline-style: initial; outline-color: initial; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; vertical-align: baseline; "&gt;&lt;p style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; font-family: inherit; font-size: 15px; font-style: inherit; font-weight: inherit; margin-top: 0px; margin-right: 0px; margin-bottom: 1.625em; margin-left: 0px; outline-width: 0px; outline-style: initial; outline-color: initial; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; vertical-align: baseline; "&gt;My mission has been to help programmers work with less pain, but I want to go back to basics: to provide tools for creative people (including children), particularly on iPad, iPhone/iPod Touch, MacOS X.&lt;/p&gt;&lt;p style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; font-family: inherit; font-size: 15px; font-style: inherit; font-weight: inherit; margin-top: 0px; margin-right: 0px; margin-bottom: 1.625em; margin-left: 0px; outline-width: 0px; outline-style: initial; outline-color: initial; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; vertical-align: baseline; "&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-7658740536699917989?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/7658740536699917989/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2011/11/changing-directions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/7658740536699917989'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/7658740536699917989'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2011/11/changing-directions.html' title='changing directions'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-8727476416377952538</id><published>2011-06-08T10:34:00.000-07:00</published><updated>2011-06-08T10:40:39.947-07:00</updated><title type='text'>TDD, BDD, and XXDD</title><content type='html'>&lt;p   style="  ;font-family:Times;font-size:medium;"&gt;(repost from &lt;span class="Apple-style-span"  style="color: rgb(51, 102, 153);  font-weight: bold; font-size:14px;"&gt;2006.Aug.12 Sat)&lt;/span&gt;&lt;/p&gt;&lt;p style="font-family: Times; font-size: medium; "&gt;Check out Dave Astel's &lt;a href="http://blog.daveastels.com/files/BDD_Intro.pdf"&gt;paper (pdf)&lt;/a&gt; on TDD/BDD. Quotes:&lt;/p&gt;&lt;blockquote style="font-family: Times; font-size: medium; "&gt;&lt;p&gt;[...] There are a score of books available on TDD, mine even won a Jolt award. So it seems that everything is rosy? Everyone who's doing TDD is fully understanding it and getting the full benefit, right?&lt;/p&gt;&lt;p&gt;Fat Chance!&lt;/p&gt;&lt;p&gt;Too few people I talk to really understand what it's really about. That means that many people who practice TDD are not getting the full benefit from it. What's wrong?&lt;/p&gt;&lt;p&gt;&lt;b&gt;The focus on testing&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Well... one thing is that people think it's about testing. That's just not the case.&lt;/p&gt;&lt;p&gt;Sure, there are similarities, and you end up with a nice low level regression suite... but those are coincidental or happy side effects. So why have things come to this unhappy state of affairs? Why do so many not get it?[...]&lt;/p&gt;&lt;p&gt;So with people thinking about testing, it's easy to come up with all sorts of negative reactions and reasons not to do it... especially when time gets short and the pressure's on.&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="font-family: Times; font-size: medium; "&gt;By the way, I &lt;b&gt;HATE&lt;/b&gt; saying TDD is &lt;b&gt;"not about the testing"&lt;/b&gt;. I have to say it now and then because of people not realizing it's about designing, rather than testing. The fact that the word "test" is in the name just helps confuse the issue. My preference for naming this design technique, is to call it "Behavior Driven Design". Or "Behavior-Spec Driven Design". With BSDD, I could say BSDD &lt;i&gt;is&lt;/i&gt; about the behavior-specs, but mostly about&lt;b&gt;driving design&lt;/b&gt;.&lt;/p&gt;&lt;p style="font-family: Times; font-size: medium; "&gt;Alistair Cockburn's &lt;a href="http://alistair.cockburn.us/index.php/Dos_equis_driven_design"&gt;"Executable Example Driven Design"&lt;/a&gt; (XXDD) is OK, but a bit long-winded. And I don't want to have say "Dos-equis Driven Design is not about beer." :-)&lt;/p&gt;&lt;p style="font-family: Times; font-size: medium; "&gt;The problem is mental frameworks. People reject ideas that don't fit into their mental framework. You say "test" and the listener's mental framework comes up with these and other assumptions:&lt;/p&gt;&lt;ul style="font-family: Times; font-size: medium; "&gt;&lt;li&gt;Testing can be done manually.&lt;/li&gt;&lt;li&gt;I can do implementing, someone else can do testing.&lt;/li&gt;&lt;li&gt;Testing looks for bugs.&lt;/li&gt;&lt;li&gt;Tests need something to test.&lt;/li&gt;&lt;li&gt;Testing is hard.&lt;/li&gt;&lt;li&gt;We can skip testing if we are good enough programmers, or time is short.&lt;/li&gt;&lt;/ul&gt;&lt;p style="font-family: Times; font-size: medium; "&gt;None of those assumptions directly applies to TDD. TDD can't be separated into tests written by one person and code written by another because the TDD cycle of test-code-refactor is a design process that one person (or a pair) goes through in cycles, where each cycle takes only minutes. TDD/BDD helps me find bugs, but that's not the purpose of TDD. TDD isn't TDD is you do the "test" part manually.&lt;/p&gt;&lt;p style="font-family: Times; font-size: medium; "&gt;If you say "Test-Driven Development is not about the tests," that usually doesn't provide the zen-like kick in the brain-pan that the speaker intends. Instead, the phrase gets rejected because it doesn't fit into the listener's mental framework for "tests". The listener probably thinks you're nuts. He or she might just flip the "bozo bit" and stop listening to you.&lt;/p&gt;&lt;p style="font-family: Times; font-size: medium; "&gt;If instead you say "Behavior Spec", the listener's mental framework will have fewer contradictory assumptions. For example:&lt;/p&gt;&lt;ul style="font-family: Times; font-size: medium; "&gt;&lt;li&gt;Specs are written before coding.&lt;/li&gt;&lt;li&gt;Specs can provide examples.&lt;/li&gt;&lt;li&gt;Specs tell you what you need to implement.&lt;/li&gt;&lt;li&gt;Someone else can write specs and I can write the code.&lt;/li&gt;&lt;/ul&gt;&lt;p style="font-family: Times; font-size: medium; "&gt;Not all of those assumptions are true for BDD, but there are fewer contradictions to this idea of BBD that you're trying to introduce into someone's mental framework. Behavior Specs are written before the code exists (though only minutes before). Behavior Specs are executable examples. Behavior Specs tell you, more or less, what you need to implement next. There is still the contradictory idea that someone can write the Spec and someone else can write the code, but that isn't as difficult to overcome as all the other assumptions that come up with the word "test".&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p style="font-family: Times; font-size: medium; "&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-8727476416377952538?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/8727476416377952538/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2011/06/tdd-bdd-and-xxdd.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/8727476416377952538'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/8727476416377952538'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2011/06/tdd-bdd-and-xxdd.html' title='TDD, BDD, and XXDD'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-1405457360847003539</id><published>2011-06-02T01:32:00.000-07:00</published><updated>2011-06-02T01:36:38.719-07:00</updated><title type='text'>What part of the brain calculates how a whip works?</title><content type='html'>&lt;div&gt;Imagine a whip, in which each centimeter of the whip contains a data processor node, that calculates the position of the node in 3d space, the acceleration and velocity of the node in 3d space, the relative angle between this node and the next node, and the strength and angle of the pull on this node from the previous node, and so on.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Imagine each of these nodes gathering gigabytes of data, as a talented master of the whip, whose only control of this leather string of nodes comes from the handle in his hand, waves and curls the whip in the air, to snap it with precision, the tip exceeding the speed of sound, to clip a playing card or other some other target.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;How much could we learn from examining and processing that data? What equations could we derive?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;No doubt simulating this activity would take bank of CPUs some time to crank through the numbers. Far more time than the real-time action that took place.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;How does a man do it? Practice, of course. And the more esoteric calculations are done in parts of our brain that are not subject to conscious reasoning. The parts that can predict the not-entirely parabolic path of ball thrown in baseball or football.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;(See &lt;a href="http://www.videojug.com/film/how-to-crack-a-whip-like-indiana-jones"&gt;How to crack a whip like Indiana Jones&lt;/a&gt; )&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Would it not be interesting if the simulation of a whip could be repurposed to predict movements in currency-trading, stocks and bonds, real-estate prices, national economies? &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In some limited situations the number of variables might not be that different. The forces and effects, velocity and acceration and position, could have analogs in this financial world.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;How would a whip-weilder of finance practice? How would he get feedback? Could it be visible enough and fast enough to allow the esoteric calculating parts of his brain reliably direct his (financially metaphoric) hand?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-1405457360847003539?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/1405457360847003539/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2011/06/what-part-of-brain-calculates-how-whip.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/1405457360847003539'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/1405457360847003539'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2011/06/what-part-of-brain-calculates-how-whip.html' title='What part of the brain calculates how a whip works?'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-7866988072905443418</id><published>2011-04-18T04:27:00.000-07:00</published><updated>2011-04-18T04:43:44.095-07:00</updated><title type='text'>Objects Dependancies Are Their Own Tax</title><content type='html'>&lt;div&gt;This list of ways one class can depend on another is ordered from worst to best (for C++):&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;1. A depends on B because B is Singleton.&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Avoid this. The dependency is 'invisible' and Singleton makes it worse than a global variable. Destruction is usually not possible unless a counting mechanism is used.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;2. A depends on B because B is global variable.&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Avoid this. The dependency is 'invisible'.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;3. A depends on B because B is a file-local variable. &lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Avoid this. Not accessible to test.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;4. A depends on B because B is a function-static variable.&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Avoid this. Initialization is not multiple-thread safe. Not accessible to test. Destruction is difficult.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;5. A depends on B because B is a class-static variable. &lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Avoid this. A class with static members and non-static members is doing two things. Separate the two responsibilities into separate classes, one of which can be a longer-lived than the other.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;6. A depends on B because B is a member variable of A "by value".&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Great for "value" objects, not so good for other kinds of objects. ("By Value" means by &lt;b&gt;not&lt;/b&gt; by pointer &lt;b&gt;nor&lt;/b&gt; by reference,)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;7. A depends on B because B is a local variable of one of A's function. &lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Inaccessible to test. The dependency is 'invisible'.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;8. A depends on B because B is a "by value" parameter in A's functions.&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Not subject to faking or mocking, any data or behavior that are defined in a subclass of 'B' is "sliced-off" to be just a "B" inside the function.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;9. A depends on B because B is a pointer/reference member of A, created in constructor. &lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Creation in the constructor is too soon for us to insert a fake.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;10. A depends on B because B is a pointer/reference member of A, created in non-virtual function.&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;We can't override the creation inside the function.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;11. A depends on B because B is a pointer/reference member of A, created in virtual function.&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;This allows us to override the function that creates B, using a fake, stub, or mock.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;12. A depends on B because B is a pointer/reference member set by parameter in A's constructor.&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;We can create A with a fake, sub, or mock in testing. Dependency is visible.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;13. A depends on B because B is a pointer/reference parameter in A's functions.&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;This makes the dependency visible in the interface. We can supply fake, stub, or mock in testing.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-7866988072905443418?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/7866988072905443418/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2011/04/objects-dependancies-are-their-own-tax.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/7866988072905443418'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/7866988072905443418'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2011/04/objects-dependancies-are-their-own-tax.html' title='Objects Dependancies Are Their Own Tax'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-4540956929863596383</id><published>2011-04-18T04:03:00.000-07:00</published><updated>2011-04-18T04:08:52.349-07:00</updated><title type='text'>Coupling. Or... what you don't want your objects doing too much of.</title><content type='html'>Dependencies by one class on another class can cause problems when refactoring and writing microtests. In microtests, you want awkward collaborators to be faked,  mocked, or stubbed out, and some kinds of dependencies make that more  difficult than others.&lt;br /&gt;&lt;br /&gt;Here are some dependencies from best (least-coupled) to worst (most tightly-coupled).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1. Class A depends on Class B, where class B is an interface&lt;/b&gt; ("pure" abstract base class).&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;We can test instances of A by creating our own test-specific subclasses of B to pass into A.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;2. Class A depends on Class B, where class B is a concrete class but the functions are declared virtual.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;We can test instances of A by creating our own test-specific subclases of B, but at a price: we have to deal with B's constructors and destructor, possibly doing stuff we don't want.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;3. Class A depend on Class B, where class B is concrete class with no virtual functions.&lt;/b&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;/b&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;We're going to need to refactor B and/or A for testability. Either making B's functions virtual, or putting an testable Adapter between A and B.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;4. Class A depends on Class B, and class B grants class A "friend" access.&lt;/b&gt; &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Class A not only depends on the public interface of B, but also the private parts of B as well. Not recommended. Don't do this unless you are Bjarne Stroustrup. If a test needs to access private parts of B, make those parts 'protected' and use a test-specific subclass to change selected parts of B to have 'public' access.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;5. Class A depends on Class B, and class B is a class declared INSIDE class A.&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;/b&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;This can lead to mutual complete visibility between A and B, plus the scoping makes it hard to test A without B, or vice versa. Not recommended. Don't do this unless you are Alexander Stepanov.&lt;br /&gt;&lt;br /&gt;Also affecting how class A depends on class B is the WAY the dependency is manifest. It turns out that "visible" dependencies are often better than "hidden" dependencies, which is opposite of the usual idea of "information hiding", the predecessor idea of "encapsulation".&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-4540956929863596383?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/4540956929863596383/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2011/04/coupling-or-what-you-dont-want-your.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/4540956929863596383'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/4540956929863596383'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2011/04/coupling-or-what-you-dont-want-your.html' title='Coupling. Or... what you don&apos;t want your objects doing too much of.'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-9223235768583887853</id><published>2011-04-09T05:21:00.000-07:00</published><updated>2011-04-09T05:23:28.501-07:00</updated><title type='text'>from one twitter-reading session</title><content type='html'>Stuff I found interesting in reading twitter today, mostly links to things I'd want to read later.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;RT: @LeanVoices: The idea is the easy bit, execution is where excellence and hard work resides.&lt;br /&gt;&lt;br /&gt;RT: @suziedwards: Resume blooper of the day? "Software Mythologies used include Waterfall and Scrum".&lt;br /&gt;&lt;br /&gt;RT @markrneedham: How to type on an iPad http://bit.ly/ftr9Vl&lt;br /&gt;&lt;br /&gt;RT @flowchainsensei: Facebook's data center play sidelines Google, Apple http://reg.cx/1NBh&lt;br /&gt;&lt;br /&gt;Chad Fowler = "These have changed my developer life, how I perceive software&lt;br /&gt;and that great technology is fun" http://bit.ly/hP2B6O&lt;br /&gt;&lt;br /&gt;Cool, @gregturn has finished Python Testing Cookbook! #congrats http://www.packtpub.com/python-testing-cookbook/book&lt;br /&gt;&lt;br /&gt;RT @hackernewsbot: New engine shakes up auto industry... http://www.msnbc.msn.com/id/42460541/ns/technology_and_science-innovation/&lt;br /&gt;&lt;br /&gt;Divvy is pretty awesome. http://bit.ly/g11Hj5&lt;br /&gt;&lt;br /&gt;RT @badbanana: If you enjoy being the 10,000th person to put your thumb into a hole, then bowling is for you.&lt;br /&gt;&lt;br /&gt;RT @theCoachingblog: "The things we hate about ourselves aren't more real than things we like about ourselves."&lt;br /&gt;(Ellen Goodman) #quote&lt;br /&gt;&lt;br /&gt;"Managing" Velocity: The term velocity is very well-chosen. It means speed in a certain direction, w... http://bit.ly/gvikOP #agileotter&lt;br /&gt;&lt;br /&gt;RT @capotribu: "My startup story: from big idea to thriving business in 8 short years" http://t.co/IXMCjfV &lt; great story of real reality&lt;br /&gt;&lt;br /&gt;Fun Fact http://dinosaurmusings.wordpress.com/2011/04/08/fun-fact/&lt;br /&gt;&lt;br /&gt;Our schools failed many of us. Why don't people understand the role of analogy? http://bit.ly/gBRqji (see comments) #testing&lt;br /&gt;&lt;br /&gt;Good read. RT @toddcharron: An Agile Pace http://t.co/Rn9Gzuf - reminds me of http://t.co/gwmGRX7 #agile #scrum #kanban #overtime&lt;br /&gt;&lt;br /&gt;Best #Agile article this year: Agile’s Second Chasm (and how we fell in) http://bit.ly/hvQDpT by @williampietri #recommended&lt;br /&gt;&lt;br /&gt;RT @tottinge @jamesshore Someone was selling us a product that allows you to "collaborate in isolation from each other."&lt;br /&gt;&lt;br /&gt;James Shore = For the record: Rabu is not and never* will be a project management tool, a planning tool, or a replacement for a whiteboard.&lt;br /&gt;&lt;br /&gt;See what you started, mike hill? RT @alancfrancis: I am now nekkid as a jaybird, in an apartment with 10 windows wide open, attempting to cool down.  #sorrytoputthatimag ...&lt;br /&gt;&lt;br /&gt;10  Acts of Resistance That Changed the World — YES! Magazine http://t.co/NFN2UVx&lt;br /&gt;&lt;br /&gt;jasonlittle = we did a retrospective on why we stopped doing retrospectives.  good insights, blog post coming.&lt;br /&gt;&lt;br /&gt;I read this = http://blog.benjaminm.net/2011/02/16/argyriscasestudylearningmodelii/ = worth it&lt;br /&gt;&lt;br /&gt;http://blog.benjaminm.net/2010/12/07/agile-argyris-double-loop-learning/&lt;br /&gt;&lt;br /&gt;publishing co I never heard of: http://www.packtpub.com/python-testing-cookbook/book&lt;br /&gt;&lt;br /&gt;This practical cookbook covers lots of test styles including unit-level, test discovery, doctest, BDD, acceptance, smoke, and load testing. It will guide you to use popular Python tools effectively and discover how to write custom extensions. You will learn how to use popular continuous integration systems like Jenkins (formerly known as Hudson) and TeamCity to automatically test your code upon check in. This book explores Python's built-in ability to run code found embedded in doc strings and also plugging in to popular web testing tools like Selenium. By the end of this book, you will be proficient in many test tactics and be ready to apply them to new applications as well as legacy ones.&lt;br /&gt;&lt;br /&gt;http://www.ted.com/index.php/talks/jonathan_haidt_on_the_moral_mind.html&lt;br /&gt;&lt;br /&gt;yourmorals.org  ?&lt;br /&gt;&lt;br /&gt;https://github.com/twitter/commons&lt;br /&gt;&lt;br /&gt;engineering.twitter.com blog = Cross-site Scripting Protection is one hundred percent live on mobile.twitter.com&lt;br /&gt;&lt;br /&gt;After a soft launch, we ran into some unexpected issues. Several common Firefox extensions insert Javascript on page load, thereby triggering a report. However, even more surprising were the number of ISPs who were inadvertently inserting Javascript or altering image tags to point to their caching servers. It was the first example of how CSP gave us visibility into what was happening on the user’s end. We addressed this problem by mandating SSL for Firefox 4 users, which prevents any alteration of our content.&lt;br /&gt;&lt;br /&gt;http://c2.com/cgi/wiki?WikiDesignPrinciples&lt;br /&gt;&lt;br /&gt;http://elabs.se/blog/15-you-re-cuking-it-wrong&lt;br /&gt;&lt;br /&gt;http://dannorth.net/2011/01/31/whose-domain-is-it-anyway/&lt;br /&gt;&lt;br /&gt;http://cuke4ninja.com/&lt;br /&gt;&lt;br /&gt;http://www.infoq.com/articles/Accidental-Agilist = Johanna Rothman wrote:&lt;br /&gt;&lt;blockquote&gt;I didn’t think if myself as an agilist, of course. I decided to experiment with some practices, such as pairing and TDD. I’d worked closely with a couple of people one-on-one, back when I was a developer, and I wasn’t sure if it was really pairing. So I tried pairing and TDD with a colleague, Keith Ray, at an AYE conference, and sure enough, it was just like what I had done at work. Except, Keith was much nicer than my work colleague back in the ‘80s.&lt;br /&gt;&lt;/blockquote&gt;  :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-9223235768583887853?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/9223235768583887853/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2011/04/from-one-twitter-reading-session.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/9223235768583887853'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/9223235768583887853'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2011/04/from-one-twitter-reading-session.html' title='from one twitter-reading session'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-6956777472732278668</id><published>2011-03-20T18:35:00.000-07:00</published><updated>2011-03-20T20:08:24.057-07:00</updated><title type='text'>J. S. Bach 300+ years of beautiful music</title><content type='html'>In honor of Bach's birthday, March 21, 1685, and the &lt;a href="http://search.twitter.com/search?q=%23bachchat"&gt;#bachchat&lt;/a&gt; celebration on twitter. Here are some of my favorite performances of Bach's music.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;My current favorite is &lt;i&gt;The "Little" Fugue in G Minor&lt;/i&gt;, BWV 578. ("A fugue is a &lt;a href="http://en.wikipedia.org/wiki/Contrapuntal"&gt;contrapuntal&lt;/a&gt; piece of music wherein a particular melody is played in a number of voices, each voice introduced in turn by playing the melody." &lt;a href="http://en.wiktionary.org/wiki/fugue"&gt;wiktionary&lt;/a&gt;)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To get a feeling for how &lt;i&gt;The Little Fugue&lt;/i&gt; introduces the melody over and over, in multiple voices, each continuing to play over the others and yet still sound "good", check out this "piano-roll" animated rendition of this piece on youtube.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;iframe title="YouTube video player" width="480" height="390" src="https://www.youtube.com/embed/pVadl4ocX0M?rel=0" frameborder="0" allowfullscreen=""&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The above piece is performed on a &lt;a href="http://en.wikipedia.org/wiki/Pedal_piano"&gt;piano-like&lt;/a&gt; instrument with a pedals, so the pianist can play a bass melody with his feet, just like an organist. And I think you would &lt;b&gt;need&lt;/b&gt; that with this piece. I'm not sure how someone would like all the parts with just two hands.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now the more &lt;b&gt;fun&lt;/b&gt; performances are these...  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The Canadian Brass:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;iframe title="YouTube video player" width="480" height="390" src="https://www.youtube.com/embed/Qvc4955x_W8?rel=0" frameborder="0" allowfullscreen=""&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The Swingle Singers:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;iframe title="YouTube video player" width="480" height="390" src="https://www.youtube.com/embed/659PBM3Xq2A?rel=0" frameborder="0" allowfullscreen=""&gt;&lt;/iframe&gt; &lt;/div&gt; &lt;div&gt;&lt;br /&gt;&lt;/div&gt;Leopold Stokowski's orchestral arrangement:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;iframe title="YouTube video player" width="480" height="390" src="https://www.youtube.com/embed/LHMJFhJNycM?rel=0" frameborder="0" allowfullscreen=""&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You can search for other renditions of this fugue on other instruments. Wendy Carlos did a recording using a Moog synthesizer in &lt;a href="http://www.wendycarlos.com/+sobox.html"&gt;Switched-On-Bach Boxed Set&lt;/a&gt;. The original instrument was of course, organ.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Bach's most famous organ piece is &lt;i&gt;The Toccata and Fugue in D Minor&lt;/i&gt;, BWV 565 which may &lt;b&gt;not&lt;/b&gt; have been written by Bach (!) and may have originally been a &lt;b&gt;violin&lt;/b&gt; piece (!!). See the wikipedia article &lt;a href="http://en.wikipedia.org/wiki/Toccata_and_Fugue_in_D_minor,_BWV_565"&gt;here&lt;/a&gt;. And here's what the violin piece might have originally sounded like:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;iframe title="YouTube video player" width="480" height="390" src="https://www.youtube.com/embed/aNfox7ORW1Q?rel=0" frameborder="0" allowfullscreen=""&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I rather like Don Dorsey's synthesized version of &lt;i&gt;The Toccata and Fugue &lt;/i&gt;in&lt;i&gt; &lt;a href="http://www.amazon.com/Bachbusters-Johann-Sebastian-Bach/dp/B000003CTU"&gt;Bach Busters&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;No youtube version of Don Dorsey's version. But there is this guitar performance:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;iframe title="YouTube video player" width="480" height="390" src="https://www.youtube.com/embed/xdEAccE7BMs?rel=0" frameborder="0" allowfullscreen=""&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;My other favorites include the &lt;a href="http://en.wikipedia.org/wiki/Brandenburg_concertos"&gt;Brandenburg concertos&lt;/a&gt;, The &lt;i&gt;&lt;a href="http://en.wikipedia.org/wiki/Passacaglia_and_Fugue_in_C_minor,_BWV_582"&gt;Passacaglia and Fugue in C Minor&lt;/a&gt;&lt;/i&gt; (which is another &lt;a href="http://www.youtube.com/watch?v=dfuyjrhPIc4"&gt;piece&lt;/a&gt; arranged by Leopold Stokowski for orchestra)...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;iframe title="YouTube video player" width="425" height="349" src="https://www.youtube.com/embed/dfuyjrhPIc4?rel=0" frameborder="0" allowfullscreen=""&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;...and several pieces from the &lt;a href="http://en.wikipedia.org/wiki/Notebook_for_Anna_Magdalena_Bach"&gt;Anna Magdalena notebook&lt;/a&gt;. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I'm not a fan of Bach's vocal music.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I own a "complete" &lt;a href="http://www.amazon.com/Bach-Light-Without-Sacred-Cantatas/dp/B00001IV8C/ref=pd_sim_sbs_m_5"&gt;collection&lt;/a&gt; of Bach's music (153 CDs, excluding his religious vocal music), including several recordings of my favorite pieces.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-6956777472732278668?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/6956777472732278668/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2011/03/j-s-bach-300-years-of-beautiful-music.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/6956777472732278668'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/6956777472732278668'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2011/03/j-s-bach-300-years-of-beautiful-music.html' title='J. S. Bach 300+ years of beautiful music'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/pVadl4ocX0M/default.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-7130985994750649836</id><published>2011-02-09T10:05:00.000-08:00</published><updated>2011-02-09T11:47:03.882-08:00</updated><title type='text'>If you are struggling how to TDD something...</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 14px; border-collapse: collapse; "&gt;If you struggling to think how to test-drive something with simple input and complex output, a few heuristics might help:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;1.  Testing pathological code (e.g. bad argument values) isn't going to drive your implementation that much, so leave that for later. Try the simplest successful case first.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;2.  If you really can't think how to test it, sketch out the algorithm (e.g. code-first) and figure out how you could test that algorithm. If the algorithm is 50 lines long, pretend it is 50 method calls instead: how would you test each of those method-calls? What does each line/method take as input, what is its output? Then try to go back to test-first and re-implement the code. Don't worry about public / private methods. Once your are "done" or at good stopping point, figure out which classes should own which methods, then refactor them to cooperating classes where most of the work is in public methods of each class. Move the tests to be closer to the code they test.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;3. A class where there is only one or two public methods and a dozen or more private methods is exhibiting the code smell "&lt;a href="http://www.artima.com/weblogs/viewpost.jsp?thread=125574"&gt;Iceberg Class&lt;/a&gt;".&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;4. If the complexity resides in a third-party library or framework, concentrate your tests on YOUR code, assuming the third-party library or framework is correct. Unless, of course, the third-party library or framework needs tests (because it is unreliable), in which case test how your code uses the library or framework to get expected results. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;5. You might have the test create the output, you verify that the output is correct manually, and then you save that output as a "gold standard" to test against automatically. I've done that for image-processing... it broke rarely, when the jpg library I was using changed.&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-7130985994750649836?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/7130985994750649836/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2011/02/if-you-are-struggling-how-to-tdd.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/7130985994750649836'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/7130985994750649836'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2011/02/if-you-are-struggling-how-to-tdd.html' title='If you are struggling how to TDD something...'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-1033311086519031314</id><published>2010-11-23T10:13:00.000-08:00</published><updated>2010-11-23T10:26:28.212-08:00</updated><title type='text'>High technical debt = slum</title><content type='html'>&lt;div&gt;Sometimes I think the "debt" analogy is too clean. Brian Foote and his coauthor used many analogies in his "Big Ball of Mud" paper, including "Shanty Town", but I think the best analogy for the products I've seen with large amounts of technical debt is "Slum".&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Products with large technical debt are money-makers, in spite of their problems (until the problems cost too much). &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Slums have slum-lords, who profit from lack of maintenance, who are ignoring the pain of the inhabitants (developers and tester), and who are also ignoring the benefits of a clean environment... (of course, you can only take an analogy so far).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Still, it takes an &lt;b&gt;empowered&lt;/b&gt; group of inhabitants to transform a slum into a desirable place to live and work. That requires management support. &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-1033311086519031314?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/1033311086519031314/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2010/11/high-technical-debt-slum.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/1033311086519031314'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/1033311086519031314'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2010/11/high-technical-debt-slum.html' title='High technical debt = slum'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-7137104842259360924</id><published>2010-11-23T09:03:00.000-08:00</published><updated>2010-11-23T09:27:33.696-08:00</updated><title type='text'>Some books I recommend to those new to Agile</title><content type='html'>&lt;style type="text/css"&gt; p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Arial} p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Arial; color: #0500cc} p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Arial; min-height: 16.0px} span.s1 {color: #000000} span.s2 {text-decoration: underline} &lt;/style&gt;   &lt;p class="p1"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;The following are some books I recommend to developers new to Agile software development.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="p1"&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;This book is new, pretty complete, and easy-to-read about adopting agile software development: &lt;a href="http://pragprog.com/titles/jtrap/the-agile-samurai"&gt;The Agile Samurai&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt; &lt;p class="p1"&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;This book covers the same ground as the Agile Samurai book. It's a &lt;span class="Apple-style-span"&gt;little more &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;in-depth. Most of it is now free on-line, but you can buy the book from Amazon: &lt;span class="Apple-style-span" style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; "&gt;&lt;a href="http://jamesshore.com/Agile-Book/"&gt;The Art of Agile Development&lt;/a&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt; &lt;p class="p1"&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;This book is about test-driven development in C: &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(51, 51, 51); letter-spacing: -1px; "&gt;&lt;a href="http://pragprog.com/titles/jgade/test-driven-development-for-embedded-c"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Test Driven Development for Embedded C&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt; &lt;p class="p1"&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;This is the original TDD book in Java: &lt;a href="http://www.amazon.com/Test-Driven-Development-Kent-Beck/dp/0321146530"&gt;Test-Driven Development&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt; &lt;p class="p1"&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;The original book on &lt;a href="http://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672/ref=pd_bxgy_b_img_b"&gt;Refactoring&lt;/a&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt; &lt;p class="p1"&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;If you have legacy code, you also need to this book: &lt;a href="http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052/ref=pd_sim_b_2"&gt;Working Effectively With Legacy Code&lt;/a&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt; &lt;p class="p2"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0); "&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Industrial logic has eLearning and in-person workshops on  &lt;a href="http://goo.gl/YfWIn" style="color: rgb(61, 129, 238); "&gt;TDD&lt;/a&gt;, &lt;a href="http://goo.gl/q2GEZ" style="color: rgb(61, 129, 238); "&gt;Refactoring&lt;/a&gt;, &lt;a href="http://goo.gl/kmKAI" style="color: rgb(61, 129, 238); "&gt;Design Patterns&lt;/a&gt;, and other topics. This web-based eLearning contains videos, exercises, and quizzes that are, for most people, more effective than reading a book. I would recommend both.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-7137104842259360924?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/7137104842259360924/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2010/11/some-books-i-recommend-to-those-new-to.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/7137104842259360924'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/7137104842259360924'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2010/11/some-books-i-recommend-to-those-new-to.html' title='Some books I recommend to those new to Agile'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-8055936498943450512</id><published>2010-11-19T22:48:00.000-08:00</published><updated>2010-11-20T00:32:17.970-08:00</updated><title type='text'>Going meta sometimes helps.</title><content type='html'>One of the sessions I participated in at &lt;a href="http://www.ayeconference.com/"&gt;AYE&lt;/a&gt; 2010 was Steve Smith's session on "&lt;a href="http://www.ayeconference.com/schedule/#10S20"&gt;Power, Authority, and Teams&lt;/a&gt;". We did an exercise where we individually tried to solve a problem (on paper, a problem whose answer can be scored as to correctness)  and then we were divided into four teams, with one observer each, to try to solve the same problem.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The team that I was on, started with some direct actions by individuals: deciding we would use a flip-chart on an easel, and moving the flip-chart away from another team (which, funnily enough, put us next to another flip-chart on an easel, so we could have avoided carrying that easel around). One partipant decided to act as scribe, and off we want, problem-solving. I'm sure it looked like pure chaos. And it was. (But not necessarily in a bad way.)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As we worked through the problem, sometimes we'd ask for a show of hands in favor of a particular part of the solution. We never actually formalized how voting would work, and certainly never had more than one third of the group raising their hands. I think a lot of us in the group were trying to gauge agreement by audio and visual cues, but we didn't go "meta" long enough to formalize &lt;b&gt;how&lt;/b&gt; we would signal agreement. We didn't appoint roles, or vote on a leader. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You have to remember that a many of us were coaches. "Agile coaches," even. We know about dot-voting (I almost suggested it once during this chaos), consensus/thumb-voting. We know about team-formation, Satir change model, self-organizing teams. Some of us had been through &lt;a href="http://www.estherderby.com/workshops/problem-solving-leadership-psl"&gt;Problem-Solving Leadership&lt;/a&gt; training. We didn't use any of those tools. I know I could have, but I didn't, and I expect some others were thinking the same thing.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;After struggling with one problem solving technique for a while, one of the Europeans in the group complained that our usage of American-style measurements was making it hard for him to contribute. I wrote "1 meter ≈ 3 feet" on the flip-chart to help him out, but another member of the team proposed working in relative sizes instead of absolute sizes. We transitioned to that problem-solving style and, after a little confusion, the team seemed to jell.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We had come to an agreement on process, though never explicitly agreeing on process through any formal means. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Later, we could compare our individual scores on the answering the problem with our team scores. Our team scored higher than any of our individual scores, though we were in third-place compared to the other three teams. The team with the highest score had chosen to use computers to solve the problem. Imagine! A bunch of software people using &lt;i&gt;computers&lt;/i&gt; to solve the problem! :-)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;OK, our team had a moment of conversation, early on, where some of us agreed not to use computers for the problem-solving, as that seemed against the spirit of the simulation. Again, not a formally-ratified agreement, but no one in our team went against that decision during the simulation. We were supposed to be learning about &lt;i&gt;power: &lt;/i&gt;how people interact with each other, so we didn't bring computers into the simulation.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The team in fourth place had a score that was &lt;b&gt;lower&lt;/b&gt; than any of their individual scores. I really wish I could have observed what was going on in that team. Somehow their collective problem-solving skill went completely opposite of their individual skills.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I think that even if we &lt;b&gt;had&lt;/b&gt; formalized how our team made its decisions, we probably would have come to the same solution that we did in our informal way. We might have done so faster. We might have included insights from some of the quieter members of the team, and might done a little bit better. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It's also possible that if we had been too formal, we could have done worse, perhaps much worse.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Two points I want to mention. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In a team-building exercise at AYE 2005, my team happened to be all PSL graduates and no one in the other team was a PSL graduate. My team quickly jelled. We decided to enjoy ourselves and not stress out. The other team, across the room, we could see going through "forming, storming, norming, performing" stages. We ended up coming in second-place (of two teams)... but each team was working on a different LEGO model, so the difference in performance could be the difference in complexity of the models, or differences in our LEGO-building skills. As much as we would like to have simple causes-and-effects, sometimes effectiveness in one area doesn't mean success in another.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The other point I want to mention, I just read in &lt;a href="http://www.dorsethouse.com/books/gift.html"&gt;The Gift Of Time&lt;/a&gt;, in the chapter written by Willem van den Ende: "Solving the Groupthink Problem". He quotes a diagram-of-effects by Jerry Weinberg (&lt;a href="http://www.geraldmweinberg.com/Site/QSM_vol_3.html"&gt;Quality Software Management vol. 3&lt;/a&gt;) Rather than re-print the image, I'll try to describe it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;"Effectiveness of meta-planning" directly affects "Effectiveness of strategic planning".&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;"Effectiveness of strategic planning" directly affects "Effectiveness of action planning".&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;"Effectiveness of action planning" directly affects "Quality of Action".&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;"Other Factors" directly affects "Effectiveness of action planning" and also directly affects "Quality of Action".&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;"Change Artistry" directly affects "Quality of Action".&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That may or may not speak for itself. (Probably not, but it's getting late.) Willem has a paper &lt;a href="http://www.methodsandtools.com/archive/archive.php?id=54"&gt;here&lt;/a&gt; that shows other diagrams of effects. Diagramming systems can be useful.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And one last thing... In a discussion with the "power" team, I listed a bunch of different ways we can have power (or influence): speaking louder, speaking more persuasively, deciding on a process for the team to follow, holding the marker and thus acting as scribe... &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That last idea had some impact on the participant who had been acting as scribe. She had been thinking that by acting as scribe, she would be &lt;i&gt;avoiding&lt;/i&gt; taking power in this simulation. But the scribe can influence what gets recorded, who gets listened to. It's a position of power. We coaches who sometimes facilitate meetings by acting as scribe, should keep that in mind. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There are all sorts of power.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-8055936498943450512?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/8055936498943450512/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2010/11/going-meta-sometimes-helps.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/8055936498943450512'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/8055936498943450512'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2010/11/going-meta-sometimes-helps.html' title='Going meta sometimes helps.'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-2046962070160345089</id><published>2010-11-13T13:39:00.000-08:00</published><updated>2010-11-13T13:53:12.768-08:00</updated><title type='text'>7 Design Transformations</title><content type='html'>Joshua Kerievsky summarizes 7 design transformation techniques at &lt;a href="http://bit.ly/bZn42O"&gt;Industrial Blogic&lt;/a&gt;. We teach these in our &lt;a href="http://bit.ly/9T5S9I"&gt;Refactoring Album&lt;/a&gt; and use these in our daily work. It's a quick read. Check it out!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-2046962070160345089?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/2046962070160345089/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2010/11/7-design-transformations.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/2046962070160345089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/2046962070160345089'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2010/11/7-design-transformations.html' title='7 Design Transformations'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-5619804938074045389</id><published>2010-11-04T18:15:00.000-07:00</published><updated>2010-11-04T18:25:12.798-07:00</updated><title type='text'>Beautiful tools</title><content type='html'>Go to this &lt;a href="http://developer.apple.com/library/mac/#featuredarticles/StaticAnalysis/index.html"&gt;page&lt;/a&gt; and scroll down to Figure 4. Apple's IDE graphically shows you the results of static analysis by drawing arrows over the code.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Beautiful.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-5619804938074045389?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/5619804938074045389/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2010/11/beautiful-tools.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/5619804938074045389'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/5619804938074045389'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2010/11/beautiful-tools.html' title='Beautiful tools'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-3658926261184655960</id><published>2010-11-03T10:24:00.000-07:00</published><updated>2010-11-03T15:22:20.741-07:00</updated><title type='text'>Virtual Functions in C++ make TDD easier, but at what cost?</title><content type='html'>&lt;div&gt;Virtual functions in C++ make allow us to do mocking, stubbing, and faking, which helps us test code in isolation in TDD or just microtesting in general. A frequent objection to virtual functions is that it "costs more" than simple function calls.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The cost of a virtual function is hardly ever important, unless the function is being called in a very tight loop, or it is being called at interrupt-time, and even then compiler / linker optimization might overcome the "extra" table-lookup that makes a function virtual. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In C, calling a function through a function-pointer is equivalent to calling a virtual function in C++. Implementations of file-systems APIs in Linux and BSD Unix use function-pointers internally to do what C++ does with virtual functions.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The cost of cache-misses (on-chip cache and off-chip cache) is a LOT bigger than the cost of virtual function pointers. Incorrect branch-prediction is also a CPU-level cost that people fail to understand. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The best way to know if making a function virtual has any user-apparent cost, is to measure the application via some tool that does non-invasive timing. Often, there will be no visible effect if you make some functions virtual that were non-virtual before. (I'm talking about REAL applications, not benchmarks.)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-3658926261184655960?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/3658926261184655960/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2010/11/virtual-functions-in-c-make-tdd-easier.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/3658926261184655960'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/3658926261184655960'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2010/11/virtual-functions-in-c-make-tdd-easier.html' title='Virtual Functions in C++ make TDD easier, but at what cost?'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-2527803199692889634</id><published>2010-10-23T23:10:00.000-07:00</published><updated>2010-10-23T23:23:26.090-07:00</updated><title type='text'>Summoning the Demon: Testing</title><content type='html'>James Bach, advocate of exploratory testing and one of the founders of context-driven testing movement. He gave a keynote in Sweden. Watch it here:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;object id="bplayer" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="320" height="276"&gt;&lt;embed name="bplayer" src="http://static.bambuser.com/r/player.swf?vid=1088504" type="application/x-shockwave-flash" width="320" height="276" allowfullscreen="true" allowscriptaccess="always" wmode="opaque"&gt;&lt;/embed&gt;&lt;param name="movie" value="http://static.bambuser.com/r/player.swf?vid=1088504"&gt;&lt;param name="allowfullscreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;param name="wmode" value="opaque"&gt;&lt;/object&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;He says at one point "You got to get good at what you're doing, and you got to get credit for what you're doing." But they don't blog about it, don't talk about it on the internet. They don't establish a reputation. Then they don't have a fall-back position if they disagree with some stupid metrics that their managers want to impose on the testers.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There are lots of programmers out there blogging about their craft. Percentage-wise its probably a small number, but it seems like it's even fewer testers that do so. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;James also says "I have a bunch of Google alerts. If you use certain code words in your blog I will read them. [...] &lt;b&gt;If you say the name of the demon, he shall appear: &lt;i&gt;and read your blog.&lt;/i&gt;&lt;/b&gt;"&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;:-)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Hi James!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-2527803199692889634?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/2527803199692889634/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2010/10/summoning-demon-testing.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/2527803199692889634'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/2527803199692889634'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2010/10/summoning-demon-testing.html' title='Summoning the Demon: Testing'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-1358474101357799983</id><published>2010-10-02T12:28:00.000-07:00</published><updated>2010-10-02T12:31:38.701-07:00</updated><title type='text'>My Response on TDD list on the "excessive cost" of unit testing</title><content type='html'>&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Helvetica; -webkit-tap-highlight-color: rgba(26, 26, 26, 0.296875); -webkit-composition-fill-color: rgba(175, 192, 227, 0.230469); -webkit-composition-frame-color: rgba(77, 128, 180, 0.230469); font-size: medium; "&gt;&lt;blockquote type="cite"&gt;&lt;span&gt;And also, and excessive focus on unit testing inhibits refactoring.&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;Not in my experience.&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote type="cite"&gt;&lt;span&gt;What if I split C into two or more classes?&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;So C was too large and now you're fixing it, splitting it into C and CPrime. Great! Good unit tests for C insure this refactoring doesn't break desired behaviors. If a test fails, it's doing its job, warning you that you did part of the refactoring wrong. Because unit tests are closer to code they test than integration tests, it will be easier to locate the problem and fix it.&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote type="cite"&gt;&lt;span&gt;Do I have to rework and split all its tests, so that they'll be one-class unit tests on the new classes?&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;No. If you do refactorings in small steps as described in Martin Fowler's book, the tests don't change (except for name and signature changes that I hope you are using a refactoring tool to do.) CPrime is indirectly tested by the tests for C.&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;AFTER I've split the class, and the tests are still passing, I may move some tests to directly test CPrime. &lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;Further refactorings might remove some of the forwarding-functions from C that you would have created if you were doing the Extract Class/Move Method refactorings as per Fowler.&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote type="cite"&gt;&lt;span&gt;What if I decide to combine C and D into a single class.  What will that do to my tests?&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;You change change all users of C and D appropriately, whether those users are tests or production code. Refactoring tools make that easy. &lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;Avoiding the code smell "Duplicated Code" in both your test code and your production code insures that all the changes required for a Merge Class Refactoring are minimal. &lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote type="cite"&gt;&lt;span&gt;And how will my tests help me determine if the new combined class is correct?  If I have only unit tests for C and D, then really I won't have any way to determine if the new combined "CD" class is working correctly?&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;There are three activities in TDD: (1) writing a test (usually one that fails first), (2) writing code to pass a test, (3) refactoring to clean up code smells. &lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;By separating #3 from #2, you are much less likely to have problems. You do need new skills: refactoring is not the same as "rewriting"; you can't let code smells go unfixed for very long; and you need to know how (and when) to use fakes and mocks to test how objects collaborate and also break dependencies to test in isolation.&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;Because tests in TDD _do_ allow collaboration between multiple objects, they might not fit your definition of a "unit test". That's one reason we at Industrial Logic call them "microtests". Each microtest only tests a single behavior, setting up the class under test with real or fake collaborators as needed.&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;You might find IL's courses at&lt;a href="http://elearning.industriallogic.com/gh" detectors="true"&gt;http://elearning.industriallogic.com/gh&lt;/a&gt; helpful for learning Refactoring, Code Smells, TDD, etc. &lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;Hope this helps,&lt;/span&gt;&lt;br /&gt;&lt;span&gt;C Keith Ray&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-1358474101357799983?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/1358474101357799983/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2010/10/my-response-on-tdd-list-on-excessive.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/1358474101357799983'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/1358474101357799983'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2010/10/my-response-on-tdd-list-on-excessive.html' title='My Response on TDD list on the &quot;excessive cost&quot; of unit testing'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-4046338198659774498</id><published>2010-09-07T08:36:00.000-07:00</published><updated>2010-09-07T08:38:07.426-07:00</updated><title type='text'>What's the most important thing?</title><content type='html'>For Agile software development, what is the one thing that's so important that anything else is a distraction?&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;short answer: &lt;b&gt;Working software&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;slightly longer answer: &lt;b&gt;Being able to reliably build working software&lt;/b&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Thoughts?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-4046338198659774498?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/4046338198659774498/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2010/09/whats-most-important-thing.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/4046338198659774498'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/4046338198659774498'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2010/09/whats-most-important-thing.html' title='What&apos;s the most important thing?'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-4347987020227176836</id><published>2010-04-23T16:35:00.001-07:00</published><updated>2010-04-23T16:35:59.807-07:00</updated><title type='text'>Mind Heart Body 2</title><content type='html'>&lt;ol&gt;&lt;li&gt;Mind: More time creating value! &lt;/li&gt;&lt;li&gt;Heart: No more debugging! &lt;/li&gt;&lt;li&gt;Body: Test-drive new features. &lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;a href="http://bit.ly/7pla9C"&gt;http://bit.ly/7pla9C&lt;/a&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-4347987020227176836?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/4347987020227176836/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2010/04/mind-heart-body-2.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/4347987020227176836'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/4347987020227176836'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2010/04/mind-heart-body-2.html' title='Mind Heart Body 2'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-5353852635475653742</id><published>2010-04-23T16:33:00.000-07:00</published><updated>2010-04-23T16:36:32.085-07:00</updated><title type='text'>Mind Heart Body 1</title><content type='html'>&lt;ol&gt;&lt;li&gt;Mind: More time creating value! &lt;/li&gt;&lt;li&gt;Heart: No more debugging! &lt;/li&gt;&lt;li&gt;Body: Write microtests whenever you find bugs.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt; &lt;a href="http://bit.ly/7pla9C"&gt;http://bit.ly/7pla9C&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-5353852635475653742?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/5353852635475653742/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2010/04/mind-heart-body-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/5353852635475653742'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/5353852635475653742'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2010/04/mind-heart-body-1.html' title='Mind Heart Body 1'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-7659371621220048888</id><published>2010-04-16T22:51:00.000-07:00</published><updated>2010-04-16T22:58:14.392-07:00</updated><title type='text'>Test-Driving C++</title><content type='html'>&lt;p&gt;Reprinted from my blog in 2007.Jan.31 Wed&lt;/p&gt;&lt;p&gt;In most languages, when I'm using Test Driven Development to create a class, I only put into that class those methods or fields that I needed to pass a test. C++ has some exceptions to that, given how the compiler will generate aspects of a "canonical c++ class" for you.&lt;/p&gt;&lt;p&gt;I should explain the idea of a "Canonical C++" class. Imagine that I have this code:&lt;/p&gt;&lt;pre&gt;class Buddy&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;  Icon* myIcon;&lt;br /&gt;  std::string myName;&lt;br /&gt;};&lt;/pre&gt;&lt;p&gt;Now, I didn't write a constructor, destructor, nor an assignment-operator, but the compiler did create those for me. It's as if I really wrote the following code:&lt;/p&gt;&lt;pre&gt;class Buddy&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;   Icon* myIcon;&lt;br /&gt;   std::string myName;&lt;br /&gt;&lt;br /&gt;   Buddy() // default constructor&lt;br /&gt;       : myName() // invokes std::string's default constructor&lt;br /&gt;   { // myIcon is not initialized, it probably has a garbage value here.&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   Buddy(const Buddy&amp;amp; other) // copy constructor&lt;br /&gt;       : myIcon( other.myIcon ) // copy the variable's value&lt;br /&gt;       , myName( other.myName ) // invokes std::string's copy constructor&lt;br /&gt;   {&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   ~Buddy() // destructor&lt;br /&gt;   {&lt;br /&gt;   } // invokes std::string's destructor for myName.&lt;br /&gt;&lt;br /&gt;   Buddy&amp;amp; operator=(const Buddy&amp;amp; other)&lt;br /&gt;   { // assignment operator&lt;br /&gt;       myIcon = other.myIcon; // copy the variable's value&lt;br /&gt;       myName = other.myName; // call std::string's assignment operator&lt;br /&gt;   }&lt;br /&gt;};&lt;/pre&gt;&lt;p&gt;A "canonical" C++ class has default constructor (and/or other constructors), copy constructor, destructor, and assignment-operator. These may be defined by the programmer or created by the compiler.&lt;/p&gt;&lt;p&gt;And this invisible compiler-generated code can be wrong, particularly if ownership of pointers or other resources is involved. Let's say that I test-drive a default constructor that sets up myIcon to point to a newly-created Icon object, and write the corresponding destructor code to delete the Icon object. It's hard to verify the "state" of an object after its destructor is called ('cuz it's GONE), but there are a few tricks to verify the behavior of a destructor that I won't get into here.&lt;/p&gt;&lt;pre&gt;class Buddy&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;   Icon* myIcon;&lt;br /&gt;   std::string myName;&lt;br /&gt;&lt;br /&gt;   Buddy()&lt;br /&gt;       : myIcon( NULL )&lt;br /&gt;       , myName( "no name" )&lt;br /&gt;   {&lt;br /&gt;       myIcon = new Icon(Icon::DEFAULT_ICON);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   ~Buddy()&lt;br /&gt;   {&lt;br /&gt;       delete myIcon;&lt;br /&gt;   }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;SPECIFY_(Context,BuddyHasDefaultNameAndIcon)&lt;br /&gt;{&lt;br /&gt;   Buddy* aBud = new Buddy;&lt;br /&gt;   VALUE( aBud-&gt;myName ).SHOULD_EQUAL( "no name" );&lt;br /&gt;   VALUE( aBud-&gt;myIcon ).SHOULD_NOT_EQUAL( NULL );&lt;br /&gt;   delete aBud;&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;This test will pass. (by the way, I'm using "ckr_spec" here, a Behavior-Driven-Design framework I've written in C++ in my spare time. I'll publish more about ckr_spec one of these days.) However, this test doesn't exercise the compiler-created copy-constructor and assignment operators. AND THOSE ARE WRONG. Nothing (besides self-discipline) prevents anyone from writing the following (crashing) code:&lt;/p&gt;&lt;pre&gt;void crashingCode()&lt;br /&gt;{&lt;br /&gt;   Buddy keith;&lt;br /&gt;   Buddy keithClone(keith); // calls compiler-created copy constructor&lt;br /&gt;   Buddy anotherKeith;&lt;br /&gt;   anotherKeith = keith; // calls compiler-created assignment operator&lt;br /&gt;&lt;br /&gt;// destructors are called invisibly here - crash deleting the same Icon&lt;br /&gt;// object 3 times. (Also leaks an Icon object, too.)&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;The compiler-created copy constructors just copy the pointer to the Icon object. They don't create a NEW Icon object. So in "crashingCode" above, the Icon object created in the constructor of "keith" gets deleted three times, when the destructors for the "keith", "keithClone", and "anotherKeith" objects get called at the end of the function.&lt;/p&gt;&lt;p&gt;Therefore, when I'm test-driving a C++ class, very early on, I make a decision. Is this a "value" class that is going support the copy-constructor and assignment-operator, or an "entity" class that should never be copied because the instance represents something with a persistent identity? (These are some over-simplified ideas from Domain-Driven Design.) I can change my mind later, of course.&lt;/p&gt;&lt;p&gt;If my class is going to allow "value" semantics, then I'll need to write some tests to assure that the copy-constructor and assignment operator function correctly, &lt;i&gt;whether I've written them, or the compiler has generated them&lt;/i&gt;.&lt;/p&gt;&lt;p&gt;If I'm not going to allow "value" semantics, then I need to signal to the compiler and to my fellow programmer not to generate or use the copy-constructor and assignment-operator. Declaring them private and unimplemented is how to do that.&lt;/p&gt;&lt;pre&gt;class Buddy&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;   Icon* myIcon;&lt;br /&gt;   std::string myName;&lt;br /&gt;&lt;br /&gt;   Buddy()&lt;br /&gt;       : myIcon( NULL )&lt;br /&gt;       , myName( "no name" )&lt;br /&gt;   {&lt;br /&gt;       myIcon = new Icon(Icon::DEFAULT_ICON);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   ~Buddy()&lt;br /&gt;   {&lt;br /&gt;       delete myIcon;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;private:&lt;br /&gt;   Buddy(const Buddy&amp;amp; other);&lt;br /&gt;       // don't implement copy constructor&lt;br /&gt;&lt;br /&gt;   Buddy&amp;amp; operator=(const Buddy&amp;amp; other);&lt;br /&gt;       // don't implement assignment operator&lt;br /&gt;};&lt;br /&gt;// the crashingCode example will not compile now.&lt;/pre&gt;&lt;p&gt;For entity objects, quite often I don't want to allow the default constructor either, so I would declare that private and unimplemented as well.&lt;/p&gt;&lt;p&gt;The moral of the story is that in C++, sometimes you have to write code to prevent the compiler from writing the code for you. Just add that to your TDD/BDD development process.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-7659371621220048888?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/7659371621220048888/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2010/04/test-driving-c.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/7659371621220048888'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/7659371621220048888'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2010/04/test-driving-c.html' title='Test-Driving C++'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-9134991049765524064</id><published>2009-09-13T14:10:00.000-07:00</published><updated>2009-09-13T14:17:57.991-07:00</updated><title type='text'>Lean in a Nutshell</title><content type='html'>(originally posted 2003 Dec. 31 on my old blog-site)&lt;br /&gt;&lt;br /&gt;On the &lt;a href="http://groups.yahoo.com/group/leandevelopment/"&gt;Lean Development&lt;/a&gt; mailing list, John Roth summarizes the heart of Lean: (my emphasis)&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Lean is the opposite of fat, and the only basic principle of lean thinking is to &lt;span style="font-weight:bold;"&gt;eliminate waste&lt;/span&gt;. As the saying goes, all else is commentary, or at least an elaboration on that one basic thought: find a &lt;span style="font-weight:bold;"&gt;faster, better, cheaper way to add value&lt;/span&gt; to the product, and do it at all scales, from the total, end to end process on down to the individual practices used to construct it.&lt;br /&gt;&lt;br /&gt;[...] In manufacturing, the first exercise is to squeeze as much in-process inventory out of the value chain as possible. Doing that will force a huge number of other beneficial changes.&lt;br /&gt;&lt;br /&gt;In Lean Software Development, the first exercise is to go to fixed length iterations, where you have a production quality deployable piece of software at the end of each iteration. Doing that one thing will force a huge number of other changes in the process. I can't emphasize those two criteria too much: production quality and deployable. If you need further testing, signoffs or work from some other department after the iteration ends, you don't have it.[...]&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Let's look at the seven core principles of lean, and compare them to Extreme Programming practices:&lt;br /&gt;&lt;br /&gt;1. Eliminate Waste. Waste is anything that doesn't contribute to adding value to the product. One-hour status meetings waste time, so XP has 15-minute daily standup meetings instead. Excessive documentation and planning wastes time and energy, so XP recommends creating just enough documentation and planning, at appropriate levels of detail. Debugging is a waste, so XP does test-driven-development, which reduces debugging time and reduces time spent manually testing. Slow communication to/from the Customer/Domain Expert is a waste, so XP recommends having the Customer on-site.&lt;br /&gt;&lt;br /&gt;2. Amplify Learning. Creating software is a 'learning' process. Typically developers do this learning alone, and that knowledge doesn't spread around to other developers very quickly. XP does coding in pairs to spread knowledge around faster. (Code reviews can also do this, but with higher overhead.) The Customer/Domain Expert is learning, too, as he sees his ideas implemented and developers ask him for details needed for acceptance tests. XP teams often do Retrospectives each iteration to bring learning to the whole team. Having all the developers and Customer working in a "war-room" also helps the whole team learn together.&lt;br /&gt;&lt;br /&gt;3. Decide as Late as Possible. In Release Planning, stories are "promises for future communication" - the Customer/Domain Expert describes each feature/story in just enough detail for the engineers to provide a rough estimate. In Iteration Planning, the Customer describes the story in more detail, so the engineers can break it down into a task-list and/or rough design. The Customer/Tester specifies acceptance tests, which test the "what" not the "how", and then the programmers do test-driven-development where "what" tests and "how" coding are interleaved in a short cycle.&lt;br /&gt;&lt;br /&gt;4. Deliver as Fast as Possible. "Simple Code" does everything necessary for the current requirements, but not more, so the team can ship it quickly. Keeping the quality high via test-driven-development avoids coding on an unstable foundation, wasting time debugging. Having the Customer/Domain Expert within range of spoken questions allows getting requirements into code in a minimum of time.&lt;br /&gt;&lt;br /&gt;5. Empower the Team. XP encourages all team members to design, test, and code, instead of restricting those activities to a few. It encourages people to sign up for tasks, instead of assigning them to those who may not be as willing or as able. Anyone can improve code at any time, as long as the tests continue to run - allowing new learnings to be reflected in the code/design.&lt;br /&gt;&lt;br /&gt;6. Build Integrity In. With short iterations where something isn't "done" until it passes (automated and manual) acceptance testing, and test-driven-development insuring that every line of code is tested, the XP team always builds on top of working software. In every iteration, all automated testing is repeated frequently, detecting as soon as possible any "breakage" of code. Any bugs found by manual testing or automated tests failing are not just fixed, but also force the creation of new automated tests.&lt;br /&gt;&lt;br /&gt;7. See the Whole. Before beginning the first iteration, the XP team has a release plan. The Customer/Domain Expert has created that plan with the development team, and together they maintain and update the plan throughout the project, measuring and charting progress. Code is only implemented according to the current and previous requirements, so there is no work wasted on a requirement that may be dropped... however, engineers are not going to write code that will be difficult to adapt to that future requirement in that future comes around. To use the (not very good bridge-building analogy): the draw-bridge may not have motors in this iteration, but the builders are not going to build the bridge out of stone in this iteration, ignoring the need for mobility in the future.&lt;br /&gt;&lt;br /&gt;By the way, I hate the "bridge-building" analogy, because writing software isn't building, it is designing. Running the compiler and linker associated "build" scripts, etc., are the "building". If building a bridge were as quick and easy as running a compiler and linker, we'd build bridges multiple times in order to test them. Any comparison of software development to bridges should be to designing bridges - an iterative, learning activity where multiple solutions are designed and tested (via mathematical/computer models or physical models) until all the requirements are met.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-9134991049765524064?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/9134991049765524064/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2009/09/lean-in-nutshell.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/9134991049765524064'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/9134991049765524064'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2009/09/lean-in-nutshell.html' title='Lean in a Nutshell'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-7335112528950361155</id><published>2009-06-10T20:13:00.000-07:00</published><updated>2009-06-10T20:22:11.165-07:00</updated><title type='text'>Measured Throughput - Where are your bottlenecks?</title><content type='html'>Agile Hiring: see Esther Derby's article on &lt;a href="http://www.computerworld.com/developmenttopics/development/story/0,10801,91817,00.html"&gt;Hiring for a Collaborative Team&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Johanna Rothman &lt;a href="http://www.jrothman.com/weblog/archive/2004_04_01_mpdarchive.html#108117703530198800"&gt;writes&lt;/a&gt; about an organization where the number of requirements implemented are always significantly less than the number of requirements requested. They've been blaming the testers (!) and not seeing that their throughput through the whole system is limited. Given the numbers that she posts, I compute that the through-put is about 3.4 completed requirements per week for project 1, 3.7 per week for project 2, and 2.3 per week for project 3.&lt;br /&gt;&lt;br /&gt;If that company accepted that they're only going to get about 3 requirements per week implemented, no matter how long the project is, they could avoid waste in the "requirements/design" phase by not specifying more requirements than their measured through-put allows.&lt;br /&gt;&lt;br /&gt;They could also use that figure to move to incremental development as well, and maybe learn practices that would improve throughput as well. If they used XP or another appropriate set of agile practices, they could maximize information-flow and minimize delays between requirements, implementation, and testing.&lt;br /&gt;&lt;br /&gt;To find the bottle-neck, we need to know who's waiting on whom in this organization. Is there a queue of finished-but-not-tested work piling up in front of the testers? Then it could be that the testers are the bottleneck. One way to deal with a bottleneck is to change to a "pull system". In this case, a programmer only does implementation when tester is about to be ready to test their work. That leaves the programmers idle, but then they could use that "idle" time to improve their development process (code reviews, unit testing, etc.)&lt;br /&gt;&lt;br /&gt;In this system, the bottleneck is the programmers. The "pull system" can extend to the requirements: don't specify a requirement until a programmer about to be ready to implement it and a tester is about ready to test it. To move out of phasist approach, work on testing (creating automated tests) and implementation can overlap -- or (the XP way) the programming can actually follow the creation of tests and use the tests as an executable version of the specification.&lt;br /&gt;&lt;br /&gt;(Reposted: original was posted 2004.Apr.05 Mon)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-7335112528950361155?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/7335112528950361155/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2009/06/measured-throughput-where-are-your.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/7335112528950361155'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/7335112528950361155'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2009/06/measured-throughput-where-are-your.html' title='Measured Throughput - Where are your bottlenecks?'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-7442688383532270309</id><published>2009-05-27T13:52:00.000-07:00</published><updated>2009-05-27T14:07:27.734-07:00</updated><title type='text'>Test Driven Dialog</title><content type='html'>repost of my blog entry of 2003, April 08:&lt;br /&gt;&lt;br /&gt;This is a dialog I created in July 2002, from messages on the &lt;a href="http://groups.yahoo.com/group/testdrivendevelopment/message/1732"&gt;Test Driven Development&lt;/a&gt; mailing list -- an email conversation between Robert Blum and Roger Lipscombe. After my editing, they didn't recognize their words, so perhaps I did a little more writing than editing. Any similarity to my favorite comics characters is purely coincidence.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Calvin&lt;/span&gt;: I don't do test driven programming. I write some code, and test it manually, walking through it in the debugger, checking that it works.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Hobbes&lt;/span&gt;: How do you know that it works? Could you express that as a test before you run your code?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Calvin&lt;/span&gt;: I can't think about the test until I've thought about the code&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Hobbes&lt;/span&gt;: Changing the habit of writing code before the test can be a bother. Try this: Write the code on paper. Then write a test.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Calvin&lt;/span&gt;: Paper?!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Hobbes&lt;/span&gt;: What if you just outlined the code on a whiteboard and didn't write any real code? Could you still write a test first?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Calvin&lt;/span&gt;: I'd feel silly doing that alone.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Hobbes&lt;/span&gt;: What if you explained it to your pair partner? Could you still write a test first, or maybe have your pair partner write the test?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Calvin&lt;/span&gt;: That could work.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Hobbes&lt;/span&gt;: I notice you're refactoring without tests. What's that like?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Calvin&lt;/span&gt;: After I refactor, I have to test it again manually, in case I make a mistake doing the refactoring.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Hobbes&lt;/span&gt;: Wouldn't it be easier to run some quick automated tests before and after you refactor?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Calvin&lt;/span&gt;: Well duh! If I had the tests.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Hobbes&lt;/span&gt;: If you do test-driven development, your tests drive the design of your code, and as a side-benefit, you get a nice small set of automated tests that make refactoring safe.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Calvin&lt;/span&gt;: Perhaps if I start by thinking about the interfaces that my class or module would need to support, I would be able to write the unit test first? Does this sound like the kind of thing I should be trying more of?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Hobbes&lt;/span&gt;: I think so. If I were given just the task of writing a class or module, my first test would describe a very simple case of what I wanted from that code. The interface of this not-yet-written code is evolving, of course, during my test-driven development process. Since I'm calling the functions that I need at each moment, without a care how (or if) they are implemented, it tends to create a pretty useable interface.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Calvin&lt;/span&gt;: So you find out quickly if your interface functions are no good when you're forced to use them as client, in the tests, before investing a lot of work at writing them!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Hobbes&lt;/span&gt;: Now you're getting it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Calvin&lt;/span&gt;: Tell me, when you think of a feature, is your next thought about testing or implementation?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Hobbes&lt;/span&gt;: I just think about using that feature. Which leads me to an example of how I would use it. Now I just write down the results I expect from that, and voila, there's the test. I'm not even actively thinking 'I have to write a test now. How can I test it?'. My main focus is how I can use it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;J. B. Rainsberger added a few more lines:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Hobbes&lt;/span&gt;: Have you written tests for that code yet?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Calvin&lt;/span&gt;: Tests?! TESTS?! I don't need tests! What do I need tests for? Don't you think I can write something this simple without using tests as a crutch?! I know it's right!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Hobbes&lt;/span&gt;: (rolling his eyes) Of course you do.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Calvin&lt;/span&gt;: Right. Now help me fix these last four bugs.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;And Laurent Bossavit capped it off:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Hobbes&lt;/span&gt;: I thought I was doing that.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-7442688383532270309?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/7442688383532270309/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2009/05/test-driven-dialog.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/7442688383532270309'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/7442688383532270309'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2009/05/test-driven-dialog.html' title='Test Driven Dialog'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-5092024305495728637</id><published>2009-03-10T19:18:00.000-07:00</published><updated>2009-03-10T19:31:10.500-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='video'/><category scheme='http://www.blogger.com/atom/ns#' term='blog'/><category scheme='http://www.blogger.com/atom/ns#' term='industrial logic'/><category scheme='http://www.blogger.com/atom/ns#' term='technical debt'/><category scheme='http://www.blogger.com/atom/ns#' term='elearning'/><title type='text'>New Industrial Blogic</title><content type='html'>&lt;a href="http://www.industriallogic.com/"&gt;Industrial Logic, Inc.&lt;/a&gt;, my employer, now has a blog, built using technology from our eLearning software. (Which means it doesn't have an RSS feed yet, but I'm sure it will eventually.)&lt;br /&gt;&lt;br /&gt;The first entry, "Do What You Love In A Down Economy" by Joshua Kerievsky, is &lt;a href="https://elearning.industriallogic.com/gh/submit?Action=PageAction&amp;album=blog2009&amp;path=blog2009/march/doWhatYouLove&amp;devLanguage=Java"&gt;here&lt;/a&gt;. I'll probably contribute blog entries there, as well continuing to post, perhaps, more personal blog entries here.&lt;br /&gt;&lt;br /&gt;Josh has also &lt;span style="font-style:italic;"&gt;finally&lt;/span&gt; made visible to the public, the page in our eLearning where graphically demonstrates &lt;a href="https://elearning.industriallogic.com/gh/submit?Action=PageAction&amp;album=recognizingSmells&amp;path=recognizingSmells/technicalDebt/technicalDebtMismanagement&amp;devLanguage=Java"&gt;technical debt&lt;/a&gt;. It's the movie where a printout of a single function is draped out in a hallway, 28 pages long.&lt;br /&gt;&lt;br /&gt;Students of our training courses and &lt;a href="https://elearning.industriallogic.com/gh/submit?Action=BrowseAlbumsAction"&gt;eLearning&lt;/a&gt; have been asking Josh to make this video public for years. Now it is.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-5092024305495728637?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/5092024305495728637/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2009/03/new-industrial-blogic.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/5092024305495728637'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/5092024305495728637'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2009/03/new-industrial-blogic.html' title='New Industrial Blogic'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-7879909438715010938</id><published>2009-02-05T09:25:00.001-08:00</published><updated>2009-02-05T09:40:37.493-08:00</updated><title type='text'>Who Tests the Tests?</title><content type='html'>Q: Who tests the tests?&lt;br /&gt;A: The whole team.&lt;br /&gt;&lt;br /&gt;1. Story Tests or Customer Tests test the fully-integrated application. Those tests are developed in close collaboration with the Customer and his/her helpers (for example, Business Analysts, Professional Testers). &lt;br /&gt;&lt;br /&gt;2. Programmer Tests, which come from doing Test Driven Development, are tested by seeing them fail (for the right reasons) before making them pass. When pair programming, two sets of eyes see those tests and the code that makes them pass.&lt;br /&gt;&lt;br /&gt;The Programmer and Story tests are also run again many times during development. And incremental/iterative development (ala XP, or Scrum, or any of the other Agile methods) requires refactoring as the team adds new features. Refactoring will change the code, but the tests should continue to pass.&lt;br /&gt;&lt;br /&gt;The tests continue to pass despite refactoring because the behavior of the tested code should stay the same until both the tests and code-under-test are deliberately changed. If the tests fail during refactoring, either the tests are too close to the code, or the refactoring wasn't done entirely correctly. In either case, at least one or two programmers are going to look at those tests and the associated code again. So the tests are getting another set of eyes reviewing them.&lt;br /&gt;&lt;br /&gt;Sometimes I have written a programmer test, which I expect to fail, and it passes unexpectedly. I take that seriously. Is the test not good enough? Is the code that I planned to change already doing what I want? Good thing I have a pair to help me answer those questions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-7879909438715010938?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/7879909438715010938/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2009/02/who-tests-tests.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/7879909438715010938'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/7879909438715010938'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2009/02/who-tests-tests.html' title='Who Tests the Tests?'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-2826080286358486998</id><published>2009-01-03T11:39:00.000-08:00</published><updated>2009-01-29T10:09:00.894-08:00</updated><title type='text'>Peer Discussion Improves Student Performance</title><content type='html'>Science Daily &lt;a href="http://www.sciencedaily.com/releases/2009/01/090102100234.htm"&gt;reports&lt;/a&gt; that peer discussion using "clickers" helps students learn in a way that simple lecturing does not.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Clickers are simple audience response devices, similar to a TV remote control, that allow students to record their answers to thought-provoking, multiple-choice questions in class. After students answer a question individually, the instructor often asks them to discuss the question and then vote again before revealing the answer. After discussion, they usually do better on the question - but why?&lt;br /&gt;&lt;br /&gt;The important point is that none of the students were told what the right answer was," said Su. "Even when students in a discussion group all got the initial answer wrong, after talking to each other they were able to figure out the correct response, to learn. That was unexpected, and I think that's dramatic.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.industriallogic.com/"&gt;Industrial Logic's&lt;/a&gt; Agile &lt;a href="https://elearning.industriallogic.com/gh/submit?Action=BrowseAlbumsAction"&gt;eLearning&lt;/a&gt; allows students to add comments or questions on every page, and even comment or question specific parts of a quiz. You can see a sample of this in the new videos in the &lt;a href="https://elearning.industriallogic.com/gh/submit?Action=AlbumContentsAction&amp;album=welcome&amp;devLanguage=Java"&gt;Welcome&lt;/a&gt; Album. (See "Community and Feedback" in the track "Find Your Way: Start Here")&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-2826080286358486998?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/2826080286358486998/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2009/01/peer-discussion-improves-student.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/2826080286358486998'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/2826080286358486998'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2009/01/peer-discussion-improves-student.html' title='Peer Discussion Improves Student Performance'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-477978380199165584</id><published>2008-12-29T09:31:00.000-08:00</published><updated>2008-12-29T09:38:32.789-08:00</updated><title type='text'></title><content type='html'>William Wake described the essence of an automated test as &lt;a href="http://weblogs.java.net/blog/wwake/archive/2003/12/"&gt;Arrange, Act, Assert&lt;/a&gt;. I've added "Erase", to account for the clean-up that some tests have to do. You might ask why "Erase" added to "Arrange, Act, Assert" and not some word starting with "A". I think starting with "eh?" is close enough. :-)&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;"The thing about elves is they've got no ... begins with m," Granny snapped her fingers irritably."&lt;br /&gt;&lt;br /&gt;"Manners?"&lt;br /&gt;&lt;br /&gt;"Hah! Right, but no."&lt;br /&gt;&lt;br /&gt;"Muscle? Mucus? Mystery?"&lt;br /&gt;&lt;br /&gt;"No. No. No. Means like ... seein' the other person's point of view."&lt;br /&gt;&lt;br /&gt;Verence tried to see the world from a Granny Weatherwax perspective, and suspicion dawned.&lt;br /&gt;&lt;br /&gt;"Empathy?"&lt;br /&gt;&lt;br /&gt;"Right. None at all. Even a hunter, a good hunter, can feel for the quarry. That's what makes 'em a good hunter. Elves aren't like that. They're cruel for fun [...]"&lt;br /&gt;&lt;br /&gt;—Terry Pratchett, Lords and Ladies&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;In C++, with certain test frameworks, a test might be specified in a manner something like the following in C++.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;TEST(TestBlurImageFilter)&lt;br /&gt;{&lt;br /&gt;    // Arrange&lt;br /&gt;    string outfileName = NewTempFileName("TestImageFilter");&lt;br /&gt;    Image* sourceImage = new Image("lena.png");&lt;br /&gt;&lt;br /&gt;    // Act&lt;br /&gt;    ImageFilter* filter = new BlurImageFilter();&lt;br /&gt;    filter-&gt;ProcessToFile(sourceImage, outfileName);&lt;br /&gt;&lt;br /&gt;    // Assert&lt;br /&gt;    AssertImagesEqual("expected_lena_blurred.png", outfileName);&lt;br /&gt;&lt;br /&gt;    // Erase&lt;br /&gt;    DeleteTempFile(outfileName);&lt;br /&gt;    delete filter;&lt;br /&gt;    delete sourceImage;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Note: generally you don't want to deal with files in unit tests; working in-memory would be much faster. Also, if this is one of those frameworks that throws an exception, or otherwise aborts the test if an assertion fails, then the "Erase" portion of the test won't get executed if AssertImagesEqual failed. Let's assume that's not a problem for the moment.&lt;br /&gt;&lt;br /&gt;Let's imagine that you then write a another test like so:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;TEST(TestUnblurImageFilter)&lt;br /&gt;{&lt;br /&gt;    // Arrange&lt;br /&gt;    string outfileName = NewTempFileName("TestImageFilter");&lt;br /&gt;    Image* sourceImage = new Image("lena.png");&lt;br /&gt;&lt;br /&gt;    // Act&lt;br /&gt;    ImageFilter* filter = new UnblurImageFilter();&lt;br /&gt;    filter-&gt;ProcessToFile(sourceImage, outfileName);&lt;br /&gt;&lt;br /&gt;    // Assert&lt;br /&gt;    AssertImagesEqual("expected_lena_unblurred.png", outfileName);&lt;br /&gt;&lt;br /&gt;    // Erase&lt;br /&gt;    DeleteTempFile(outfileName);&lt;br /&gt;    delete filter;&lt;br /&gt;    delete sourceImage;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now you've got duplicated "Arrange" and "Erase" sections. And duplicated logic in tests can be just as bad it would be in production code. Fortunately, most test frameworks already have support for extracting "Arrange" and "Erase" to methods in a "test fixture". The above code could be refactored to something like the following:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class ImageFilterTests : public TestFixture&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;    ImageFilterTests()&lt;br /&gt;        : sourceImage(NULL), filter(NULL)&lt;br /&gt;    {&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    string outfileName;&lt;br /&gt;    Image* sourceImage;&lt;br /&gt;    ImageFilter* filter;&lt;br /&gt;&lt;br /&gt;    virtual void SetUp()&lt;br /&gt;    {&lt;br /&gt;        // Arrange&lt;br /&gt;        outfileName = NewTempFileName("TestImageFilter");&lt;br /&gt;        sourceImage = new Image("lena.png");&lt;br /&gt;    }&lt;br /&gt;    virtual void TearDown()&lt;br /&gt;    {&lt;br /&gt;        // Erase&lt;br /&gt;        DeleteTempFile(outfileName);&lt;br /&gt;        delete filter;&lt;br /&gt;        delete sourceImage;&lt;br /&gt;    }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;TEST_F(ImageFilterTests, TestBlurImageFilter)&lt;br /&gt;{&lt;br /&gt;    // Act&lt;br /&gt;    filter = new BlurImageFilter();&lt;br /&gt;    filter-&gt;ProcessToFile(sourceImage, outfileName);&lt;br /&gt;&lt;br /&gt;    // Assert&lt;br /&gt;    AssertImagesEqual("expected_lena_blurred.png", outfileName);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;TEST_F(ImageFilterTests, TestUnblurImageFilter)&lt;br /&gt;{&lt;br /&gt;    // Act&lt;br /&gt;    filter = new UnblurImageFilter();&lt;br /&gt;    filter-&gt;ProcessToFile(sourceImage, outfileName);&lt;br /&gt;&lt;br /&gt;    // Assert&lt;br /&gt;    AssertImagesEqual("expected_lena_unblurred.png", outfileName);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Not only has this eliminated the duplicated logic, most unit test frameworks will also guarantee running the TearDown method even if the test fails, so you don't have to write your own try/catch blocks or other contortions for exception-safe "erase".&lt;br /&gt;&lt;br /&gt;You'll see that I also added a constructor to insure that the pointer variables have valid NULL values so we don't delete garbage pointers if the Image or Filter objects were not allocated successfully. (You should consider using boost::shared_ptr and/or boost::scoped_ptr if you're dealing with object pointers in C++ code and tests, by the way.)&lt;br /&gt;&lt;br /&gt;In those C++ test frameworks where the test-fixture creation and deletion is done just before and after executing the test, the SetUp and TearDown methods can (almost always) be replaced with a constructor and destructor instead. Using that and boost::scoped_ptr to insure exception-safe object deletion would allow us to write the following code:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class ImageFilterTests : public TestFixture&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;    ImageFilterTests()&lt;br /&gt;        : outfileName(NewTempFileName("TestImageFilter")),&lt;br /&gt;          sourceImage(new Image("lena.png"))&lt;br /&gt;    {&lt;br /&gt;        // Arrange&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    virtual ~ImageFilterTests()&lt;br /&gt;    {&lt;br /&gt;        // Erase&lt;br /&gt;        DeleteTempFile(outfileName);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    string outfileName;&lt;br /&gt;    boost::scoped_ptr&lt;img src="" /&gt; sourceImage;&lt;br /&gt;    boost::scoped_ptr&lt;imagefilter&gt; filter;&lt;/imagefilter&gt;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;TEST_F(ImageFilterTests, TestBlurImageFilter)&lt;br /&gt;{&lt;br /&gt;    // Act&lt;br /&gt;    filter.reset(new BlurImageFilter());&lt;br /&gt;    filter-&gt;ProcessToFile(sourceImage.get(), outfileName);&lt;br /&gt;&lt;br /&gt;    // Assert&lt;br /&gt;    AssertImagesEqual("expected_lena_blurred.png", outfileName);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;TEST_F(ImageFilterTests, TestUnblurImageFilter)&lt;br /&gt;{&lt;br /&gt;    // Act&lt;br /&gt;    filter.reset(new UnblurImageFilter());&lt;br /&gt;    filter-&gt;ProcessToFile(sourceImage.get(), outfileName);&lt;br /&gt;&lt;br /&gt;    // Assert&lt;br /&gt;    AssertImagesEqual("expected_lena_unblurred.png", outfileName);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-477978380199165584?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/477978380199165584/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/12/william-wake-described-essence-of.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/477978380199165584'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/477978380199165584'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/12/william-wake-described-essence-of.html' title=''/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-5169035274676813623</id><published>2008-12-15T10:09:00.000-08:00</published><updated>2008-12-15T10:19:25.692-08:00</updated><title type='text'>C++ Mocking Framework</title><content type='html'>Google released &lt;a href="http://code.google.com/p/googletest/"&gt;Google Test for C++&lt;/a&gt; earlier this year, and just recently released &lt;a href="http://code.google.com/p/googlemock/"&gt;Google C++ Mocking Framework&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;These are extensively documented... check them out!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-5169035274676813623?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/5169035274676813623/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/12/c-mocking-framework.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/5169035274676813623'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/5169035274676813623'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/12/c-mocking-framework.html' title='C++ Mocking Framework'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-271286595257115662</id><published>2008-12-09T10:53:00.000-08:00</published><updated>2008-12-09T11:02:41.712-08:00</updated><title type='text'>What a Tangled Web We Weave, When Don't Have Effective Tracking</title><content type='html'>This is a re-post of a blog entry I wrote in 2003... &lt;br /&gt;&lt;br /&gt;Steve Norrie points to a recent online article by Jerry Weinberg published on CrossTalk, the Journal of Defense Software Engineering here: &lt;a href="http://stsc.hill.af.mil/CrossTalk/2003/04/weinberg.html"&gt;Destroying Communication and Control in Software Development.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I'd like to mention a few of the Extreme Programming (XP) solutions to some of the problems mentioned in this article. Be aware that XP is a light-weight process, relying on people rather than technology to do the right thing. (A savvy person can undermine technology anyway.)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Requirements&lt;/span&gt;. One of the first areas that communication can be destroyed is by not doing requirements well... not involving the customer, thinking that requirements are a waste of time, and so on. Extreme Programming recommends involving the customer, or a qualified representative of the customer, throughout the entire project. And in addition to talking about the requirements often and in detail, XP requires writing the requirements down in an executable form - automated acceptance tests.&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-weight:bold;"&gt;configuration management system&lt;/span&gt; (CMS). The CMS tracks requirements, design, code, test data, test results, user documentation, etc. Jerry notes that information in the CMS can be undermined by failing to keep it up to date, restricting read-access from people who should have access, removing data or failing to put data into it. Extreme Programming doesn't require any specific CMS system (software or otherwise) for this tracking, but does suggest using the simplest thing that actually works. For code, tests, and test data, I recommend using CVS or some other source-code-management system. For acceptance test results, many XP teams record those on a white board or poster board, updated them weekly or daily, charting them over the course of the project. XP does strongly recommend using index cards (story cards) for tracking requirements during initial and weekly planning, and also strongly recommends documenting the relationship between the automatic acceptance tests and the story cards. The person playing the Customer role, as well as the whole team, is responsible for keeping track of the stories. Many XP teams also record the stories in web-accessible ways, such as a &lt;a href="http://www.amazon.com/exec/obidos/ASIN/020171499X"&gt;wiki&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;In regards to a bug-tracking database, some XP teams track bugs the same way as stories - index cards and acceptance tests. You might think that this won't work, but consider that several XP teams have reported that their bug rate after implementing XP dropped from hundreds per six months to around one bug per month. It helps that bugs are not usually recorded until after a story is finished, and in XP, a story is not finished until it is passing its acceptance tests - this requires conversation between the tester and coder as soon as problems are noticed during the implementation and testing of the story. When a bug is recorded, it probably indicates that an acceptance test that was passing has started failing.&lt;br /&gt;&lt;br /&gt;Weinberg recommends that you "set and enforce a policy of complete and open information at all times." Agile processes like XP need accurate information daily. Many projects keep tracking information on poster boards and white boards, visible not only to all team members, but anyone in management who walks by. This is the "Project Progress Poster" concept that Weinberg recommends in &lt;a href="http://www.amazon.com/exec/obidos/ASIN/0932633323/"&gt;Quality Software Management: Anticipating Change&lt;/a&gt;. Since in my company, few people in management walk by, we keep tracking information in our wiki web pages.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Quality Assurance&lt;/span&gt;. Weinberg recommends "Prevent these abuses by having quality assurance report to the highest levels of management, and not to project management." In XP, QA testers are delegates of the person playing the Customer role -- the same person who defines the requirements. QA testers should not only be implementing and running the automated acceptance tests, but also running stress tests and manual testing of the product's user interface.&lt;br /&gt;&lt;br /&gt;Weinberg reports that testing often comes too late in the project to be useful in effective risk management. (There's a phrase in XP circles: "Doctor, it hurts when I do this..."). Don't wait until it is too late. XP requires testing to start in the first iteration of the project -- the first week. This and other XP practices enables effective risk management.&lt;br /&gt;&lt;br /&gt;The XP solutions noted here require that project management be willing to face reality at all times. One of the quickest routes to failing with XP is to &lt;span style="font-weight:bold;"&gt;not&lt;/span&gt; do XP. If project management destroys information, hides it, degrades it, or inserts misleading inforation, intentionally or not, it is going to be very difficult to have a successful project, no matter what the methodology used.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-271286595257115662?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/271286595257115662/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/12/what-tangled-web-we-weave-when-dont.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/271286595257115662'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/271286595257115662'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/12/what-tangled-web-we-weave-when-dont.html' title='What a Tangled Web We Weave, When Don&apos;t Have Effective Tracking'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-5726161404113870792</id><published>2008-11-25T10:39:00.000-08:00</published><updated>2008-11-25T10:48:25.733-08:00</updated><title type='text'>Science Daily Snips</title><content type='html'>Hopes for cleaner, safer energy:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.sciencedaily.com/releases/2008/11/081117131709.htm"&gt;Quicker, Easier Way To Make Coal Cleaner&lt;/a&gt;  "Construction of new coal-fired power plants in the United States is in danger of coming to a standstill, partly due to the high cost of the requirement — whether existing or anticipated — to capture all emissions of carbon dioxide [...] Instead of capturing all of its CO2 emissions, plants could capture a significant fraction of those emissions with less costly changes in plant design and operation [...]" &lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.sciencedaily.com/releases/2008/11/081120073126.htm"&gt;Making Gases More Transportable&lt;/a&gt; "Chemists at the University of Liverpool have developed a way of converting methane gas into a powder form [...] made out of a mixture of silica and water which can soak up large quantities of methane molecules [...] might be easily transported or used as a vehicle fuel."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-5726161404113870792?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/5726161404113870792/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/11/science-daily-snips.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/5726161404113870792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/5726161404113870792'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/11/science-daily-snips.html' title='Science Daily Snips'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-260996267689773196</id><published>2008-11-18T16:50:00.000-08:00</published><updated>2008-11-18T17:30:22.717-08:00</updated><title type='text'>Agile Methods Help Programmers Shine</title><content type='html'>Now and then someone says something like "Agile methods won't turn a mediocre programming into a star. That irritates me, because &lt;span style="font-weight:bold;"&gt;bad&lt;/span&gt; non-agile methods can make a very good programmer produce mediocre results. Without taking into account their environment, no one will know how good that "mediocre" programmer can actually be.&lt;br /&gt;&lt;br /&gt;A star NASCAR driver probably won't win the race, if his car has a flat tire and his support team can't or won't replace it. It doesn't matter how good the driver is, if the car is bad.&lt;br /&gt;&lt;br /&gt;One simple idea - &lt;span style="font-style:italic;"&gt;that the "traditional" way of developing an application is by implementing one complete layer at a time (whether bottom-up or top-down)&lt;/span&gt; - dooms a project to deliver no working features until late in the development cycle. When feedback finally arrives about the features (wrong requirements and/or wrong implementations), there is often not enough time to fix all the problems, and so the developers look bad. The testers also look bad if they don't have enough time to test, or enough time for fixes to be tested.&lt;br /&gt;&lt;br /&gt;Turn that idea around - &lt;span style="font-style:italic;"&gt;develop one vertical slice of an application at a time, so each feature can be tested as soon as possible&lt;/span&gt; - allows the customers and testers to provide feedback early in the development cycle. That can make a difference in how good the final product can be. Instead of projects running late or shipping with bugs, the project has known good features, can ship when enough features have been done, and the developers look so much better. People might say the project has star programmers.&lt;br /&gt;&lt;br /&gt;Many programmers and testers have been trained in that "traditional" style. It's assumed in many books, schools, and corporate cultures.  I call it "Unconscious Waterfall" when the style is just assumed. It takes a very remarkable developer to do good work in this environment.&lt;br /&gt;&lt;br /&gt;In some shops where they do something they call "Waterfall" and they make it work, it turns out that they verify that many features are working correctly early in the project - there are many places where requirements, tests, and code are examined, verified, validated. Those kinds of waterfall projects are pretty rare, from what I see.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-260996267689773196?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/260996267689773196/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/11/agile-methods-help-programmers-shine.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/260996267689773196'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/260996267689773196'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/11/agile-methods-help-programmers-shine.html' title='Agile Methods Help Programmers Shine'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-2146029447311079226</id><published>2008-11-05T09:27:00.000-08:00</published><updated>2008-11-05T09:29:45.946-08:00</updated><title type='text'>Adopt pets from the Humane Society</title><content type='html'>I adopted two cats last weekend. A five-month old female and a 3-year old female. Beautiful, curious, energetic, affectionate. I'll post pictures later. &lt;br /&gt;&lt;br /&gt;Check the web pages of your local humane society. They probably have cats, dogs, rabbits and birds. If you can, give some of them a loving home.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-2146029447311079226?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/2146029447311079226/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/11/adopt-pets-from-humane-society.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/2146029447311079226'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/2146029447311079226'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/11/adopt-pets-from-humane-society.html' title='Adopt pets from the Humane Society'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-5849488105375522448</id><published>2008-10-26T10:27:00.000-07:00</published><updated>2008-10-26T10:44:19.902-07:00</updated><title type='text'>When a student is ready...</title><content type='html'>When a student is ready, a teacher will appear. On an agile team, everyone can be a student and teacher. One team member may be more knowledgeable about the unit testing framework, but another may know more about object-oriented design. One team member may be more skilled with the IDE, and another knows the in-and-outs of the mocking framework. &lt;br /&gt;&lt;br /&gt;Pair programming is an excellent time for these kinds of knowledge transfer. Code-reviews (particularly those conducted asynchronously over email) are a low-bandwidth medium for teaching and learning. It can happen, but teaching and learning has a lot more room to occur with in-person interactions.&lt;br /&gt;&lt;br /&gt;The converse: "When a student is not ready, a teacher will not appear." also happens. People who reject pair programming without giving it a serious try are sometimes afraid to expose their fallibility. I didn't expect to enjoy pair programming, and when I first gave it a try, I was making typos and exposing my fallibility right from the start. And then the person I was pairing with was just as clumsy and fallible. As we continued to pair, we learned not only how fallible we are, but also how smart we are. We get to know we each as human beings. We find out that instead of being a waste of time, we make progress faster than we could if we were programming alone.&lt;br /&gt;&lt;br /&gt;It takes courage to pair program. Do it for a while, and you'll find it also provides more safety than programming alone does.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-5849488105375522448?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/5849488105375522448/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/10/when-student-is-ready.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/5849488105375522448'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/5849488105375522448'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/10/when-student-is-ready.html' title='When a student is ready...'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-3337573273085859777</id><published>2008-09-17T10:22:00.000-07:00</published><updated>2008-09-17T10:39:48.252-07:00</updated><title type='text'>Refactoring for Testable C++ at OOPSLA</title><content type='html'>I will be co-presenting a workshop on &lt;a href="http://www.oopsla.org/oopsla2008/program-overview/tutorials.html#tutorial23"&gt;Refactoring Legacy C++ Code to Testable C++&lt;/a&gt; with &lt;a href="http://www.infoq.com/interviews/Industrial-XP-Joshua-Kerievsky"&gt;Joshua Kerievsky&lt;/a&gt; at &lt;a href="http://www.oopsla.org/oopsla2008/registration.html"&gt;OOPSLA 2008&lt;/a&gt;. If you deal with C++ code and want to make it testable, this tutorial is for you.&lt;br /&gt;&lt;br /&gt;This tutorial for intermediate-level C++ programmers is based on my own pragmatic experience working with legacy C++, as well as the experience of other &lt;a href="http://www.industriallogic.com/"&gt;Industrial Logic&lt;/a&gt; coaches. It is part lecture with slides and video, and part practice on C++ code that we provide.&lt;br /&gt;&lt;br /&gt;I gave this workshop with &lt;a href="http://dobbscodetalk.com/index.php?option=com_myblog&amp;show=Five-Questions-With-Gil-Broza.html&amp;Itemid=29"&gt;Gil Broza&lt;/a&gt; at the &lt;a href="http://www.agile2008.org/"&gt;Agile 2008&lt;/a&gt; conference, and the class members really appreciated digging into the labs -- to the point that many of them choose to work on the code and tests in one of the labs instead of taking a break.&lt;br /&gt;&lt;br /&gt;If you are working with hard-to-test legacy C++ code, and want to get it under test so  you can safely refactor it, this tutorial will present several hard-to-test examples of C++ code and show  how it can be refactored into testable code. The legacy code problems that may experience have several possible refactorings to get them under test, and we will cover the pros and cons of the most common refactorings and problems.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-3337573273085859777?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/3337573273085859777/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/09/refactoring-for-testable-c-at-oopsla.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/3337573273085859777'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/3337573273085859777'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/09/refactoring-for-testable-c-at-oopsla.html' title='Refactoring for Testable C++ at OOPSLA'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-3485991111430444712</id><published>2008-09-05T11:40:00.000-07:00</published><updated>2008-09-05T11:42:43.230-07:00</updated><title type='text'>Looking at Good Object Oriented Design</title><content type='html'>Looking at good Object Oriented design is like watching an effective manager (or CEO) who knows how to delegate the proper responsibilities to his or her team(s).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-3485991111430444712?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/3485991111430444712/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/09/looking-at-good-object-oriented-design.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/3485991111430444712'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/3485991111430444712'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/09/looking-at-good-object-oriented-design.html' title='Looking at Good Object Oriented Design'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-316977247785673062</id><published>2008-09-03T10:40:00.000-07:00</published><updated>2008-09-03T10:50:15.387-07:00</updated><title type='text'>jBehave's Golden Rules</title><content type='html'>I like these "Golden Rules" for contributers to &lt;a href="http://jbehave.org/"&gt;jBehave:&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;p&gt;Here are some rules that we follow when developing JBehave:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Example Driven:&lt;/strong&gt; Only create code to solve a realistic (and preferably real) problem.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Behaviour Driven:&lt;/strong&gt; Only create classes once you can describe and automate examples of their behaviour.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;No Misbehaving:&lt;/strong&gt; Automated examples must work before being checked into the repository, and existing tests must not be broken.&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;They have a new &lt;a href="http://jbehave.org/2008/09/03/jbehave-20-released/"&gt;release,&lt;/a&gt; by the way. With "plain text" scenarios. Check it out.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-316977247785673062?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/316977247785673062/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/09/jbehaves-golden-rules.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/316977247785673062'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/316977247785673062'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/09/jbehaves-golden-rules.html' title='jBehave&apos;s Golden Rules'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-154222983819901982</id><published>2008-08-21T07:21:00.000-07:00</published><updated>2008-08-21T07:38:51.420-07:00</updated><title type='text'>SF Reading material for you and your iPhone</title><content type='html'>&lt;a href="http://starrigger.blogspot.com/"&gt;Jeffrey Carver&lt;/a&gt; has made the book &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Neptune Crossing&lt;/span&gt;, available for &lt;a href="http://www.starrigger.net/Downloads.htm"&gt;download&lt;/a&gt;. The HTML version appears to be quite readable on my iPhone when rotated for a horizontal aspect ratio.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.amazon.com/exec/obidos/search-handle-url?%5Fencoding=UTF8&amp;amp;search-type=ss&amp;amp;index=books&amp;amp;field-author=Cory%20Doctorow"&gt;Cory Doctorow&lt;/a&gt; has made several of his books available for download, the best being &lt;a href="http://craphound.com/littlebrother/download/"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Little Brother&lt;/span&gt;&lt;/a&gt;. He is finding that free online releases of his books are enhancing the sales of his paper editions, rather than reducing sales.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Other authors are finding the same thing. Old out-of-print books made available for download can revive an author's readership, while new books simultaneously released on the web and in paper can generate more buzz than just the paper edition will.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A little bit more about &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Little Brother:&lt;/span&gt;  one of the &lt;a href="http://craphound.com/littlebrother/category/reviews/"&gt;blurbs&lt;/a&gt; sums it up well: &lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;Little Brother is a scarily realistic adventure about how homeland security technology could be abused to wrongfully imprison innocent Americans. A teenage hacker-turned-hero pits himself against the government to fight for his basic freedoms. This book is action-packed with tales of courage, technology, and demonstrations of digital disobedience as the technophile's civil protest.&lt;br /&gt;–&lt;span class="Apple-style-span" style="font-style: italic;"&gt; Andrew "bunnie" Huang, author of &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Hacking the Xbox&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;Check it out.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-154222983819901982?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/154222983819901982/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/08/sf-reading-material-for-you-and-your.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/154222983819901982'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/154222983819901982'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/08/sf-reading-material-for-you-and-your.html' title='SF Reading material for you and your iPhone'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-6505515834344050655</id><published>2008-08-19T10:02:00.000-07:00</published><updated>2008-08-21T07:20:44.215-07:00</updated><title type='text'>Can someone do a meta-study on agile adoption</title><content type='html'>Get conference proceedings from Agile2008 and earlier. Check out all the experience reports and other papers about agile adoption. What do the success reports have in common? What do the failure reports have in common? What is a typical timeline for success for transforming a project team, a division, a company?&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-6505515834344050655?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/6505515834344050655/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/08/can-someone-do-meta-study-on-agile.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/6505515834344050655'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/6505515834344050655'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/08/can-someone-do-meta-study-on-agile.html' title='Can someone do a meta-study on agile adoption'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-7952076180722451400</id><published>2008-08-15T11:23:00.000-07:00</published><updated>2008-08-15T11:29:47.111-07:00</updated><title type='text'>Clean Code</title><content type='html'>Clean Code (also known as "Simple Code" as defined by Kent Beck) is (paraphrased):&lt;br /&gt;&lt;ul&gt;&lt;li&gt; &lt;span style="font-weight: bold;"&gt;Correct&lt;/span&gt;:  it passes all its tests and its tests are thorough (but not redundant) and correct. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt; Does not contain duplication&lt;/span&gt;: Duplicate logic is eliminated and localized in a few places – this may require using functional or object oriented concepts and design patterns. Duplicate data is minimized. Duplicate syntax is also minimized. No redundency. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt; Expresses its concepts&lt;/span&gt;: by using good class names, methods names, and other identifiers. Dependencies are expressed in interfaces. Methods and classes are short, readable, and have a single responsibility. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt; Contains no superfluous parts:&lt;/span&gt; it does not have dead code, unnecessary parameters, etc. No code left over from features that have been removed. No code for features that haven't been scheduled for implementation. &lt;/li&gt;&lt;/ul&gt;I find that more explanation is often needed, since some programmers will, for example, point at "expresses its concepts" by saying: this huge function in this huge class perfectly expresses the two dozen actions it performs.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-7952076180722451400?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/7952076180722451400/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/08/clean-code.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/7952076180722451400'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/7952076180722451400'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/08/clean-code.html' title='Clean Code'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-3258717836337157005</id><published>2008-08-09T19:58:00.000-07:00</published><updated>2008-08-09T21:21:20.404-07:00</updated><title type='text'>How I Learned...</title><content type='html'>&lt;blockquote&gt;&lt;/blockquote&gt;&lt;a href="http://www.richarddurnall.com/?p=45"&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;/blockquote&gt;richard durnall&lt;/a&gt; points to an article "&lt;a href="http://www.wku.edu/~hrtm/CFS-452/Readings/stayer.htm"&gt;How I Learned to Let My Workers Lead&lt;/a&gt;" by Ralph Stayer. Richard notes &lt;blockquote&gt; There is a deeper, less tangible philosophy embeded within Lean that focuses on people, the systems we place them in and the behaviours these systems encourage. [...]&lt;/blockquote&gt;&lt;blockquote&gt;The Stayer article explains the leap of faith we have to take as leaders to create new systems where the people can determine the process.&lt;/blockquote&gt;&lt;blockquote&gt;In Lean Ops we missed this deeper philosophy. We focussed on the tools and when they didn’t work we just tried harder to enforce the application of the tools. The irony! [...]"&lt;/blockquote&gt;&lt;div&gt;&lt;div&gt;This correlates with several lessons that I am still learning to embody within myself and organizations I interact with. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;An observation: The most well-known success story of "Lean", Toyota, shows that the corporate culture is more important than the practices. Attempts to imitate the practices without the culture of &lt;span class="Apple-style-span" style="font-weight: bold; "&gt;&lt;span class="Apple-style-span" style="font-style: italic; "&gt;true&lt;/span&gt;&lt;/span&gt; empowerment have failed. And from what I've heard, many of their specific practices change over the course of time.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A few choice quotes from Ralph Stayer's article: &lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;If I was going to fix what I had made, I would have to start by fixing myself.&lt;/blockquote&gt;Of course, fixing himself and his company (which, since he was the founder, was a reflection of himself) was a long and circuitous course... The "end state" he envisioned for his company was:&lt;blockquote&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;[...] a flock of geese on the wing. I didn't want an organizational chart with traditional lines and boxes, but a "V" of individuals who knew the common goal, took turns leading, and adjusted their structure to the task at hand. [...] Most important, each individual bird is responsible for its own performance.&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;Note the difference from his "end state" and how he attempted to get there:&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;I spent those two years pursuing another mirage as well -- detailed strategic and tactical plans [...] We tried-to plan organizational structure two to three years before it would be needed -- who would be responsible for what and who would report to whom, all care fully diagramed in boxes and lines on charts. Later I realized that these &lt;span class="Apple-style-span" style=""&gt;&lt;span class="Apple-style-span" style=""&gt;structural changes had to grow from day-to-day working realities; no one could dictate them from above, and certainly not in advance&lt;/span&gt;&lt;/span&gt;.&lt;/blockquote&gt;Now &lt;span class="Apple-style-span" style="font-style: italic;"&gt;that&lt;/span&gt; is one of the lessons I learned when I attended Jerry Weinberg's &lt;a href="http://www.estherderby.com/workshops/ProblemSolvingLeadership.htm"&gt;PSL&lt;/a&gt; and participated in the experiential simulations he designed. Everyone who attends tends to learn different lessons -- often, the lessons they most need to learn. Jerry creates an environment that enables us to observe problems, without him having to didactically explain what's going on. He was teaching this before "Agile" or "Lean" became buzzwords in the software development community.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Trying to assign decision-making (or not) responsibilities and define a team structure before beginning a project is a something like buying equipment and organizing a team for to play &lt;a href="http://olympicsblog.dallasnews.com/archives/2008/08/kevin-sherrington-us-softball.html"&gt;softball&lt;/a&gt;, without knowing that the sport you're actually going to be playing is &lt;a href="http://news.xinhuanet.com/english/2008-08/10/content_9111845.htm"&gt;basketball&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;[...] The early 1980s taught me that I couldn't give responsibility. People had to expect it, want it, even demand it. So my end state needed redefining. The goal was not so much a state of shared responsibility as an environment where people insist on being responsible.&lt;br /&gt;&lt;br /&gt;To bring people to that new Point B, I had to learn to be a better coach. It took me additional years to learn the art of coaching, by which, in a nutshell, I mean communicating a vision and then getting people to see their own behavior, harness their own frustrations, and own their own problems.&lt;/blockquote&gt;Coaching is an art I'm still working on. As an Agile coach, I can model the behavior I'd like to see in others, observe, communicate, offer feedback, ask for feedback, and sometimes give advice. It turns out that managers (even CEOs) have little more power than a coach does:&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;The debacle of ordering change and watching it fail to occur showed me my limitations. I had come to realize that I didn't directly control the performance of the people at Johnsonville, that as a manager I didn't really manage people. They managed themselves.[...]&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;Stayer describes how top management had the responsibility of checking the quality of the product (tasting the sausage) and he made the change that the workers who are responsible for creating the product would become responsible for checking quality, with the expectation that quality would remain high. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The employees self-organized taking ownership for quality and defects, and to remedy the defects. This led to better quality and employees asked for more information and more responsibility including changing training, HR, and salary structures: paying for people taking on more responsibilities rather than simply job tenure. &lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&lt;/blockquote&gt;Check it out.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-3258717836337157005?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/3258717836337157005/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/08/how-i-learned.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/3258717836337157005'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/3258717836337157005'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/08/how-i-learned.html' title='How I Learned...'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-6633895583230950417</id><published>2008-08-08T04:59:00.000-07:00</published><updated>2008-08-08T05:00:47.126-07:00</updated><title type='text'>Last day at Agile2008</title><content type='html'>I will be on the "Legacy Wrapup" panel with Michael Feathers today.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-6633895583230950417?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/6633895583230950417/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/08/last-day-at-agile2008.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/6633895583230950417'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/6633895583230950417'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/08/last-day-at-agile2008.html' title='Last day at Agile2008'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-7704543237992262356</id><published>2008-08-01T09:21:00.000-07:00</published><updated>2008-08-01T10:36:38.807-07:00</updated><title type='text'>Industrial Logic at Agile 2008</title><content type='html'>My Industrial Logic colleagues will be out in force at the Agile 2008 conference.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In order of appearance...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Tuesday&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Brian Foote: "Agility, Evolution, Emergence, And The Primordial Ooze"&lt;/li&gt;&lt;li&gt;Mike Hill: "Throwing the Agile Transition Party"&lt;/li&gt;&lt;li&gt;Brian Foote: "Big Ball of Mud"&lt;/li&gt;&lt;li&gt;Joshua Kerievsky : "Ten Terrific Transition Tips"&lt;/li&gt;&lt;li&gt;John Tangney: "Mastering Selenium"&lt;/li&gt;&lt;/ul&gt;Wednesday&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Mike Hill: "Clean Code Clinic: Dealing with CRRAP - Microtesting Legacy Code"&lt;/li&gt;&lt;li&gt;Joshua Kerievsky, Gil Broza: "Crafting User Stories – Four Experts And The Audience Weigh In"&lt;/li&gt;&lt;li&gt;Joshua Kerievsky: "Refactoring Strategies &amp;amp; Tactics"&lt;/li&gt;&lt;li&gt;Gil Broza: "Agile Clinic - Bring Your Toughest Challenges"&lt;/li&gt;&lt;/ul&gt;Thursday&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Gil Broza: "The Secrets of High-Performance Agile Implementations"&lt;/li&gt;&lt;li&gt;Keith Ray, Gil Broza: "Refactoring for Testable C++"&lt;/li&gt;&lt;li&gt;Brian Foote: "Patterns Poster Children"&lt;/li&gt;&lt;li&gt;Joshua Kerievsky: "Estimating Considered Wasteful: Introducing Micro-Releases"&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Tuesday - Friday&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Joshua Kerievsky, Mike Hill: "Programming with the Stars"&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-7704543237992262356?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/7704543237992262356/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/08/industrial-logic-at-agile-2008.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/7704543237992262356'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/7704543237992262356'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/08/industrial-logic-at-agile-2008.html' title='Industrial Logic at Agile 2008'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-4454049337400524938</id><published>2008-07-29T13:43:00.000-07:00</published><updated>2008-07-29T13:45:32.527-07:00</updated><title type='text'>next week - Agile 2008</title><content type='html'>Next week I'll be at the &lt;a href="http://www.agile2008.org/"&gt;Agile 2008 Conference&lt;/a&gt;, where I'll be co-presenting a workshop with Gil Broza on refactoring legacy c++ code for testability. I might even blog from the conference. Hope to see you there.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-4454049337400524938?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/4454049337400524938/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/07/next-week-agile-2008.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/4454049337400524938'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/4454049337400524938'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/07/next-week-agile-2008.html' title='next week - Agile 2008'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-8778736393447707746</id><published>2008-07-29T10:50:00.000-07:00</published><updated>2008-07-29T10:59:00.355-07:00</updated><title type='text'>Three rules of TDD?</title><content type='html'>A recent object mentor &lt;a href="http://blog.objectmentor.com/articles/2008/07/21/tdd-is-how-i-do-it-not-what-i-do"&gt;blog entry&lt;/a&gt; said:&lt;br /&gt;  &lt;blockquote&gt;&lt;span style="font-style: italic;"&gt;We had an interesting result during that class. One group was practicing Bob’s three rules of TDD (paraphrased);   &lt;/span&gt;&lt;ul style="font-style: italic;"&gt;&lt;li&gt;Write no production code without failing tests&lt;/li&gt;&lt;li&gt;Write only enough test code so that it fails (not compiling is failing)&lt;/li&gt;&lt;li&gt;Write only enough production code to get your tests to pass.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-style: italic;"&gt; But they ended up with a bit of a mess. Following the three rules wasn’t enough. These rules are guiding principles, but those three rules mean nothing if you forget about clean code, refactoring and basic design principles&lt;/span&gt; [...]&lt;/blockquote&gt;Maybe the cause of the mess were the rules they used. I remember the rules more like this:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Write enough &lt;span style="font-weight: bold;"&gt;test&lt;/span&gt; code so that to get a single test failure.&lt;/li&gt;&lt;li&gt;Write enough production &lt;span style="font-weight: bold;"&gt;code&lt;/span&gt; to get all your tests to pass.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Refactor&lt;/span&gt; until the code is Simple/Clean. (See elsewhere for the Rules of Simplicity/Clean)&lt;/li&gt;&lt;/ol&gt;As Brett Schuchert points out in that blog post, leaving out the refactoring step puts you onto the road to certain doom.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;cite&gt;&lt;/cite&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-8778736393447707746?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/8778736393447707746/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/07/three-rules-of-tdd.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/8778736393447707746'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/8778736393447707746'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/07/three-rules-of-tdd.html' title='Three rules of TDD?'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6278117270415743822.post-3079461520613820493</id><published>2008-07-28T15:07:00.000-07:00</published><updated>2008-07-28T15:10:21.581-07:00</updated><title type='text'>Hello again!</title><content type='html'>I'm moving my blog &lt;a href="http://homepage.mac.com/keithray/blog/"&gt;Exploring Solution Spaces&lt;/a&gt; away from being hosted on .mac into blogger.&lt;br /&gt;&lt;br /&gt;More later!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6278117270415743822-3079461520613820493?l=agilesolutionspace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://agilesolutionspace.blogspot.com/feeds/3079461520613820493/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/07/hello-again.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/3079461520613820493'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6278117270415743822/posts/default/3079461520613820493'/><link rel='alternate' type='text/html' href='http://agilesolutionspace.blogspot.com/2008/07/hello-again.html' title='Hello again!'/><author><name>C. Keith Ray</name><uri>http://www.blogger.com/profile/06981113185117230625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>
