<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://www.lostechies.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Girl Writes Code (Sharon Cichelli)</title><link>http://www.lostechies.com/blogs/sharoncichelli/default.aspx</link><description /><dc:language>en</dc:language><generator>CommunityServer 2008.5 (Build: 30929.2835)</generator><item><title>Rhino Mocks Examples, with a fix</title><link>http://www.lostechies.com/blogs/sharoncichelli/archive/2010/03/18/rhino-mocks-examples-with-a-fix.aspx</link><pubDate>Fri, 19 Mar 2010 02:35:00 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:75445</guid><dc:creator>Sharon J. Cichelli</dc:creator><slash:comments>8</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/sharoncichelli/rsscomments.aspx?PostID=75445</wfw:commentRss><comments>http://www.lostechies.com/blogs/sharoncichelli/archive/2010/03/18/rhino-mocks-examples-with-a-fix.aspx#comments</comments><description>&lt;p&gt;Jon Kruger created an excellent &lt;a href="http://jonkruger.com/blog/2010/03/12/how-to-use-rhino-mocks-documented-through-tests/"&gt;explanation of Rhino Mocks, using unit tests&lt;/a&gt; to demonstrate and illuminate the syntax and capabilities. (Found via &lt;a href="http://twitter.com/gar3t"&gt;@gar3t&lt;/a&gt;.) It needs one small correction, which I'd like to write about here so that I can link to and support Jon's work, and because it gives the opportunity to clarify a subtle distinction between mocks and stubs and verified expectations.&lt;/p&gt;
&lt;p&gt;First, go check out &lt;a href="http://github.com/JonKruger/RhinoMocksExamples/raw/master/src/RhinoMocksExamples/RhinoMocksExamples/RhinoMocksTests.cs"&gt;Jon's code&lt;/a&gt;, then come back here.&lt;/p&gt;
&lt;p&gt;The problem lies in the following test. I can comment out the part that looks like it is satisfying the assertions, yet the test still passes&amp;mdash;a false positive.&lt;/p&gt;
&lt;div style="font-family: Courier New; font-size: 8pt; color: black; background: white; border: 1px solid #ccc; overflow: auto; width: 550px;"&gt;
&lt;pre style="margin: 0px;"&gt;[&lt;span style="color: #2b91af;"&gt;Test&lt;/span&gt;]&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Another_way_to_verify_expectations_instead_of_AssertWasCalled()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;{&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; stub = &lt;span style="color: #2b91af;"&gt;MockRepository&lt;/span&gt;.GenerateStub&amp;lt;&lt;span style="color: #2b91af;"&gt;ISampleClass&lt;/span&gt;&amp;gt;();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; &lt;span style="color: green;"&gt;// Here I'm setting up an expectation that a method will be called&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; stub.Expect(s =&amp;gt; s.MethodThatReturnsInteger(&lt;span style="color: #a31515;"&gt;"foo"&lt;/span&gt;)).Return(5);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; &lt;span style="color: green;"&gt;//Sneaky Sharon comments out the "Act" part of the test:&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; &lt;span style="color: green;"&gt;//var output = stub.MethodThatReturnsInteger("foo");&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; &lt;span style="color: green;"&gt;//Assert.AreEqual(5, output);&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; &lt;span style="color: green;"&gt;// ... and now I'm verifying that the method was called&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; stub.VerifyAllExpectations();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;In translation, that test says: Create a fake ISampleClass; set up an expectation that a method will be called; &lt;s&gt;call that method&lt;/s&gt; do nothing; verify that your expectations were met (and flag the test as a failure if they weren't). Shoot. Worse than not having my expectations met is not realizing they're not being met. Reminds me of my college boyfriend.&lt;/p&gt;
&lt;p&gt;There are two things to fix here. The first is that this test is a little solipsistic. If you create a mock, tell the mock to act, and verify things about the mock... all you're testing are mocks. Instead, you want your tests to exercise &lt;em&gt;real&lt;/em&gt; code. The "system under test," i.e., the class being tested, should be part of your production code. Its dependencies are what get mocked, so that you can verify proper interactions with those dependencies. Let's fix the solipsism before going on to the second issue.&lt;/p&gt;
&lt;p&gt;As originally written, the expectation would be satisfied by the "Act" (as in Arrange-Act-Assert) part of the test. It says, "Call this method. Did I just call this method? Oh, good." Instead, you want to ensure the system under test correctly interacts with its friends,&amp;nbsp;using Rhino Mocks' AssertWasCalled and Expect methods. We need a real class that takes the stubbed class and calls a method on the stubbed class, and we'll write unit tests around the real class.&lt;/p&gt;
&lt;div style="font-family: Courier New; font-size: 8pt; color: black; background: white; border: 1px solid #ccc; overflow: auto; width: 550px;"&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;MyRealClass&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;{&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; ActOnTheSampleClass(&lt;span style="color: #2b91af;"&gt;ISampleClass&lt;/span&gt; sampleClass)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Here's the re-written test, verifying how my real class interacts with the ISampleClass interface.&lt;/p&gt;
&lt;div style="font-family: Courier New; font-size: 8pt; color: black; background: white; border: 1px solid #ccc; overflow: auto; width: 550px;"&gt;
&lt;pre style="margin: 0px;"&gt;[&lt;span style="color: #2b91af;"&gt;Test&lt;/span&gt;]&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Another_way_to_verify_expectations_instead_of_AssertWasCalled()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;{&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; stub = &lt;span style="color: #2b91af;"&gt;MockRepository&lt;/span&gt;.GenerateStub&amp;lt;&lt;span style="color: #2b91af;"&gt;ISampleClass&lt;/span&gt;&amp;gt;();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; systemUnderTest = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;MyRealClass&lt;/span&gt;();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; &lt;span style="color: green;"&gt;// Here I'm setting up an expectation that a method will be called&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; stub.Expect(s =&amp;gt; s.MethodThatReturnsInteger(&lt;span style="color: #a31515;"&gt;"foo"&lt;/span&gt;)).Return(5);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; &lt;span style="color: green;"&gt;// Tell the system to act (which, if it is working correctly, &lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; &lt;span style="color: green;"&gt;// will call a method on the ISampleClass.&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; systemUnderTest.ActOnTheSampleClass(stub);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; &lt;span style="color: green;"&gt;// ... and now I'm verifying that the method was called&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; stub.VerifyAllExpectations();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This test will still pass, despite the fact that my real class does not currently call any methods on the ISampleClass interface. This points to the second issue to fix. In Rhino Mocks, expectations on stubs are not verified; only mocks are verified. If an object is created with GenerateStub instead of GenerateMock, then its VerifyAllExpectations method doesn't do anything. This is non-obvious because the AssertWasCalled and AssertWasNotCalled methods on a stub &lt;em&gt;will&lt;/em&gt; behave the way you want them to.&lt;/p&gt;
&lt;p&gt;In Rhino Mocks, a stub can keep track of its interactions and assert that they happened, but it cannot record expectations and verify they were met. A mock can do both these things. &lt;/p&gt;
&lt;p&gt;That is how they are implemented in Rhino Mocks. If you were holding firm to the ideas in Fowler's &lt;a href="http://martinfowler.com/articles/mocksArentStubs.html"&gt;Mocks Aren't Stubs&lt;/a&gt; article, I think stubs would implement neither VerifyAll nor AssertWasCalled. Semantically, verifying expectations and asserting interactions are synonymous, if you ask me; therefore, stubs shouldn't do either one.&lt;/p&gt;
&lt;p&gt;Back to Jon Kruger's tests. If we call GenerateMock instead of GenerateStub, the test will fail properly with an ExpectationViolationException.&lt;/p&gt;
&lt;div style="font-family: Courier New; font-size: 8pt; color: black; background: white; border: 1px solid #ccc; overflow: auto; width: 550px;"&gt;
&lt;pre style="margin: 0px;"&gt;[&lt;span style="color: #2b91af;"&gt;Test&lt;/span&gt;]&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Another_way_to_verify_expectations_instead_of_AssertWasCalled()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;{&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; stub = &lt;span style="color: #2b91af;"&gt;MockRepository&lt;/span&gt;.GenerateMock&amp;lt;&lt;span style="color: #2b91af;"&gt;ISampleClass&lt;/span&gt;&amp;gt;();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; systemUnderTest = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;MyRealClass&lt;/span&gt;();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; &lt;span style="color: green;"&gt;// Here I'm setting up an expectation that a method will be called&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; stub.Expect(s =&amp;gt; s.MethodThatReturnsInteger(&lt;span style="color: #a31515;"&gt;"foo"&lt;/span&gt;)).Return(5);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; &lt;span style="color: green;"&gt;// Tell the system to act (which, if it is working correctly, &lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; &lt;span style="color: green;"&gt;// will call a method on the ISampleClass.&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; systemUnderTest.ActOnTheSampleClass(stub);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; &lt;span style="color: green;"&gt;// ... and now I'm verifying that the method was called&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; stub.VerifyAllExpectations();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now that we're red, let's get to green. Change the system under test so that it does its job as expected.&lt;/p&gt;
&lt;div style="font-family: Courier New; font-size: 8pt; color: black; background: white; border: 1px solid #ccc; overflow: auto; width: 550px;"&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;MyRealClass&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;{&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; ActOnTheSampleClass(&lt;span style="color: #2b91af;"&gt;ISampleClass&lt;/span&gt; sampleClass)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; &amp;nbsp; sampleClass.MethodThatReturnsInteger(&lt;span style="color: #a31515;"&gt;"foo"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Wahoo, a passing test that we can rely on.&lt;/p&gt;
&lt;p&gt;The two key points from this exercise are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="http://jonkruger.com/blog/2010/03/12/how-to-use-rhino-mocks-documented-through-tests/"&gt;Describing Rhino Mocks with unit tests&lt;/a&gt; is a cool way to explain a topic. Let's have more executable documentation, eh?&lt;/li&gt;
&lt;li&gt;Expectations on stubs aren't verified, so beware of falsely passing tests.&lt;/li&gt;
&lt;/ol&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=Rhino+Mocks+Examples%2c+with+a+fix&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fsharoncichelli%2farchive%2f2010%2f03%2f18%2frhino-mocks-examples-with-a-fix.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fsharoncichelli%2farchive%2f2010%2f03%2f18%2frhino-mocks-examples-with-a-fix.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=75445" width="1" height="1"&gt;</description><category domain="http://www.lostechies.com/blogs/sharoncichelli/archive/tags/unit+testing/default.aspx">unit testing</category><category domain="http://www.lostechies.com/blogs/sharoncichelli/archive/tags/Rhino+Mocks/default.aspx">Rhino Mocks</category></item><item><title>More Dogs and Bears and Chickens and Things: Invite your colleagues to Pablo's Fiesta</title><link>http://www.lostechies.com/blogs/sharoncichelli/archive/2010/02/07/more-dogs-and-bears-and-chickens-and-things-invite-your-colleagues-to-pablo-s-fiesta.aspx</link><pubDate>Sun, 07 Feb 2010 22:16:00 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:61264</guid><dc:creator>Sharon J. Cichelli</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/sharoncichelli/rsscomments.aspx?PostID=61264</wfw:commentRss><comments>http://www.lostechies.com/blogs/sharoncichelli/archive/2010/02/07/more-dogs-and-bears-and-chickens-and-things-invite-your-colleagues-to-pablo-s-fiesta.aspx#comments</comments><description>&lt;p&gt;If you work with developers who are women, please tell them about the &lt;a href="http://fiesta.lostechies.com/"&gt;Los Techies Open Space conference&lt;/a&gt;, coming up at the end of February. If you've attended an event like this in the past, you're already aware of some facts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The Austin developer community is vibrant, engaged, and constantly striving to improve our craft. We've got a good thing going here.&lt;/li&gt;
&lt;li&gt;The quality of the conversations and the value of the event far outstrip the price of admission; it would be a bargain at twice the price.&lt;/li&gt;
&lt;li&gt;Women are way under-represented.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Early in my career, I wasn't tapped into the information channels that announce events like this. I didn't go because I just didn't know about them. My friend and colleague &lt;a href="http://www.lostechies.com/blogs/joshuaflanagan/"&gt;Josh Flanagan&lt;/a&gt; made a point of letting me know, and encouraging me to go, and showing that it was not only okay but right to ask my employer to send me to such things.&lt;/p&gt;
&lt;p&gt;Attending conferences has made a huge difference in my growth as a developer and in my career. It brought me into the on-going conversation in the developer community. It exposed me to new practices and new technologies, which I brought back to the team. Please do the same favor for your women co-workers that Josh did for me: Tell them about Pablo's Fiesta and encourage them to sign up.&lt;/p&gt;
&lt;p&gt;Bringing women into the mix brings new, diverse ideas into the conversation, new skillsets to the community, more role models for our kids. The conference will be improved by spicing up the guest list. Although I'm focusing on women here, reach out to any of your colleagues who "don't usually go to these things." New voices mean new synergy, which means more learning and more fun.&lt;/p&gt;
&lt;p&gt;And you. &lt;a href="http://fiesta.lostechies.com/"&gt;Sign up&lt;/a&gt;, your own self. It'll be great.&lt;/p&gt;
&lt;p&gt;If you have any questions about Pablo's Fiesta, or about whether you'd enjoy it, please feel free to post them here, and I'll get the answers for you.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=More+Dogs+and+Bears+and+Chickens+and+Things%3a+Invite+your+colleagues+to+Pablo%27s+Fiesta&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fsharoncichelli%2farchive%2f2010%2f02%2f07%2fmore-dogs-and-bears-and-chickens-and-things-invite-your-colleagues-to-pablo-s-fiesta.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fsharoncichelli%2farchive%2f2010%2f02%2f07%2fmore-dogs-and-bears-and-chickens-and-things-invite-your-colleagues-to-pablo-s-fiesta.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=61264" width="1" height="1"&gt;</description></item><item><title>Interface-Oriented Design - Book Review</title><link>http://www.lostechies.com/blogs/sharoncichelli/archive/2010/01/17/interface-oriented-design-book-review.aspx</link><pubDate>Sun, 17 Jan 2010 18:54:00 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:48689</guid><dc:creator>Sharon J. Cichelli</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/sharoncichelli/rsscomments.aspx?PostID=48689</wfw:commentRss><comments>http://www.lostechies.com/blogs/sharoncichelli/archive/2010/01/17/interface-oriented-design-book-review.aspx#comments</comments><description>&lt;p&gt;Ken Pugh's &lt;i&gt;&lt;a href="http://www.pragprog.com/titles/kpiod/interface-oriented-design"&gt;Interface-Oriented Design&lt;/a&gt;&lt;/i&gt; (Pragmatic Programmers) presents an approach to designing applications that focuses first on the interfaces, the places where pieces of the application interact. The interfaces here are not primarily user interfaces, but module-to-module interfaces and service interfaces, and the applications are not exclusively object-oriented. Pugh's proposed process is to identify use cases and test cases, determine the interfaces that will enable those use cases, then create tests and implementations for the interfaces.&lt;/p&gt;
&lt;p&gt;The book is divided into three parts. The first explains the concepts and theory underlying an interface-focused approach to design. These concepts include real-world analogies which quickly provide context to the discussion; types of interfaces, such as stateless versus stateful, and procedural versus document; design concerns such as contracts, cohesiveness, and polymorphism; and the Asimov-inspired "three laws of interfaces," which specify the qualities of a well behaved implementation. Part two is brief and describes where interface-oriented design fits into the project lifecycle. Part three walks through three examples, from concept to design to implementation, and highlights the design patterns exhibited in those examples. The book concludes with a grab-bag appendix of topics that could have been better served by integration into the main text.&lt;/p&gt;
&lt;p&gt;If your learning style is learn-by-doing, you might get more out of the book by reading Part Three before Part One. Part Three provides the "yeah, but what are we &lt;em&gt;doin'&lt;/em&gt; here" skeleton onto which you can hang the theory that is explained in Part One. I find theory easier to digest and retain if I know which of my real-world, day-to-day experiences it applies to. You'll get that context if you flip the order in which you read it.&lt;/p&gt;
&lt;p&gt;I picked up this book looking for best practices on providing and consuming remote interfaces, and it isn't that. Have you ever taken a sip of something you like, but because you were expecting a completely different flavor, it tasted off? I bumped into that dissonance here, so it was hard for me to get into the book. To appropriately prepare your palate, the flavor to anticipate from &lt;i&gt;Interface-Oriented Design&lt;/i&gt; is a technique for thinking about a problem domain and its software solution by thinking about the places where responsibilities interact, analogous to the way that &lt;a href="http://en.wikipedia.org/wiki/Service-oriented_architecture"&gt;service-oriented architecture&lt;/a&gt; is a technique for thinking about software design.&lt;/p&gt;
&lt;p&gt;An area where this book really shines is Pugh's deft use of real-world examples. In the first  chapter, he introduces the process of ordering a pizza as a series of exchanges through a PizzaOrdering interface. The example is familiar, relatable, and practically identical across the United States (&lt;a href="http://www.austinspizza.com/"&gt;implementations vary&lt;/a&gt;, of course). Pugh then uses that example and expands upon it throughout the rest of the book, allowing us to fit new concepts into the model as it is refined. This worked better than if each new concept had been presented with a new example; the book gained a pedagogical momentum.&lt;/p&gt;
&lt;p&gt;Many times during my reading, I asked myself whether the ideas were so fundamental and distilled as to shift my way of thinking, or so fundamental as to be mundane and trivial. Was this book raising the level of abstraction, like climbing a mountain to get a better view of the landscape, or just telling me no-duh stuff I already knew? Is its audience experienced developers looking to put terms and practices around habits they do instinctively, or is its audience beginners who need an introduction to methodical design? I still haven't decided. Will it affect my thinking? Probably. Not in ways that I can articulate and enumerate for you, but likely in subtle and profound ways that I may or may not notice as they occur. For yourself, I recommend checking out the table of contents (available from the &lt;a href="http://www.pragprog.com/titles/kpiod/interface-oriented-design"&gt;Pragmatic Bookshelf&lt;/a&gt;) and see if it suits you.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=Interface-Oriented+Design+-+Book+Review&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fsharoncichelli%2farchive%2f2010%2f01%2f17%2finterface-oriented-design-book-review.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fsharoncichelli%2farchive%2f2010%2f01%2f17%2finterface-oriented-design-book-review.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=48689" width="1" height="1"&gt;</description><category domain="http://www.lostechies.com/blogs/sharoncichelli/archive/tags/books/default.aspx">books</category></item><item><title>Happy Hack-o-ween: Electronics and a microcontroller spice up the haunt</title><link>http://www.lostechies.com/blogs/sharoncichelli/archive/2009/11/08/happy-hack-o-ween-electronics-and-a-microcontroller-spice-up-the-haunt.aspx</link><pubDate>Sun, 08 Nov 2009 16:27:00 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:30142</guid><dc:creator>Sharon J. Cichelli</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/sharoncichelli/rsscomments.aspx?PostID=30142</wfw:commentRss><comments>http://www.lostechies.com/blogs/sharoncichelli/archive/2009/11/08/happy-hack-o-ween-electronics-and-a-microcontroller-spice-up-the-haunt.aspx#comments</comments><description>&lt;p&gt;Ah, Halloween, when a young woman's fancy turns to love. And zombies.&lt;/p&gt;
&lt;p&gt;I had two personal requirements for the costume I would build this year:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It shall be spooky.&lt;/li&gt;
&lt;li&gt;It shall blink.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I'll tell you about the final result, the electronics and the software that went into it, plus the techniques I used to achieve wearable electronics. I'll introduce you to the &lt;a href="http://www.arduino.cc/"&gt;Arduino&lt;/a&gt;, an open-source microcontroller prototyping platform, which is an exhilarating tool/toy for making your software skills manifest in the physical world.&lt;/p&gt;
&lt;p&gt;My husband and I have been teaching ourselves electronics. A few months ago, Dad taught me to solder. I recently read Syuzi Pakhchyan's excellent primer on wearable electronics and smart materials, &lt;a href="http://www.librarything.com/work/5874825/book/47829579"&gt;&lt;i&gt;Fashioning Technology&lt;/i&gt;&lt;/a&gt;. And I've been &lt;a href="http://blog.makezine.com/archive/2009/10/ambient_led_flowerpot_clock.html"&gt;making things&lt;/a&gt; with my Arduino. All these ideas were swirling and combining in my head to inspire this year's Halloween project. Er, &lt;em&gt;costume&lt;/em&gt;. Same difference.&lt;/p&gt;
&lt;p&gt;What was I? I was a nightmare... the thing under your bed... the reason for your well developed sense of paranoia...&lt;br /&gt;
&lt;a href="http://www.flickr.com/photos/spyderella/sets/72157622735987434/"&gt;&lt;img src="http://farm3.static.flickr.com/2609/4076005063_851a85338f_m.jpg" width="161" height="240" alt="The thing under your bed" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I sported a crop of writhing eyeballs erupting from my head. Each eyeball has an LED inside it, and they blink randomly and independently, until I trigger a hidden switch, which causes the blinky ones to go dark and two red eyes to pulse menacingly. In the &lt;a href="http://www.flickr.com/photos/spyderella/sets/72157622735987434/"&gt;Flickr photoset&lt;/a&gt;, you can see the construction process.&lt;/p&gt;
&lt;h2&gt;The Arduino Sketch&lt;/h2&gt;
&lt;p&gt;The term "Arduino" is overloaded to mean:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;a particular chip and circuit board which you can buy or build;&lt;/li&gt;
&lt;li&gt;the IDE in which you write programs for the chip;&lt;/li&gt;
&lt;li&gt;the language, which is C-flavored;&lt;/li&gt;
&lt;li&gt;fun.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Arduino programs are called sketches. Every sketch must contain two functions: setup (runs once) and loop (runs continuously). Here's my sketch, with extra explanatory comments, that blinks the six regular eyeballs and responds to the switch by pulsing the red eyeballs.&lt;/p&gt;
&lt;div style="font-family: Courier New; font-size: 8pt; color: black; background: white; border: 1px solid #ccc; overflow: auto; width: 600px; height: 400px;"&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;#define&lt;/span&gt; SWITCH 8&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;int&lt;/span&gt; ledPins[] = {2, 3, 4, 5, 6, 7};&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;const&lt;/span&gt; &lt;span style="color: blue;"&gt;int&lt;/span&gt; ledPinsCount = 6;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;int&lt;/span&gt; redEyePins[] = {10, 11};&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;const&lt;/span&gt; &lt;span style="color: blue;"&gt;int&lt;/span&gt; redEyePinsCount = 2;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;long&lt;/span&gt; durations[ledPinsCount];&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;int&lt;/span&gt; ledStates[ledPinsCount];&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;long&lt;/span&gt; previousTimes[ledPinsCount];&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;int&lt;/span&gt; i;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;10&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;11&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;void&lt;/span&gt; setup()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;12&lt;/span&gt;&amp;nbsp;{&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;13&lt;/span&gt;&amp;nbsp;&amp;nbsp; pinMode(SWITCH, INPUT); &lt;span style="color: green;"&gt;//Specify the switch pin as an input.&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;14&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;15&lt;/span&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;for&lt;/span&gt; (i = 0; i &amp;lt; redEyePinsCount; i++)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;16&lt;/span&gt;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;17&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; pinMode(redEyePins, OUTPUT); &lt;span style="color: green;"&gt;//Specify each red-eye LED pin as an output.&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;18&lt;/span&gt;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;19&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;20&lt;/span&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;for&lt;/span&gt;(i = 0; i &amp;lt; ledPinsCount; i++)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;21&lt;/span&gt;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;22&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; pinMode(ledPins, OUTPUT); &lt;span style="color: green;"&gt;//Specify each regular LED pin as an output.&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;23&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; ledStates = random(1); &lt;span style="color: green;"&gt;//Randomly set the LEDs to on or off (1 or 0).&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;24&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; durations = GetRandomDuration(); &lt;span style="color: green;"&gt;//Define a random duration for each LED to stay in that state.&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;25&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; previousTimes = 0; &lt;span style="color: green;"&gt;//At time of setup, the "last time we changed" is at 0 milliseconds, the start of time.&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;26&lt;/span&gt;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;27&lt;/span&gt;&amp;nbsp;}&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;28&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;29&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;void&lt;/span&gt; loop()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;30&lt;/span&gt;&amp;nbsp;{&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;31&lt;/span&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (digitalRead(SWITCH) == HIGH)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;32&lt;/span&gt;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;33&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; TurnOffLeds();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;34&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; PulseRedEyes();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;35&lt;/span&gt;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;36&lt;/span&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;else&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;37&lt;/span&gt;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;38&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;for&lt;/span&gt;(i = 0; i &amp;lt; redEyePinsCount; i++)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;39&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;40&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; digitalWrite(redEyePins, LOW); &lt;span style="color: green;"&gt;//Turn the red eyes all the way off.&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;41&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;42&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;43&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;for&lt;/span&gt;(i = 0; i &amp;lt; ledPinsCount; i++) &lt;span style="color: green;"&gt;//For each LED:&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;44&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;45&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (millis() - previousTimes &amp;gt; durations)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;46&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;47&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ChangeLed(i); &lt;span style="color: green;"&gt;//If this one's duration is up, then flip it.&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;48&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;49&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;50&lt;/span&gt;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;51&lt;/span&gt;&amp;nbsp;}&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;52&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;53&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;void&lt;/span&gt; TurnOffLeds()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;54&lt;/span&gt;&amp;nbsp;{&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;55&lt;/span&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;for&lt;/span&gt;(i = 0; i &amp;lt; ledPinsCount; i++)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;56&lt;/span&gt;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;57&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; digitalWrite(ledPins, LOW);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;58&lt;/span&gt;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;59&lt;/span&gt;&amp;nbsp;}&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;60&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;61&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;void&lt;/span&gt; PulseRedEyes()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;62&lt;/span&gt;&amp;nbsp;{&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;63&lt;/span&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//Fade on, then off.&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;64&lt;/span&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;int&lt;/span&gt; j;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;65&lt;/span&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;for&lt;/span&gt;(j = 0; j &amp;lt; 255; j+=5)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;66&lt;/span&gt;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;67&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;for&lt;/span&gt;(i = 0; i &amp;lt; redEyePinsCount; i++)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;68&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;69&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; analogWrite(redEyePins, j);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;70&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; delay(10);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;71&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;72&lt;/span&gt;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;73&lt;/span&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;for&lt;/span&gt;(j = 255; j &amp;gt; 0; j-=5)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;74&lt;/span&gt;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;75&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;for&lt;/span&gt;(i = 0; i &amp;lt; redEyePinsCount; i++)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;76&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;77&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; analogWrite(redEyePins, j);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;78&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; delay(10);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;79&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;80&lt;/span&gt;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;81&lt;/span&gt;&amp;nbsp;}&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;82&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;83&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;void&lt;/span&gt; ChangeLed(&lt;span style="color: blue;"&gt;int&lt;/span&gt; ledPin)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;84&lt;/span&gt;&amp;nbsp;{&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;85&lt;/span&gt;&amp;nbsp;&amp;nbsp; previousTimes[ledPin] = millis(); &lt;span style="color: green;"&gt;//Update the "last time we changed" to now.&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;86&lt;/span&gt;&amp;nbsp;&amp;nbsp; durations[ledPin] = GetRandomDuration(); &lt;span style="color: green;"&gt;//Give it a new random duration.&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;87&lt;/span&gt;&amp;nbsp;&amp;nbsp; ledStates[ledPin] = 1 - ledStates[ledPin]; &lt;span style="color: green;"&gt;//Flip the state between on and off.&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;88&lt;/span&gt;&amp;nbsp;&amp;nbsp; digitalWrite(ledPins[ledPin], ledStates[ledPin]); &lt;span style="color: green;"&gt;//Set the LED to that state.&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;89&lt;/span&gt;&amp;nbsp;}&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;90&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;91&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;long&lt;/span&gt; GetRandomDuration()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;92&lt;/span&gt;&amp;nbsp;{&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;93&lt;/span&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//Random number between 1 and 10, then multiplied by 400 to give it a detectable duration.&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;94&lt;/span&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; random(1, 10) * 400;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;95&lt;/span&gt;&amp;nbsp;}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;I like the way the eyes blink independently. If they all flashed in unison, they would look like Christmas lights, and you would notice that two were "special" because they weren't flashing. Instead, the duration that any given eyeball is lit or dark constantly changes.&lt;/p&gt;
&lt;p&gt;The blinking is managed by a collection of arrays. One array represents each of my LED pins, so that I can address them in a for loop. The three other arrays hold: the state (on/off) of each LED; the duration each LED should stay in that state; the reading from the millisecond counter when the LED last flipped its state. Each time the loop function executes, if the switch is not connected, then I look at each LED; if the difference between the current time and the time when it previously changed is greater than its duration, flip its state (from off to on, or from on to off), randomly assign it a new duration, and record "now" as the new "previously changed" time. If the switch &lt;em&gt;is&lt;/em&gt; connected, then I make the red eyes fade on and fade off.&lt;/p&gt;
&lt;h2&gt;Fading with PWM&lt;/h2&gt;
&lt;p&gt;PWM (Pulse-Width Modulation) is a technique for making a digital component (one that turns on or off) simulate analog behavior (be a little bit on, and then a little bit more on). If you turn an LED off and on really quickly, you won't perceive the flickering, but it will look half as bright, because it is actually off for half the time. If you let it spend a little more time off than on, it will appear even dimmer. So by varying the width of the pulses, you can control how bright the LED looks.&lt;/p&gt;
&lt;p&gt;The Arduino comes with built-in PWM functions; some pins are already set up to be PWM pins. If you plug an LED into one of the PWM pins, then you can write to it as if it were an analog component. That's why, in my sketch above, I set the brightness of the red eyes using &lt;em&gt;analogWrite()&lt;/em&gt;, instead of digitalWrite(). My for loop increments the counter j from 0 to 255, and sets the brightness of both red eyes to the value of j. The Arduino takes care of (imperceptibly) flickering the LEDs with the right ratio of on-time and off-time to achieve a j amount of brightness. So the eyes get gradually brighter, then gradually dimmer. (Then control returns to the main loop function, but if my switch is still connected, the red eyes will throb again.)&lt;/p&gt;
&lt;h2&gt;Snaps: Wearable Plugs&lt;/h2&gt;
&lt;p&gt;A metal sewable snap is like a plug for your clothing, an interface between the world of textiles and the world of wires. This is handy when you need the electronics to be separate while you are getting into the clothing, or if you want to wash the clothing. My Arduino hung out at the base of my neck, to be near the LEDs on my head but hidden underneath my wig, but my control switch was near my hip. I could have run a wire down to the switch, but conductive thread was more subtle and more comfortable.&lt;/p&gt;
&lt;p&gt;To complete the connection, I soldered a short wire to one side of the snap. That wire plugged into a pin on the Arduino. The conductive thread ran from the switch at my hip up to the back of my dress near the Arduino, and I sewed that conductive thread to the other half of the snap. When the two halves are snapped together, the wire and the thread make a complete connection, as if they were one continuous wire.&lt;br /&gt;
&lt;a href="http://www.flickr.com/photos/spyderella/4085497865/" title="Soldered snaps / Sewn snaps by Spyderella, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2584/4085497865_a50e4e45d1_m.jpg" width="240" height="180" alt="Soldered snaps / Sewn snaps" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I had two threads (going out to the switch and back), so I encased them each in a bias tape tube, to prevent them from touching each other and shorting out.&lt;/p&gt;
&lt;p&gt;I've been saying "switch," but actually, I simplified at the 11th hour. I tied each thread around a safety pin, and stuck the pins to my dress. When the safety pins touched each other, they completed the circuit, which the Arduino sketch interpreted as triggering the switch&amp;mdash;cue red-eye glare.&lt;/p&gt;
&lt;h2&gt;What's Next&lt;/h2&gt;
&lt;p&gt;Soldering and sewing are both liberating skills to possess&amp;mdash;they free up your creativity to make wilder and more integrated stuff. If you are currently proficient with only one, ask around and see if you can find a buddy who's good at the other, and teach each other.&lt;/p&gt;
&lt;p&gt;The Arduino comes with a great community of hackers and makers, lots of people to learn from and collaborate with. Definitely check it out. There is lots of fun to be had, and blinking LEDs is the barest beginning of what it can do.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=Happy+Hack-o-ween%3a+Electronics+and+a+microcontroller+spice+up+the+haunt&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fsharoncichelli%2farchive%2f2009%2f11%2f08%2fhappy-hack-o-ween-electronics-and-a-microcontroller-spice-up-the-haunt.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fsharoncichelli%2farchive%2f2009%2f11%2f08%2fhappy-hack-o-ween-electronics-and-a-microcontroller-spice-up-the-haunt.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=30142" width="1" height="1"&gt;</description><category domain="http://www.lostechies.com/blogs/sharoncichelli/archive/tags/arduino/default.aspx">arduino</category><category domain="http://www.lostechies.com/blogs/sharoncichelli/archive/tags/electronics/default.aspx">electronics</category></item><item><title>Refactoring Dinner: Interfaces instead of Inheritance</title><link>http://www.lostechies.com/blogs/sharoncichelli/archive/2009/10/13/refactoring-dinner-interfaces-instead-of-inheritance.aspx</link><pubDate>Wed, 14 Oct 2009 02:03:00 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:26297</guid><dc:creator>Sharon J. Cichelli</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/sharoncichelli/rsscomments.aspx?PostID=26297</wfw:commentRss><comments>http://www.lostechies.com/blogs/sharoncichelli/archive/2009/10/13/refactoring-dinner-interfaces-instead-of-inheritance.aspx#comments</comments><description>&lt;p&gt;Last time, in &lt;a href="http://www.lostechies.com/blogs/sharoncichelli/archive/2009/08/29/cooking-up-a-good-template-method.aspx"&gt;Cooking Up a Good Template Method&lt;/a&gt;, I had a template method cooking our dinner. An abstract base class defined the template&amp;mdash;the high level steps for preparing a one-skillet dinner&amp;mdash;and a derived class provided the implementation for those steps. I'm currently reading &lt;a href="http://www.pragprog.com/titles/kpiod/interface-oriented-design"&gt;Ken Pugh's &lt;i&gt;Interface Oriented Design&lt;/i&gt;&lt;/a&gt; (more on that after I finish the book), and it got me thinking of a way to change the design to use interfaces instead of inheritance.&lt;/p&gt;
&lt;p&gt;I think there's value in this refactoring because it allows future flexibility and testability. Let's stroll through it, and I welcome your thoughts about how (and whether) this improves the code.&lt;/p&gt;
&lt;p&gt;Previously, we had a base class SkilletDinner, which was extended by variants on that theme, such as chicken with onions and bell peppers or the FancyBaconPankoDinner. (If I've learned one thing from my readership, it is that blog posts should mention bacon. Mm, crispy bacon.) As the first step in the refactoring, I'll create an interface, ISkilletCookable that provides the same methods that were previously abstract methods in SkilletDinner. By naming convention, the interface is prefixed with 'I' and is an adjective describing how it can be used (-able).&lt;/p&gt;
&lt;div style="font-family: Courier New; font-size: 8pt; color: black; background: white; border: 1px solid #ccc; overflow: auto; width: 500px;"&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;interface&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;ISkilletCookable&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;void&lt;/span&gt; HeatFat();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;void&lt;/span&gt; SauteSavoryRoot();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;void&lt;/span&gt; SauteProtein();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;void&lt;/span&gt; SauteVegetables();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;10&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;void&lt;/span&gt; AddSauceAndGarnish();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;11&lt;/span&gt;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Next, I'll create a SkilletDinner constructor that accepts an ISkilletCookable, and change the SkilletDinner's Cook() method to ask that cookable to do the work. SkilletDinner no longer needs to be abstract.&lt;/p&gt;
&lt;div style="font-family: Courier New; font-size: 8pt; color: black; background: white; border: 1px solid #ccc; overflow: auto; width: 500px;"&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;SkilletDinner&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;readonly&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;ISkilletCookable&lt;/span&gt; cookable;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; SkilletDinner(&lt;span style="color: #2b91af;"&gt;ISkilletCookable&lt;/span&gt; cookable)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;10&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;11&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;.cookable = cookable;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;12&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;13&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;14&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Cook()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;15&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;16&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; cookable.HeatFat();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;17&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; cookable.SauteSavoryRoot();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;18&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; cookable.SauteProtein();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;19&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; cookable.SauteVegetables();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;20&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; cookable.AddSauceAndGarnish();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;21&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;22&lt;/span&gt;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Then, FancyBaconPankoDinner implements ISkilletCookable and provides implementations for each of the methods that will be called by the Cook() method.&lt;/p&gt;
&lt;p&gt;The first benefit from this refactoring is flexibility. While FancyBaconPankoDinner could not have inherited multiple classes (no multiple inheritance in C#), it &lt;em&gt;can&lt;/em&gt; implement multiple interfaces. For example, it could also implement the IShoppable interface, thereby providing a ListIngredients() method that would let me include it in my grocery list.&lt;/p&gt;
&lt;p&gt;This refactoring also makes it easier for me to test the quality and completeness of my template method. I can verify&amp;mdash;does it cover all of the requisite steps for cooking a skillet dinner?&amp;mdash;by creating &lt;a href="http://martinfowler.com/articles/mocksArentStubs.html#ChoosingBetweenTheDifferences"&gt;behavior-verifying tests&lt;/a&gt; that assess the SkilletDinner's interactions with the ISkilletCookable interface. When I'm writing unit tests for the SkilletDinner class, I want to test its behavior because &lt;em&gt;the behavior is what's important&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;To forestall objections, I tried writing a test around the old version, creating my own mock class that extends the old abstract SkilletDinner. It got pretty lengthy.&lt;/p&gt;
&lt;div style="font-family: Courier New; font-size: 8pt; color: black; background: white; border: 1px solid #ccc; overflow: auto; height: 300px; width: 500px;"&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;SkilletDinnerSpecs&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; [TestFixture]&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;When_told_to_cook&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;const&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; heatFatMethod = &lt;span style="color: #a31515;"&gt;"HeatFat"&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;10&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;const&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; sauteSavoryRootMethod = &lt;span style="color: #a31515;"&gt;"SauteSavoryRoot"&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;11&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;const&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; sauteProteinMethod = &lt;span style="color: #a31515;"&gt;"SauteProtein"&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;12&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;const&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; sauteVegetablesMethod = &lt;span style="color: #a31515;"&gt;"SauteVegetables"&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;13&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;const&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; addFinishingTouchesMethod = &lt;span style="color: #a31515;"&gt;"AddFinishingTouches"&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;14&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;15&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; [&lt;span style="color: #2b91af;"&gt;Test&lt;/span&gt;]&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;16&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Should_follow_dinner_preparation_steps_in_order()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;17&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;18&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; systemUnderTest = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;MockSkilletDinner&lt;/span&gt;();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;19&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;20&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; expectedMethodCalls = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: blue;"&gt;string&lt;/span&gt;&amp;gt;();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;21&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; expectedMethodCalls.Add(heatFatMethod);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;22&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; expectedMethodCalls.Add(sauteSavoryRootMethod);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;23&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; expectedMethodCalls.Add(sauteProteinMethod);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;24&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; expectedMethodCalls.Add(sauteVegetablesMethod);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;25&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; expectedMethodCalls.Add(addFinishingTouchesMethod);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;26&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;27&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; systemUnderTest.Cook();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;28&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;29&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #2b91af;"&gt;Assert&lt;/span&gt;.AreEqual(expectedMethodCalls.Count, systemUnderTest.CalledMethods.Count, &lt;span style="color: #a31515;"&gt;"Expected number of called methods did not equal actual."&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;30&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;31&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;for&lt;/span&gt; (&lt;span style="color: blue;"&gt;int&lt;/span&gt; i = 0; i &amp;lt; expectedMethodCalls.Count; i++)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;32&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;33&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: #2b91af;"&gt;Assert&lt;/span&gt;.AreEqual(expectedMethodCalls, systemUnderTest.CalledMethods);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;34&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;35&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;36&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;37&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;MockSkilletDinner&lt;/span&gt; : &lt;span style="color: #2b91af;"&gt;SkilletDinner&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;38&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;39&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;readonly&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: blue;"&gt;string&lt;/span&gt;&amp;gt; CalledMethods = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: blue;"&gt;string&lt;/span&gt;&amp;gt;();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;40&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;41&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;override&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; HeatFat()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;42&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;43&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; CalledMethods.Add(heatFatMethod);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;44&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;45&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;46&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;override&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; SauteSavoryRoot()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;47&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;48&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; CalledMethods.Add(sauteSavoryRootMethod);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;49&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;50&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;51&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;override&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; SauteProtein()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;52&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;53&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; CalledMethods.Add(sauteProteinMethod);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;54&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;55&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;56&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;override&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; SauteVegetables()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;57&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;58&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; CalledMethods.Add(sauteVegetablesMethod);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;59&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;60&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;61&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;override&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; AddFinishingTouches()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;62&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;63&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; CalledMethods.Add(addFinishingTouchesMethod);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;64&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;65&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;66&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;67&lt;/span&gt;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;In the new design, I can mock the ISkilletCookable interface with a mocking framework like Rhino.Mocks. The interface is easy to mock because interfaces, being the epitome of abstractions, readily lend themselves to being replaced by faked implementations. Rhino.Mocks takes care of recording and verifying which methods were called.
&lt;/p&gt;
&lt;div style="font-family: Courier New; font-size: 8pt; color: black; background: white; border: 1px solid #ccc; overflow: auto; width: 500px;"&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;SkilletDinnerSpecs&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; [&lt;span style="color: #2b91af;"&gt;TestFixture&lt;/span&gt;]&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;10&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;When_told_to_cook&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;11&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;12&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; [&lt;span style="color: #2b91af;"&gt;Test&lt;/span&gt;]&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;13&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Should_follow_dinner_preparation_steps_in_order()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;14&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;15&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; mocks = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;MockRepository&lt;/span&gt;();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;16&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; cookable = mocks.StrictMock&amp;lt;&lt;span style="color: #2b91af;"&gt;ISkilletCookable&lt;/span&gt;&amp;gt;();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;17&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; systemUnderTest = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;SkilletDinner&lt;/span&gt;(cookable);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;18&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;19&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;using&lt;/span&gt; (mocks.Record())&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;20&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;21&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;using&lt;/span&gt; (mocks.Ordered())&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;22&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;23&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cookable.HeatFat();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;24&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cookable.SauteSavoryRoot();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;25&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cookable.SauteProtein();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;26&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cookable.SauteVegetables();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;27&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cookable.AddSauceAndGarnish();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;28&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;29&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;30&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;using&lt;/span&gt; (mocks.Playback())&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;31&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;32&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; systemUnderTest.Cook();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;33&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;34&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;35&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;36&lt;/span&gt;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The test relies on Rhino.Mocks to create a mock implementation of ISkilletCookable, and then verifies that the system under test, the SkilletDinner, interacts correctly with ISkilletCookable by telling it what steps to do in what order.&lt;/p&gt;
&lt;p&gt;That test is quite cognizant of the inner workings of the SkilletDinner.Cook() method, but that's specifically what I'm unit testing: Does the template method do the right steps? I don't mind how the steps are done, but you have to start the onions before you add the meat, or else the onions won't caramelize and flavor the oil.&lt;/p&gt;
&lt;p&gt;By the way, if you had previously found the learning curve for Rhino.Mocks' record/playback model too steep a hill to climb (or to convince your teammates to climb), check out &lt;a href="http://www.ayende.com/Wiki/Rhino%20Mocks%203.5.ashx"&gt;Rhino.Mocks 3.5's arrange-act-assert style&lt;/a&gt;. It creates more readable tests, putting statements in a more intuitive order. I really like it. I could not, however, use it here because I have not found a way to enforce ordering of the expectations (i.e., to assert that method A was called before B, and to fail if B was called before A) in A-A-A-style. So we have a record/playback test, instead.&lt;/p&gt;
&lt;p&gt;Here's a summary of the refactoring. I extracted an interface, ISkilletCookable, and composed SkilletDinner with an instance of that interface, liberating us from class inheritance. Because SkilletDinner is now given the worker it depends on (via dependency injection), I can give it a fake worker in my tests, so that my unit tests don't need to perform the time- and resource-consuming operation of firing up the stove. And I managed to write another blog post that mentions bacon. Mm, bacon.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=Refactoring+Dinner%3a+Interfaces+instead+of+Inheritance&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fsharoncichelli%2farchive%2f2009%2f10%2f13%2frefactoring-dinner-interfaces-instead-of-inheritance.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fsharoncichelli%2farchive%2f2009%2f10%2f13%2frefactoring-dinner-interfaces-instead-of-inheritance.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=26297" width="1" height="1"&gt;</description><category domain="http://www.lostechies.com/blogs/sharoncichelli/archive/tags/refactoring/default.aspx">refactoring</category><category domain="http://www.lostechies.com/blogs/sharoncichelli/archive/tags/unit+testing/default.aspx">unit testing</category></item><item><title>Cooking Up a Good Template Method</title><link>http://www.lostechies.com/blogs/sharoncichelli/archive/2009/08/29/cooking-up-a-good-template-method.aspx</link><pubDate>Sat, 29 Aug 2009 16:53:00 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:24304</guid><dc:creator>Sharon J. Cichelli</dc:creator><slash:comments>12</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/sharoncichelli/rsscomments.aspx?PostID=24304</wfw:commentRss><comments>http://www.lostechies.com/blogs/sharoncichelli/archive/2009/08/29/cooking-up-a-good-template-method.aspx#comments</comments><description>&lt;p&gt;The software concept of "raising the level of abstraction" has improved my skill and creativity in cooking, by teaching me to think about recipe components in terms of their properties and functions. Practicing abstraction-raising in cooking feeds back to help me with coding; for example, keeping me from going astray the other day with the &lt;a href="http://en.wikipedia.org/wiki/Template_method_pattern"&gt;Template Method pattern&lt;/a&gt;. This post is more about coding than cooking. The cooking's a metaphor. (The cake is a lie.)&lt;/p&gt;
&lt;h2&gt;Abstract Cooking&lt;/h2&gt;
&lt;p&gt;My skill with cooking grew from rote recipe following to intuitive creation when I started to think of it in terms borrowed from software: raising the level of abstraction.&lt;/p&gt;
&lt;p&gt;Consider a week-night skillet dinner. If I told you to heat canola oil in a cast-iron skillet, saute slices of onion and chunks of chicken seasoned with salt and pepper, and toss in bell peppers cut into strips, you could probably follow along and make exactly that. But that's pretty limiting. If instead I described the process as using a fat to conduct heat for sauteing a savory root, a seasoned protein, and some vegetables, then you could use that as a template, and make a week of dinners without repeating yourself.&lt;/p&gt;
&lt;p&gt;Let's dive into that step of using a fat for conduction, because it is a cool and useful bit of food science. To cook, you need to get heat onto food. The medium can be air, liquid, or fat. Each creates different results, hence the terms baking, boiling, and frying. When you toss cut-up bits of food in a skillet with oil and repeatedly jostle them, you're sauteing ("saute" means "to jump"), and that oil is playing the role of the fat, which is conducting the heat. If you'll pardon the metaphor, CanolaOil implements the IFat interface.&lt;/p&gt;
&lt;p&gt;It's useful to think of cooking this way, because if you know the properties of the various cooking fats, you can choose the right IFat implementation for the job. Canola oil is heart-healthy and stands up well to stove-top heat. Olive oil has wonderful health benefits, a bold flavor, and an intriguing green color, but those attributes are pretty much obliterated by heat, so save your expensive EVOO for raw applications like salads and dips. Butter makes everything taste better, browns up beautifully, but is harder on the heart and will burn at a low temperature; temper it with an oil like canola to keep it from burning. Peanut oil stands up to heat like a champ, so it's popular for deep frying. Armed with this kind of knowledge, I don't need to check a recipe when I'm cooking; I just think about what I'm trying to accomplish, and choose the right implementation.&lt;/p&gt;
&lt;p&gt;Pam Anderson's &lt;a href="http://www.librarything.com/work/67701"&gt;&lt;i&gt;How to Cook Without a Book&lt;/i&gt;&lt;/a&gt; got me thinking about food this way, and Harold McGee's &lt;a href="http://www.librarything.com/work/44636"&gt;&lt;i&gt;On Food and Cooking&lt;/i&gt;&lt;/a&gt; provides a feast of food geekery to fill in all the particulars.&lt;/p&gt;
&lt;h2&gt;Template Coding&lt;/h2&gt;
&lt;p&gt;Thinking about food this way, raising the level of abstraction, guides my thinking about code. My meal preparation follows the Template Method pattern, as does a class my teammate and I needed to modify recently.&lt;/p&gt;
&lt;p&gt;In this example, our application sends instructions to various external systems. The specifics of how those systems like to hold their conversations vary between systems. However, the series of steps, when phrased in our core business terms, remain the same. You do A, then you do B, then you do C, in whatever way a particular instance likes to do A, B, and C.&lt;/p&gt;
&lt;p&gt;Here's my class with its template method, translated back to the dinner metaphor:&lt;/p&gt;
&lt;div style="border: 1px solid #ccc; font-family: Courier New; font-size: 8pt; color: black; background: white; width: 500px;"&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;abstract&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;SkilletDinner&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Cook()&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HeatFat();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; SauteSavoryRoot();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; SauteProtein();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;10&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; SauteVegetables();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;11&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;12&lt;/span&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;13&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;abstract&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; HeatFat();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;14&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;abstract&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; SauteSavoryRoot();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;15&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;abstract&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; SauteProtein();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;16&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;abstract&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; SauteVegetables();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;17&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;But lo, I encountered an external system that needed to do one extra little thing. I needed a special step, just for that one instance. Like dinner the other night, where the vegetable was asparagus, the fat was bacon (oh ho!), and the final step was to toss some panko breadcrumbs into the pan to brown and toast and soak up the bacony love.&lt;/p&gt;
&lt;p&gt;How do I extend my template method to accommodate an instance-specific step?&lt;/p&gt;
&lt;p&gt;One idea that floated by was to make the method virtual, so that we could override it in our special instance. But we still wanted the rest of the steps, so we'd have to copy the whole method into the new instance, just to add a few lines. Also, anybody else could override that template, too, so that when they were told to do A, B, and C, they could totally fib and do nothing of the sort.&lt;/p&gt;
&lt;div style="border: 1px solid #ccc; font-family: Courier New; font-size: 8pt; color: black; background: white; overflow: auto; height: 300px; width: 500px;"&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;abstract&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;SkilletDinner&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;virtual&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Cook()&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: green;"&gt;//Note: The Cook template method is now virtual,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: green;"&gt;//and can be overridden in deriving classes. &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: green;"&gt;//That's not good.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;10&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HeatFat();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;11&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; SauteSavoryRoot();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;12&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; SauteProtein();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;13&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; SauteVegetables();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;14&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;15&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;abstract&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; HeatFat();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;16&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;abstract&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; SauteSavoryRoot();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;17&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;abstract&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; SauteProtein();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;18&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;abstract&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; SauteVegetables();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;19&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;20&lt;/span&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;21&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;LazyDinner&lt;/span&gt; : &lt;span style="color: #2b91af;"&gt;SkilletDinner&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;22&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;23&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;override&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Cook()&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;24&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;25&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; OrderPizza();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;26&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: green;"&gt;//We're overriding the template and *cheating*!&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;27&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: green;"&gt;//Although, if it's Austin's Pizza, &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;28&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: green;"&gt;//maybe that's okay...&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;29&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;30&lt;/span&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;31&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; OrderPizza()&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;32&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;33&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: green;"&gt;//With extra garlic!&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;34&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;35&lt;/span&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;36&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;override&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; HeatFat() { }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;37&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;override&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; SauteSavoryRoot() { }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;38&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;override&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; SauteProtein() { }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;39&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;override&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; SauteVegetables() { }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;40&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;That LazyDinner class isn't really a SkilletDinner at all; its behavior is completely different. No, that option flouts the whole point of the Template Method pattern.&lt;/p&gt;
&lt;p&gt;Our better idea was to make one small change to the template method, adding an extension point. That is, a call to a virtual method which in the base implementation does nothing, and can be overridden and told to do stuff in specific cases.&lt;/p&gt;
&lt;p&gt;Back to dinner:&lt;/p&gt;
&lt;div style="border: 1px solid #ccc; font-family: Courier New; font-size: 8pt; color: black; background: white; overflow: auto; height: 300px; width: 500px;"&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;abstract&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;SkilletDinner&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Cook()&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; HeatFat();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; SauteSavoryRoot();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; SauteProtein();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;10&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; SauteVegetables();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;11&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; AddFinishingTouches(); &lt;span style="color: green;"&gt;//Here's the hook.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;12&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;13&lt;/span&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;14&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;virtual&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; AddFinishingTouches()&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;15&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;16&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: green;"&gt;//By default, do nothing.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;17&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;18&lt;/span&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;19&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;abstract&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; HeatFat();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;20&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;abstract&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; SauteSavoryRoot();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;21&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;abstract&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; SauteProtein();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;22&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;abstract&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; SauteVegetables();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;23&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;24&lt;/span&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;25&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;FancyBaconPankoDinner&lt;/span&gt; : &lt;span style="color: #2b91af;"&gt;SkilletDinner&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;26&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;27&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;override&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; AddFinishingTouches()&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;28&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;29&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: green;"&gt;//In this case, override this extensibility hook:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;30&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ToastBreadcrumbs();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;31&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;32&lt;/span&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;33&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; ToastBreadcrumbs()&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;34&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;35&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: green;"&gt;//Toss in the bacon fat; keep 'em moving.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;36&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;37&lt;/span&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;38&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;override&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; HeatFat()&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;39&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;40&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: green;"&gt;//Cook bacon, set aside, drain off some fat.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;41&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;42&lt;/span&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;43&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;override&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; SauteSavoryRoot()&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;44&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;45&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: green;"&gt;//Minced garlic, until soft but before browning&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;46&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;47&lt;/span&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;48&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;override&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; SauteProtein()&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;49&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;50&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: green;"&gt;//How about... tofu that tastes like bacon?&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;51&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;52&lt;/span&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;53&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;protected&lt;/span&gt; &lt;span style="color: blue;"&gt;override&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; SauteVegetables()&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;54&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;55&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: green;"&gt;//Asparagus, cut into sections. &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;56&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color: green;"&gt;//Make it bright green and a little crispy.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;57&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;58&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;This maintains the contract of the template method, while allowing for special cases. With the right extensibility hooks in place, my dinner preparation happily follows the &lt;a href="http://www.lostechies.com/blogs/joe_ocampo/archive/2008/03/21/ptom-the-open-closed-principle.aspx"&gt;Open-Closed Principle&lt;/a&gt;&amp;mdash;open for extension, but closed for modification.&lt;/p&gt;
&lt;p&gt;I enjoy the way my various hobbies feed into and reflect upon each other. I hope this post has given you some useful insight into the Template Method pattern, or dinner preparation, or both. Look for synergies amongst your own varied interests; it can be the springboard for some truly breakthrough ideas.&lt;/p&gt;
&lt;p&gt;Mmm, bacon...&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=Cooking+Up+a+Good+Template+Method&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fsharoncichelli%2farchive%2f2009%2f08%2f29%2fcooking-up-a-good-template-method.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fsharoncichelli%2farchive%2f2009%2f08%2f29%2fcooking-up-a-good-template-method.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=24304" width="1" height="1"&gt;</description><category domain="http://www.lostechies.com/blogs/sharoncichelli/archive/tags/Design+Patterns/default.aspx">Design Patterns</category></item><item><title>Inconvenient Accessibility Makes Self-Documenting Code</title><link>http://www.lostechies.com/blogs/sharoncichelli/archive/2009/06/20/inconvenient-accessibility-makes-self-documenting-code.aspx</link><pubDate>Sat, 20 Jun 2009 12:11:00 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:22300</guid><dc:creator>Sharon J. Cichelli</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.lostechies.com/blogs/sharoncichelli/rsscomments.aspx?PostID=22300</wfw:commentRss><comments>http://www.lostechies.com/blogs/sharoncichelli/archive/2009/06/20/inconvenient-accessibility-makes-self-documenting-code.aspx#comments</comments><description>&lt;p&gt;Intentional use of &lt;a href="http://msdn.microsoft.com/en-us/library/ms173121.aspx"&gt;access modifiers&lt;/a&gt; (public, private, etc.) is like a clear memo to your team. This came up during &lt;a href="http://unhandled-exceptions.com/blog/"&gt;Steve Bohlen&lt;/a&gt;&amp;#39;s &lt;a href="http://www.virtualaltnet.com/"&gt;Virtual Alt.Net&lt;/a&gt; talk on &lt;a href="http://en.wikipedia.org/wiki/Domain-driven_design"&gt;domain-driven design&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Steve explained the distinction between Entity objects, which have a unique identity independent of their properties (Even when I change my name, I&amp;#39;m still me.), and Value objects, which are defined by their properties (If you change the house number in an address, you have a new address.). When dealing with Entities, code should not be able to change the unique id&amp;mdash;that would be like someone claiming your social security number and thereby &lt;em&gt;becoming&lt;/em&gt; you. Therefore, Entity classes should have &lt;em&gt;private&lt;/em&gt; setters for their unique identifiers.&lt;/p&gt;
&lt;p&gt;A meeting attendee asked why, since this gets inconvenient when you&amp;#39;re creating an object based on a record fetched from the persistence repository. It&amp;#39;s a big pain; why bother? The analogy I would offer is this. When you&amp;#39;re defining a class to represent an Entity in your business domain, you know it&amp;#39;s an Entity. You intend for it to behave and be treated like an Entity. You don&amp;#39;t want any of your teammates setting its unique id in their code. So you send them an email: &amp;quot;Don&amp;#39;t set Person.UniqueId, okay?&amp;quot; Uh hunh. How well is &lt;em&gt;that&lt;/em&gt; going to work over time?&lt;/p&gt;
&lt;p&gt;Instead, if you simply don&amp;#39;t provide a public accessor to the UniqueId property, your teammates will get the message loud and clear. Granted, someone could edit the code and change the accessibility, but the fact that he or she needs to is a flashing neon sign saying &amp;quot;Stop. Think. Are you barking up the wrong tree?&amp;quot; You&amp;#39;ve made your code communicative. Its structure conveys your intent. No need for comments; this is an example of self-documenting code.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.dotnetkicks.com/kick/?title=Inconvenient+Accessibility+Makes+Self-Documenting+Code&amp;url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fsharoncichelli%2farchive%2f2009%2f06%2f20%2finconvenient-accessibility-makes-self-documenting-code.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.lostechies.com%2fblogs%2fsharoncichelli%2farchive%2f2009%2f06%2f20%2finconvenient-accessibility-makes-self-documenting-code.aspx" border="0" alt="Kick It on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=22300" width="1" height="1"&gt;</description><category domain="http://www.lostechies.com/blogs/sharoncichelli/archive/tags/DDD/default.aspx">DDD</category></item></channel></rss>