<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
  <title>The Code Whisperer</title>
  <id>blog.thecodewhisperer.com</id>
  <updated>2001-06-01</updated>
  <author>
    <name>J. B. Rainsberger</name>
  </author>
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/thecodewhisperer/tGHC" /><feedburner:info uri="thecodewhisperer/tghc" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
    <title>Rescuing Legacy Code by Extracting Pure Functions</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/thecodewhisperer/tGHC/~3/NHFH13lA7gc/" />
    <id>http://blog.thecodewhisperer.com/2011/11/27/rescuing-legacy-code-by-extracting-pure-functions/</id>
    <published>2011-11-27</published>
    <updated>2011-11-27</updated>
    <author>
      <name>J. B. Rainsberger</name>
    </author>
    <content type="html">&lt;p&gt;After running a handful of &lt;a href="http://www.legacycoderetreat.org"&gt;Legacy Code Retreats&lt;/a&gt; I&amp;rsquo;ve had the chance to try a number of exercises related to rescuing legacy code. I&amp;rsquo;d like to share one that has met with very positive reactions from people: extracting &lt;em&gt;pure functions&lt;/em&gt;. I use the term &lt;em&gt;pure function&lt;/em&gt; to describe a function that only operates on local variables and parameters, but does not touch any state outside the function. No object fields, no global data. I have very little experience in functional programming, so I hope I use the term in a standard way.&lt;/p&gt;

&lt;p&gt;No doubt you already know about the &lt;a href="http://c2.com/ppr/wiki/WikiPagesAboutRefactoring/ComposedMethod.html"&gt;Composed Method&lt;/a&gt; design pattern, which we commonly use to help understand code as we read it. Most commonly you encounter a block of code with a comment that describes what that code does. You then extract that block of code into a method whose name matches the comment. I&amp;rsquo;ve used this technique for well on a decade to raise the level of abstraction in code, help code document itself, and eliminate misleading comments. While introducing these methods helps me read the code, it sometimes hides the tangle of dependencies that makes separating responsibilities so difficult. For this reason, I recommend trying to extract pure functions instead.&lt;/p&gt;

&lt;p&gt;To introduce a pure function, start with a block of code and extract a method for it. Now look at all the fields and global variables that the method reads and introduce each one as a parameter to the method. Now look at all the fields and global variables that the method writes to and turn these into return values. Where the old code invokes the new function, assign each new return value to the corresponding field or global variable. You know you&amp;rsquo;ve done this correctly if, of course, the overall behhavior of the program hasn&amp;rsquo;t changed and you can mark the new function as &lt;code&gt;static&lt;/code&gt; or whatever your language calls a class-level function.&lt;/p&gt;

&lt;p&gt;In some languages, like Java, you&amp;rsquo;ll have to introduce a new little class to allow you to return multiple values from the new function. If you don&amp;rsquo;t want to do that right away, then return a &lt;code&gt;Map&lt;/code&gt; of return values. Once you see that you need to return similar &lt;code&gt;Map&lt;/code&gt;s from different functions, consider replacing those &lt;code&gt;Map&lt;/code&gt;s with a new class. Perhaps that new class will attract some code!&lt;/p&gt;

&lt;p&gt;When I&amp;rsquo;ve used this technique, two key things have happened: either I&amp;rsquo;ve noticed duplication in the parameter lists of the new functions or introducing a parameter has changed the behavior of the system. In the first case, I introduce Parameter Objects for the duplicated parameters, which then probably attract code and become useful domain objects. In the second case, I&amp;rsquo;ve detected temporal coupling, which requires me to separate the function into two smaller ones so that some output from the first becomes input to the second. This helps me uncover cohesion problems, usually of the type of different things written too close together.&lt;/p&gt;

&lt;p&gt;I realise that an example would help right about now, but I would rather create some screencasts than write out examples in code, but I don&amp;rsquo;t know when exactly I intend to do that. I wanted to share this idea with you without waiting for the energy to put together a suitable screencast.&lt;/p&gt;

&lt;p&gt;I invite you to try introducing pure functions into some legacy code and practising the technique as a kata. Get used to the various maneuvers, like introducing Parameter Objects or Return Value Objects or solving temporal coupling by splitting the function in two. It sounds crazy, but I&amp;rsquo;d like to try a Legacy Code Retreat where we practise only this technique all day. I don&amp;rsquo;t know whether anyone else would find it valuable enough to try it together for an entire day, over and over and over.&lt;/p&gt;

&lt;p&gt;Would you? Add your comments below.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/thecodewhisperer/tGHC/~4/NHFH13lA7gc" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.thecodewhisperer.com/2011/11/27/rescuing-legacy-code-by-extracting-pure-functions/</feedburner:origLink></entry>
  <entry>
    <title>Detecting Changes in Third-Party Code</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/thecodewhisperer/tGHC/~3/plqi5cubVVA/" />
    <id>http://blog.thecodewhisperer.com/2011/11/26/detecting-changes-in-third-party-code/</id>
    <published>2011-11-26</published>
    <updated>2011-11-26</updated>
    <author>
      <name>J. B. Rainsberger</name>
    </author>
    <content type="html">&lt;p&gt;One of the people who watched &lt;a href="http://www.infoq.com/presentations/integration-tests-scam"&gt;the 2009 version of Integrated Tests Are A Scam&lt;/a&gt; recently asked me: &lt;em&gt;I wonder how you deal with updates of third-party libraries. How do you detect subtle API or behaviour changes? At the moment, I write state-based integration tests for these cases and I wonder whether this isn&amp;rsquo;t a sensible use of integration tests.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I write Learning Tests to discover how a third-party library works. I isolate myself from the third-party library through a layer of interfaces and adapter classes that evolve from the common ways I use the third-party library. I call this the &amp;ldquo;Pattern of Usage API&amp;rdquo;, as it represents the way my application uses that third-party library. Now my application uses the third-party library through a layer of interfaces, which means that I can introduce Contract Tests on those interfaces. These Contract Tests effectively describe the subset of the third-party library&amp;rsquo;s behavior on which I depend.&lt;/p&gt;

&lt;p&gt;Now when I upgrade the third-party library, I run the Contract Tests against my adapters to that library. Test failures usually indicate a backwards incompatible change in the third-party library. (Sometimes they indicate a trivial difference in the API which requires a trivial fix, such as an API call having been renamed or something.)&lt;/p&gt;

&lt;p&gt;Of course, this only helps me detect behavior changes related to computing answers, and not related to responsiveness, reliability, scalability, and so on. For that, I&amp;rsquo;ll always need system tests.&lt;/p&gt;

&lt;p&gt;The Contract Tests are almost always state-based integration tests. I simply limit these to the implementation of Pattern of Usage API and don&amp;rsquo;t let it leak farther up the call stack. At some point you have to integrated with the Outside World. I simply teach people to look to make that integration thinner.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/thecodewhisperer/tGHC/~4/plqi5cubVVA" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.thecodewhisperer.com/2011/11/26/detecting-changes-in-third-party-code/</feedburner:origLink></entry>
  <entry>
    <title>When should I remove duplication?</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/thecodewhisperer/tGHC/~3/FErcUhTKXV0/" />
    <id>http://blog.thecodewhisperer.com/2011/09/29/when-should-i-remove-duplication/</id>
    <published>2011-09-29</published>
    <updated>2011-09-29</updated>
    <author>
      <name>J. B. Rainsberger</name>
    </author>
    <content type="html">&lt;p&gt;As I learn to become a better programmer, I continue to follow &lt;a href="http://link.jbrains.ca/g9P6Jw"&gt;the four elements of simple design&lt;/a&gt;. Of these, I have observed that &amp;ldquo;remove duplication&amp;rdquo; helps me discover an appropriate structure for the thing I want to build. In my classes, we practise removing duplication a lot, in part because most people understand the rule &amp;ldquo;remove duplication&amp;rdquo; well enough to find it useful. After the first few weeks of practice, however, programmers following this rule observe varying results: sometimes removing the duplication makes the design much clearer, and sometimes it muddies the water. At this stage, she usually looks for more detailed rules to help decide when to remove duplication and when to leave it alone. I offer some simple rules and guidelines for this situation.&lt;/p&gt;

&lt;p&gt;When I can&amp;rsquo;t decide whether to remove a certain bit of duplication I&amp;rsquo;ve found, I fall back on two rules:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Remove duplication only after you see &lt;a href="http://link.jbrains.ca/qUxm1s"&gt;&lt;em&gt;three&lt;/em&gt; copies&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;If you don&amp;rsquo;t know how to remove this particular kind of duplication, then write more tests. Either you need more examples to see the pattern, or more examples will show a different, better pattern.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;I also remember two guidelines:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Don&amp;rsquo;t be afraid to remove duplication by introducing a method or class or interface with a stupid name. Remember that &lt;a href="http://link.jbrains.ca/nP9Fvk"&gt;you can always improve the name later&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;If you sense duplication, but don&amp;rsquo;t really see it, or can&amp;rsquo;t explain it to others, then &lt;a href="http://link.jbrains.ca/nP9Fvk"&gt;make the surrounding names more precise&lt;/a&gt;; then maybe you will see the duplication.&lt;/li&gt;
&lt;/ol&gt;

&lt;img src="http://feeds.feedburner.com/~r/thecodewhisperer/tGHC/~4/FErcUhTKXV0" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.thecodewhisperer.com/2011/09/29/when-should-i-remove-duplication/</feedburner:origLink></entry>
  <entry>
    <title>Writing Contract Tests in Java differently</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/thecodewhisperer/tGHC/~3/vLPZ2a3TbMw/" />
    <id>http://blog.thecodewhisperer.com/2011/07/17/writing-contract-tests-in-java-differently/</id>
    <published>2011-07-17</published>
    <updated>2011-07-17</updated>
    <author>
      <name>J. B. Rainsberger</name>
    </author>
    <content type="html">&lt;p&gt;I just wanted to know whether anyone has tried nesting the concrete tests inside the abstract test like this, and if you have, then how do/did you like it?&lt;/p&gt;

&lt;script src="https://gist.github.com/1084541.js"&gt; &lt;/script&gt;


&lt;p&gt;&lt;noscript&gt;&lt;a href="https://gist.github.com/1084541"&gt;See code snippet&lt;/noscript&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/thecodewhisperer/tGHC/~4/vLPZ2a3TbMw" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.thecodewhisperer.com/2011/07/17/writing-contract-tests-in-java-differently/</feedburner:origLink></entry>
  <entry>
    <title>Contract Tests: An Example</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/thecodewhisperer/tGHC/~3/HYtqVbLpvzY/" />
    <id>http://blog.thecodewhisperer.com/2011/07/07/contract-tests-an-example/</id>
    <published>2011-07-07</published>
    <updated>2011-07-07</updated>
    <author>
      <name>J. B. Rainsberger</name>
    </author>
    <content type="html">&lt;p&gt;I found an example of contract tests in Arlo Belshee&amp;rsquo;s &lt;a href="http://arlobelshee.com/tag/no-mocks"&gt;series of articles about mock-free testing&lt;/a&gt;. I must strongly, strongly point out that Arlo uses the term &amp;ldquo;mock&amp;rdquo; narrowly to refer to runtime- or bytecode-generated proxies that intercept interface method invocations and provide the ability to set method expectations, in the way that JMock and NMock do. He &lt;em&gt;does not&lt;/em&gt; mean the generic term &amp;ldquo;mock&amp;rdquo;, where he uses the term &amp;ldquo;test double&amp;rdquo; instead. I thank him for that.&lt;/p&gt;

&lt;p&gt;If you click &lt;a href="https://github.com/arlobelshee/ArsEditorExample/blob/master/SimulatableApi.Tests/FileSystemCanLocateFilesAndDirs.cs"&gt;here&lt;/a&gt; you&amp;rsquo;ll see an almost textbook example of a contract test: that is, a test class that can run the same set of tests for two different implementations of the same interface. I would change only one thing: I&amp;rsquo;d extract the tests into an abstract superclass&amp;mdash;something I otherwise hate to do&amp;mdash;and pull the declaration of the method &lt;code&gt;MakeTestSubject()&lt;/code&gt; up there, leaving two subclasses, one for the real file system and one for the simulated one. &amp;ldquo;YAGNI,&amp;rdquo; you say, and I agree, but I prefer the symmetry of the abstract superclass design to the asymmetry of having one class inherit from the other. I find it easier to grok quickly.&lt;/p&gt;

&lt;p&gt;Either way, I feel good seeing contract tests out in the wild. I&amp;rsquo;m not so crazy after all.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/thecodewhisperer/tGHC/~4/HYtqVbLpvzY" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.thecodewhisperer.com/2011/07/07/contract-tests-an-example/</feedburner:origLink></entry>
  <entry>
    <title>Adding behavior with confidence</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/thecodewhisperer/tGHC/~3/Mx2TqKJ1Ahg/" />
    <id>http://blog.thecodewhisperer.com/2011/06/22/adding-behavior-with-confidence/</id>
    <published>2011-06-22</published>
    <updated>2011-06-22</updated>
    <author>
      <name>J. B. Rainsberger</name>
    </author>
    <content type="html">&lt;h2&gt;The 30-second version&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Adding behavior confidently involves having fewer parts to change (low duplication), knowing which ones to change (high cohesion), ease of changing just the part you want to change (low coupling), and understanding how you&amp;rsquo;ve changed it (strong tests).&lt;/li&gt;
&lt;li&gt;Adding behavior requires breaking an existing assumption.&lt;/li&gt;
&lt;li&gt;In a well-factored design, we can easily find the one place we have made that assumption. (Otherwise, why bother refactoring?)&lt;/li&gt;
&lt;li&gt;First, make room for the new code, then add it.&lt;/li&gt;
&lt;li&gt;To make room for the new code, extract the existing code into a method whose name describes the generalisation we want to make, or the idea we want to introduce.&lt;/li&gt;
&lt;li&gt;By making room for the new code, we make that code easier to reuse by reducing its dependence on its surrounding context.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Want to learn more?&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Visit the links in this article.&lt;/li&gt;
&lt;li&gt;Attend &lt;a href="http://www.jbrains.ca/training/agile-design-beyond-the-basics"&gt;Agile Design: Beyond the Basics&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.jbrains.ca/schedule-a-working-session"&gt;Pair with me&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;The Details&lt;/h2&gt;

&lt;p&gt;We all want to add behavior to a system confidently, and I have observed that my confidence in adding behavior depends on two factors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I know where to add code.&lt;/li&gt;
&lt;li&gt;I understand the behavior of the code I am adding.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;I use test-driven development as the main technique for handling the second of these two factors, but what about the first? I have uncovered a technique that I both use and teach, and I&amp;rsquo;d like to share that with you. I call this &amp;ldquo;making room for the new code&amp;rdquo;, naming it for a phrase I vaguely remember reading in one of the Grand Old XP books. (Did Kent Beck or Ron Jeffries write it? I can&amp;rsquo;t remember.) This technique helps me quickly find a reasonable first-draft place in the code base to put new code. After I have put the new code in place, and I feel confident that it does what I expect, I then use the &lt;a href="http://link.jbrains.ca/g9P6Jw"&gt;Four Elements of Simple Design&lt;/a&gt; to guide me in refactoring to improve the design.&lt;/p&gt;

&lt;h2&gt;A premise&lt;/h2&gt;

&lt;p&gt;I start with the premise that &lt;strong&gt;adding behavior means breaking an assumption&lt;/strong&gt;. By this I mean that whenever we add code to a system in order to extend its behavior, we have to falsify at least one assumption we&amp;rsquo;ve previously made. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In a payroll system, in order to support a second cheque printer, we likely have to break the assumption that there is only one cheque format.&lt;/li&gt;
&lt;li&gt;In a point of sale system, in order to support separate cash and card payment reports, we likely have to break the assumption that all &amp;ldquo;we made a sale&amp;rdquo; events look the same.&lt;/li&gt;
&lt;li&gt;In a mobile phone monitoring system, in order to support billing by the second, we likely have to break the assumption that we only have to count the number of minutes a call lasted.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Some of these seem obvious, and others less so, and it bears emphasising that the specific assumption or assumptions we break depends heavily on what we&amp;rsquo;ve built so far and the way we articulate the soon-to-be-added behavior. Even so, I conjecture that &lt;span class="highlight"&gt;&lt;em&gt;for every behavior we want to add to a system, we can identify a non-empty list of assumptions that we &lt;strong&gt;need&lt;/strong&gt; to break&lt;/em&gt;&lt;/span&gt;.&lt;/p&gt;

&lt;h2&gt;The technique&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Identify an assumption that the new behavior needs to break.&lt;/li&gt;
&lt;li&gt;Find the code that implements that assumption.&lt;/li&gt;
&lt;li&gt;Extract that code into a method whose name represents the generalisation you&amp;rsquo;re about to make.&lt;/li&gt;
&lt;li&gt;Enhance the extracted method to include the generalisation.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;The less duplication you have in the system, the better this works, because duplicate code makes it difficult to find all the code that implements the assumption in question. Similarly, the more appropriate the names in your system, the better this works, because unsuitable names make it difficult to know which code implements the assumption in question, as opposed to something unrelated. You&amp;rsquo;ll notice that these points relate both to the &lt;a href="http://link.jbrains.ca/g9P6Jw"&gt;Four Elements of Simple Design&lt;/a&gt; and to the core concepts of &lt;a href="http://link.jbrains.ca/jSNrEJ"&gt;Coupling and Cohesion&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Yes, yes&amp;hellip;&lt;/p&gt;

&lt;div style="text-align: center"&gt;&lt;img style="width: 200px" src="http://images.jbrains.ca/handy-right-about-now.png"&gt;&lt;/img&gt;&lt;/div&gt;


&lt;h2&gt;An example&lt;/h2&gt;

&lt;p&gt;We are building a point of sale system, and we&amp;rsquo;ve just decided to implement sales tax. I live in PEI, Canada, where not only do we exclude sales tax from the price, we have two sales taxes, and we charge the second one &lt;em&gt;on top of&lt;/em&gt; the first one. For example:&lt;/p&gt;

&lt;p class="example"&gt;A $125 item that attracts both GST (the "Goods and Services" tax) and PST (provincial sales tax) costs a total of $144.38. GST at 5% costs $6.25, then PST at 10% of $131.25 (= $125 + $6.25) costs $13.13. The total is $125 + $6.25 + $13.13 = $144.38.&lt;/p&gt;


&lt;p&gt;Notice that this example implies that GST or PST might or might not apply to a given product, so even before we identify the old assumption to break, we need to note the new assumption we&amp;rsquo;ll make: &lt;em&gt;we assume that all products attract both GST and PST&lt;/em&gt;. Our customers won&amp;rsquo;t like it, but the tax authorities will love it, and only they have the power to treat us guilty until proven innocent.&lt;/p&gt;

&lt;p&gt;Our code has a class like this in it.&lt;/p&gt;

&lt;script src="https://gist.github.com/1040052.js?file=UserGestureListener.rb"&gt; &lt;/script&gt;


&lt;p&gt;What do we assume now that we can&amp;rsquo;t allow ourselves to assume any longer? &lt;strong&gt;The sale total should increment by the (net) price of the item we sell.&lt;/strong&gt; By &lt;em&gt;net price&lt;/em&gt; here, I refer to the pre-tax price, because of course, until now, our system has no notion of &amp;ldquo;tax&amp;rdquo;. Fortunately, because we&amp;rsquo;ve ruthlessly removed duplication so far, computing the running total of the sale requires only this line of code. We can pretty safely apply the technique of this article right here. To do this, we extract the assumption into a new method whose name represents the generalisation we&amp;rsquo;re about to make. In this case, we don&amp;rsquo;t want to increase the sale total by the product&amp;rsquo;s &lt;em&gt;price&lt;/em&gt;, but rather by its &lt;em&gt;cost&lt;/em&gt;, which includes any additional charges beyond net price. So, we introduce a method for accumulating the scanned product&amp;rsquo;s cost.&lt;/p&gt;

&lt;script src="https://gist.github.com/1040052.js?file=UserGestureListener-AddedMethodDescribingGeneralisation.rb"&gt; &lt;/script&gt;


&lt;p&gt;This creates space for the new code. We test-drive the new code, and end up with this delightful monstrosity.&lt;/p&gt;

&lt;script src="https://gist.github.com/1040052.js?file=UserGestureListener-Generalised.rb"&gt; &lt;/script&gt;


&lt;p&gt;It looks ugly, but it works. In addition to looking ugly, this method has &lt;a href="http://link.jbrains.ca/kqLJMj"&gt;Feature Envy&lt;/a&gt;. Specifically, the calculation part of &lt;code&gt;#accumulate_cost&lt;/code&gt; only talks to &lt;code&gt;product&lt;/code&gt;, and so it can move onto the class &lt;code&gt;Product&lt;/code&gt;, leaving only the accumulating left behind. You could also say that this method had &lt;a href="http://link.jbrains.ca/lUrZh4"&gt;two responsibilities&lt;/a&gt;, so I separated them, then notice the feature envy in one of them, then moved it. I can almost always take smaller steps.&lt;/p&gt;

&lt;script src="https://gist.github.com/1040052.js?file=UserGestureListener-Refactored.rb"&gt; &lt;/script&gt;


&lt;p&gt;Notice the &lt;a href="http://amzn.to/mB7yLf"&gt;context independence&lt;/a&gt; we&amp;rsquo;ve achieved with the method &lt;code&gt;Product#cost&lt;/code&gt;. We can now refine the notion of &amp;ldquo;cost&amp;rdquo; freely without worrying about how someone will use that information. We have an easy-to-find, easy-to-extend part of the system where we can add behavior for determining which products attract which taxes, supporting multiple tax calculation policies, and even including shipping, handling and restocking fees. Now we can really add future behavior with confidence.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/thecodewhisperer/tGHC/~4/Mx2TqKJ1Ahg" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.thecodewhisperer.com/2011/06/22/adding-behavior-with-confidence/</feedburner:origLink></entry>
  <entry>
    <title>A model for improving names</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/thecodewhisperer/tGHC/~3/plKF1Gvq3tY/" />
    <id>http://blog.thecodewhisperer.com/2011/06/15/a-model-for-improving-names/</id>
    <published>2011-06-15</published>
    <updated>2011-06-15</updated>
    <author>
      <name>J. B. Rainsberger</name>
    </author>
    <content type="html">&lt;p style="text-align: center"&gt;&lt;a href="http://assets.jbrains.ca/ImprovingNames.pdf"&gt;&lt;img style="width: 500px; margin: 0px auto" src="http://30.media.tumblr.com/tumblr_lmsovxnwmq1qa6fh7o1_500.png"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;A model for improving the names of variables, fields, interfaces, classes and namespaces in a system. Practise this and more in my course, &lt;a href="http://www.jbrains.ca/training/agile-design-beyond-the-basics"&gt;Agile Design: Beyond the Basics&lt;/a&gt;.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/thecodewhisperer/tGHC/~4/plKF1Gvq3tY" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.thecodewhisperer.com/2011/06/15/a-model-for-improving-names/</feedburner:origLink></entry>
  <entry>
    <title>Announcing a European Tour in 2011</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/thecodewhisperer/tGHC/~3/RExHpj_dCuI/" />
    <id>http://blog.thecodewhisperer.com/2011/06/08/announcing-a-european-tour-in-2011/</id>
    <published>2011-06-08</published>
    <updated>2011-06-08</updated>
    <author>
      <name>J. B. Rainsberger</name>
    </author>
    <content type="html">&lt;p&gt;&lt;a href="http://announcing.europeantour2011.com"&gt;&lt;img style="float: right; width: 215px; margin: 0px; padding-left: 10px; padding-bottom: 10px" src="http://www.jbrains.ca/wp-content/uploads/2011/06/JbrainsEuropeanTour2011-badge.png"&gt;&lt;/img&gt;&lt;/a&gt;I&amp;rsquo;m &lt;a href="http://announcing.europeantour2011.com"&gt;touring Europe in 2011&lt;/a&gt;. I have planned some public courses and some conferences, and am searching for private consulting and training work. Over the coming weeks I will reveal where I&amp;rsquo;m appearing on the map. The colors on the map provide a hint! If you&amp;rsquo;d like to invite me to your event, then please &lt;a href="https://jbrains.wufoo.com/forms/invite-j-b-to-your-event"&gt;visit here&lt;/a&gt;. See you later this year!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/thecodewhisperer/tGHC/~4/RExHpj_dCuI" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.thecodewhisperer.com/2011/06/08/announcing-a-european-tour-in-2011/</feedburner:origLink></entry>
  <entry>
    <title>The Continuum of Names: an example</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/thecodewhisperer/tGHC/~3/kbnSJM8c6A4/" />
    <id>http://blog.thecodewhisperer.com/2011/05/27/the-continuum-of-names-an-example/</id>
    <published>2011-05-27</published>
    <updated>2011-05-27</updated>
    <author>
      <name>J. B. Rainsberger</name>
    </author>
    <content type="html">&lt;p&gt;I found someone trying to work on improving names in their code, and &lt;a href="https://gist.github.com/986928"&gt;gave them a little advice&lt;/a&gt;. It gives a reasonable example of some of the things I think about when naming.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/thecodewhisperer/tGHC/~4/kbnSJM8c6A4" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.thecodewhisperer.com/2011/05/27/the-continuum-of-names-an-example/</feedburner:origLink></entry>
  <entry>
    <title>The Continuum of Names: A quick summary</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/thecodewhisperer/tGHC/~3/0w7PDpiEZXE/" />
    <id>http://blog.thecodewhisperer.com/2011/05/26/the-continuum-of-names-a-quick-summary/</id>
    <published>2011-05-26</published>
    <updated>2011-05-26</updated>
    <author>
      <name>J. B. Rainsberger</name>
    </author>
    <content type="html">&lt;p&gt;Emma López (@hell03610) shared with the world &lt;a href="http://blog.dev.openfinance.es/2011/05/xp2011-modular-design/"&gt;her notes&lt;/a&gt; from my XP2011 session, &amp;ldquo;A Simple Approach to Modular Design&amp;rdquo;. In it, she summarises a model I teach about how to improve names in code. I do plan to write about this in more detail this summer.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/thecodewhisperer/tGHC/~4/0w7PDpiEZXE" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.thecodewhisperer.com/2011/05/26/the-continuum-of-names-a-quick-summary/</feedburner:origLink></entry>
</feed>

