<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>HMK&#039;s Spurious Thoughts</title>
	<atom:link href="http://www.spuriousthoughts.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.spuriousthoughts.com</link>
	<description>Biased / Nicht immer ausgewogen</description>
	<lastBuildDate>Sat, 19 May 2012 18:30:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>The main benefits of TDD</title>
		<link>http://www.spuriousthoughts.com/2012/04/27/the-main-benefits-of-tdd/</link>
		<comments>http://www.spuriousthoughts.com/2012/04/27/the-main-benefits-of-tdd/#comments</comments>
		<pubDate>Fri, 27 Apr 2012 20:08:25 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.spuriousthoughts.com/?p=1516</guid>
		<description><![CDATA[For me, there are two main, long-term benefits of TDD (Test-Driven Development): First, by using TDD (thus writing the tests first) you make sure that your code remains in a testable state all the time (even if you don&#8217;t write all the tests to cover all the edge cases) &#8211; As anybody working with legacy [...]]]></description>
			<content:encoded><![CDATA[<p>For me, there are two main, long-term benefits of TDD (Test-Driven Development):</p>
<p>First, by using TDD (thus writing the tests first) you make sure that your code remains in a testable state all the time (even if you don&#8217;t write all the tests to cover all the edge cases) &#8211; As anybody working with legacy code can attest, adding unit tests to an existing code base is usually excruciatingly hard and takes a lot of time. It can be done &#8211;  witness <a href="http://www.amazon.com/gp/product/0131177052/">Working with Legacy Code</a>, sure, but it&#8217;s a very long and thorny journey. You don&#8217;t want to go down this road with the new code you&#8217;re writing every day.</p>
<p>Second, by using TDD you always have a decent, highly decoupled design &#8211; not a perfect or insanely great design, but quite a usable design to go forward. More often than not, it will be a better design than you&#8217;re used to.</p>
<p>&#8220;Test-Driven Development&#8221; is actually &#8220;Test-Driven Design&#8221;.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.spuriousthoughts.com/2012/04/27/the-main-benefits-of-tdd/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Where does &#8220;thinking&#8221; and &#8220;design&#8221; fit into the TDD picture?</title>
		<link>http://www.spuriousthoughts.com/2012/04/17/where-does-thinking-and-design-fit-into-the-tdd-picture/</link>
		<comments>http://www.spuriousthoughts.com/2012/04/17/where-does-thinking-and-design-fit-into-the-tdd-picture/#comments</comments>
		<pubDate>Tue, 17 Apr 2012 17:15:06 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.spuriousthoughts.com/?p=1501</guid>
		<description><![CDATA[I very much enjoyed @unclebobmartin&#8216;s generous talk at the Java User Group Karlsruhe last night. In addition to covering rockets, linear accelerators and small nuclear bombs as a means to overcome the gravitational field of the earth, he gave a great introductory talk on TDD and professionalism. Always a pleasure to be reminded on why [...]]]></description>
			<content:encoded><![CDATA[<p>I very much enjoyed <a href="http://twitter.com/uncluebobmartin">@unclebobmartin</a>&#8216;s generous talk at the <a href="http://jug-karlsruhe.mixxt.de/">Java User Group Karlsruhe</a> last night. In addition to covering rockets, linear accelerators and small nuclear bombs as a means to overcome the gravitational field of the earth, he gave a great introductory talk on TDD and professionalism. Always a pleasure to be reminded on why we are doing TDD in the first place.</p>
<p>One of the questions which came up during Q&#038;A &#8211; I&#8217;m paraphrasing here &#8211; was: </p>
<blockquote><p><cite>&#8220;I tried TDD and was told not to design or think, just to write the tests and the code. The result was a mess&#8221;.</cite></p></blockquote>
<p>Bob Martin&#8217;s answer was along these lines:</p>
<blockquote><p><cite>If you&#8217;re a TDD newbie, you need to leave your old rationale of thinking things through upfront behind. So the recommendation is &#8220;Don&#8217;t think about the design or what&#8217;s next&#8221;, but to methodically follow the mantra &#8220;Write some failing test&#8221; &#8211; &#8220;Write some code just so the test is satisfied&#8221; &#8211; &#8220;Write some failing test&#8221; &#8211; &#8220;Write some code just so the test is satisfied&#8221; &#8211; &#8230;. As your start to grok the rhythm of TDD, you gradually let your design skills in.</cite></p></blockquote>
<p>I would like to humbly elaborate on this answer. The practice of TDD consists of three simple steps:</p>
<ul>
<li>Step 1 &#8211; &#8220;Red&#8221; &#8211; Write some failing test
<li>Step 2 &#8211; &#8220;Green&#8221; &#8211; Write some code just so the test is satisfied (implement the simplest thing that could possibly work (not sure who coined the term, probably Ward Cunningham))
<li>Step 3 &#8211; &#8220;Refactor&#8221; &#8211; Remove all duplication from both your production and your test code</ul>
<p>Resist your urge to design upfront, to think through algorithmic solutions and alternatives. Just write a failing test. Then, write some code to make the test pass. Don&#8217;t write more code. Just the amount of code to make the test pass. </p>
<p>Now, turn to step 3. If you skip it, you will create a mess. </p>
<p>Step 3 is where your design skills are more than welcome. Apply your design skills to ruthlessly eliminate the duplication you created (and you did create some duplication because you did &#8220;the simplest thing that could possibly work&#8221; in step 2, didn&#8217;t you?) &#8211; Just keep in mind that you are not supposed to create a design which anticipates future requirement changes, you are supposed to ruthlessly eliminate duplication to create &#8220;the simplest design that could possibly work&#8221; for your current code base. </p>
<p>So there are a lot of design skills involved in TDD. It&#8217;s just that most of the design skills are applied &#8220;after the fact&#8221;. They are applied after you made the failing test pass. </p>
<p>There&#8217;s another place for design skills in TDD. Look at the first step &#8211; &#8220;Red&#8221;. You are supposed to write a failing test. You will probably need to instantiate an object (which, keep in mind, doesn&#8217;t exist yet). Or call a function or method (which don&#8217;t exist yet, either) on an existing object. You can apply your API design skills right there: What&#8217;s the best way to name the class or function? Which parameters do you need? How do you minimize the number of parameters? How do you make it easy for the test (and future users of the class / function) to accomplish the task at hand?</p>
<p>You aren&#8217;t convinced yet? You still need more places to apply your superior brain powers? Good news, there&#8217;s even more &#8220;thinking&#8221; involved. In step 1, you are supposed to write a failing test. This requires a lot of thinking:</p>
<ul>
<li>What do I test next?
<li>What&#8217;s the next logical step in the evolution of my method / class?
<li>What are the edge cases I need to test for?
<li>Which test will small enough in scope that I can cope with the implementation right away?
<li>Which test will bring me closer to the solution of the task i&#8217;m working on?</ul>
<p><b>Conclusion</b></p>
<p>If you follow TDD and apply your thinking and design skills as described above, you will end up with a testable, highly decoupled design. It&#8217;s not a great design yet, but chances are it&#8217;ll be a much better and more usable design than the ones you&#8217;ve encountered so far.</p>
<p><b>Addendum</b></p>
<p>You may wonder why I didn&#8217;t mention the long and hard thoughts you need to think in step 2 while writing the code to make the test pass. Two questions for you: You did write some failing test, just enough testing code so the test fails, correct? Then you did the simplest thing that could possibly work to make the test pass, correct? Nothing more? Good. Go figure.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.spuriousthoughts.com/2012/04/17/where-does-thinking-and-design-fit-into-the-tdd-picture/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Softwerkskammer Karlsruhe, 6th Meeting</title>
		<link>http://www.spuriousthoughts.com/2012/02/29/softwerkskammer-karlsruhe-6th-meeting/</link>
		<comments>http://www.spuriousthoughts.com/2012/02/29/softwerkskammer-karlsruhe-6th-meeting/#comments</comments>
		<pubDate>Wed, 29 Feb 2012 22:42:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.spuriousthoughts.com/?p=1461</guid>
		<description><![CDATA[Finally, I managed to attend a meeting of the Softwerkskammer Karlsruhe, a group of software professionals dedicated to improving their craft. Todays topic was Flow Design and Event Based Components, a presentation graciously provided by Tilmann Kuhn. He gave a short overview of Flow Design and then dove into a sample implementation using Event Based [...]]]></description>
			<content:encoded><![CDATA[<p>Finally, I managed to attend a meeting of the <a href="http://groupspaces.com/softwerkskammer">Softwerkskammer</a> Karlsruhe, a group of software professionals dedicated to improving their craft. Todays topic was <a href="http://clean-code-advisors.com/ressourcen/flow-design-ressourcen">Flow Design</a> and Event Based Components, a presentation graciously provided by <a href="http://www.object-zoo.net">Tilmann Kuhn</a>. He gave a short overview of Flow Design and then dove into a sample implementation using Event Based Components in Java (a language I used to be more familiar with in the 90s). Java&#8217;s (and the associated frameworks&#8217;) verboseness aside, flow design and its implementation very much reminded me of <a href="http://en.wikipedia.org/wiki/Prograph">Prograph CPX</a>, a graphical data flow language of the early 90s. In order to close the daunting gap between the flow design&#8217;s graphical representation and its textual implementation an integrated IDE is (IMHO) essential.</p>
<p>Then, Hayati Ayguen presented his take of a flow implementation in C++ for signal processing. Terse. Brief. Very focussed on a specific use case &#8211; Signal processing. Just enough infrastructure to make it work efficiently. A wonderful contrast to the Java implementation &#8211; which does have its merits, don&#8217;t get me wrong.</p>
<p>A great and thought provoking evening. Thanks to the organizers. I look forward to participate in upcoming meetings.</p>
<p>[Update 3/2/12 - Fixed up an incomplete sentence - Looks like it was way to late Wednesday night (or I got distracted by the late night soccer game analysis on TV <img src='http://www.spuriousthoughts.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> ]</p>
]]></content:encoded>
			<wfw:commentRss>http://www.spuriousthoughts.com/2012/02/29/softwerkskammer-karlsruhe-6th-meeting/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Thoughtworks Event, Frankfurt</title>
		<link>http://www.spuriousthoughts.com/2011/10/18/thoughtworks-event-frankfurt/</link>
		<comments>http://www.spuriousthoughts.com/2011/10/18/thoughtworks-event-frankfurt/#comments</comments>
		<pubDate>Tue, 18 Oct 2011 18:43:42 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.spuriousthoughts.com/?p=1369</guid>
		<description><![CDATA[Last night, Thoughtworks was hosting an public event @ Japan Center, Frankfurt &#8211; right next to the EZB and Deutsche Bank headquarters (I sure hope that those buildings were filled with busy &#038; smart people working on setting things straight with the Euro). 18:45 &#8211; Welcome by Nick Ashley, MD of ThoughtWorks Deutschland 19:00 &#8211; [...]]]></description>
			<content:encoded><![CDATA[<p>Last night, <a href="http://www.thoughtworks.com/">Thoughtworks</a> was hosting an public event @ Japan Center, Frankfurt &#8211; right next to the EZB and Deutsche Bank headquarters (I sure hope that those buildings were filled with busy &#038; smart people working on setting things straight with the Euro).</p>
<ul>
<li>18:45 &#8211; Welcome by Nick Ashley, MD of ThoughtWorks Deutschland</li>
<li>19:00 &#8211; Wolf Schlegel: &#8220;Dos and don&#8217;ts of Continuous Integration and Delivery&#8221;</li>
<li>19.20 &#8211; Erik Dörnenburg: &#8220;Lean for enterprise architecture</li>
<li>19:45 &#8211; Martin Fowler: &#8220;Software Design in the 21st Century&#8221;</li>
<li>20:30 &#8211; Networking &#8211; drinks and food</li>
</ul>
<p>Unfortunately, I missed about half of Wolf Schlegel&#8217;s talk on Continous Delivery, but judging on the second half, I would have preferred more in-depth discussion of technologies and best practices. The talk seemed like a space-station&#8217;s eye view of the topic.</p>
<p><a href="http://twitter.com/erikdoe">Erik Dörnenburg</a> was next talking about Lean Enterprise Architecture. I very much liked his analogy of comparing the role of a Software Architect to that of a Gardener instead of a traditional Architect. Spot on. Quite a few interesting thoughts on how to causing change in an organisation / team, too.</p>
<p><a href="http://twitter.com/martinfowler">Martin Fowler</a> gave two short talks, on on &#8220;<a href="http://martinfowler.com/dsl.html">Domain Specific Languages</a>&#8221; and one on &#8220;<a href="http://martinfowler.com/articles/nonDeterminism.html">Nondeterministic Tests</a>&#8220;.</p>
<p>I was quite keen on the Domain Specific Language part, as we&#8217;re currently moving away from a &#8220;home-grown&#8221; Domain Specific Language for NC-code templating &#038; output to a Python-based solution as we found that our own language lacked the expressiveness we are looking for. My key take-away was that there are two ways to create a DSL, external &#038; internal and that we&#8217;re migrating from an external DSL to an internal DSL. Looks like the DSL book is supposed to be on my reading list real soon now.</p>
<p>Martin&#8217;s thoughts on &#8220;Nondeterministic Tests&#8221; were especially interesting as I was attending a talk on <a href="http://www.spuriousthoughts.com/2011/10/10/objektforum-karlsruhe-testen-in-der-konkurrenz-situation-trotz-nebenlaufigkeit-erfolgreich-unit-tests-schreiben/">&#8220;Unit Testing &#038; Concurrency&#8221;</a> right last week in Karlsruhe. Very interesting to see the different takes on the topic &#8211; Abstracting away the concurrency altogether for unit testing purposes whereas Martin was leaning towards integration &#038; acceptance testing and giving very sound advice on how to deal with concurrency issues within the tests (polling, callbacks, test doubles).</p>
<p>As you might have imagined, I mostly skipped the Networking part due to my sociophobia.</p>
<p>Overall, a very worthwhile evening and I very much look forward to future Thoughtworks events.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.spuriousthoughts.com/2011/10/18/thoughtworks-event-frankfurt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Objektforum Karlsruhe &#8211; &#8220;Trotz Nebenläufigkeit erfolgreich Unit Tests schreiben&#8221;</title>
		<link>http://www.spuriousthoughts.com/2011/10/10/objektforum-karlsruhe-testen-in-der-konkurrenz-situation-trotz-nebenlaufigkeit-erfolgreich-unit-tests-schreiben/</link>
		<comments>http://www.spuriousthoughts.com/2011/10/10/objektforum-karlsruhe-testen-in-der-konkurrenz-situation-trotz-nebenlaufigkeit-erfolgreich-unit-tests-schreiben/#comments</comments>
		<pubDate>Mon, 10 Oct 2011 20:54:57 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.spuriousthoughts.com/?p=1356</guid>
		<description><![CDATA[Ein wirklich interessanter Vortrag mit einer nur auf den ersten Blick überraschenden Erkenntnis: Wie erstellt man Unit Tests für nebenläufige Funktionen? Man testet nicht die Nebenläufigkeit. Man abstrahiert von der Nebenläufigkeit, das heißt man erstellt das System so, daß nebenläufige Funktionen über abstrakte Interfaces beschrieben werden. Die nachfolgende Diskussion zeigte wieder einmal, daß der Informatiker [...]]]></description>
			<content:encoded><![CDATA[<p>Ein wirklich interessanter <a href="http://www.andrena.de/veranstaltungen/testen-in-der-konkurrenz-situation-trotz-nebenlaeufigkeit-erfolgreich-unit-tests-sch">Vortrag</a> mit einer nur auf den ersten Blick überraschenden Erkenntnis:</p>
<p>Wie erstellt man Unit Tests für nebenläufige Funktionen? Man testet nicht die Nebenläufigkeit. Man abstrahiert von der Nebenläufigkeit, das heißt man erstellt das System so, daß nebenläufige Funktionen über abstrakte Interfaces beschrieben werden.</p>
<p>Die nachfolgende Diskussion zeigte wieder einmal, daß der Informatiker an sich nicht einer der Flexibelsten oder Lernfähigsten ist (*). Anmerkungen wie: &#8220;Damit testen Sie aber nicht die Aspekte X und Y&#8221;, &#8220;Das ist bei uns so nicht einsetzbar, weil X&#8221; oder &#8220;Bei uns liegt aber Z vor, daher können wir nicht&#8230;&#8221; zeigten, das einige Kollegen wieder exakt die Argumente aufwärmten, die sie in den letzten 10 Jahren  bereits (erfolglos) gegen die Konzepte beim Unit-Testing von Benutzerschnittstellen, Datenbankzugriffen, Netzwerkdiensten und anderem vorgebracht hatten:</p>
<h4>Wie erstellt man Unit Tests für Benutzerschnittstellen?</h4>
<p>Man testet nicht die Benutzerschnittstelle. Man abstrahiert von der eigentlichen Benutzerschnittstelle, indem man beispielsweise MVP (Model View Presenter) nutzt.</p>
<h4>Wie erstellt man Unit Tests für die Datenbank?</h4>
<p>Man testet nicht die Datenbank. Man abstrahiert von den eigentlichen Datenbankzugriffen, indem man diese in eine eigene, möglichst einfache Mapping-Schicht auslagert.</p>
<h4>Wie erstellt man Unit Tests für Netzwerkdienste?</h4>
<p>Man testet nicht die Netzwerkdienste. Man abstrahiert von den Netzwerkdiensten, indem man diese durch abstrakte Interfaces beschreibt.</p>
<p>Um zwei weitere Beispiele aus der täglichen Praxis der extragroup GmbH zu bringen:</p>
<h4>Wie erstellt man Unit Tests für das Erstellen von Objekten in einem CAD-System?</h4>
<p>Man testet nicht das Erstellen der Objekte. Man abstrahiert vom Erstellen der CAD-Objekte, indem das eigentliche Erstellen der CAD-Objekte in eine möglichst einfache Klasse auslagert &#8211; die man im schlimmsten Falle über ein abstraktes Interface beschreibt.</p>
<h4>Wie erstellt man Unit Tests für das Erstellen von Werkzeugen in einem CAD-System?</h4>
</p>
<p>Man testet nicht das Verhalten der Werkzeuge. Man abstrahiert vom den CAD-Werkzeugen, indem die eigentliche Schnittstelle zum API des CAD-System durch ein abstraktes Interface beschreibt.</p>
<p>Der geneigte Leser wird sicher inzwischen ein Muster erkannt haben.</p>
<p>Die entscheidende Erkenntnis (für uns wie für die oben genannten Kollegen) ist, daß all dies nur mit testgetriebener Entwicklung sauber möglich ist. Unit Tests nachträglich zu einem System hinzuzufügen, welches nicht auf solche Tests ausgelegt ist, erweist sich in der Praxis als enorm aufwendig.</p>
<p>(*) Ich zähle mich selbstverständlich auch zu genau dieser Gruppe, die neuen Ideen mit einem gezielten &#8220;Das funktioniert nicht, weil&#8230;.&#8221; begegnet.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.spuriousthoughts.com/2011/10/10/objektforum-karlsruhe-testen-in-der-konkurrenz-situation-trotz-nebenlaufigkeit-erfolgreich-unit-tests-schreiben/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My brief Steve Jobs encounter</title>
		<link>http://www.spuriousthoughts.com/2011/10/06/my-brief-steve-jobs-encounter/</link>
		<comments>http://www.spuriousthoughts.com/2011/10/06/my-brief-steve-jobs-encounter/#comments</comments>
		<pubDate>Thu, 06 Oct 2011 20:55:18 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>

		<guid isPermaLink="false">http://www.spuriousthoughts.com/?p=1343</guid>
		<description><![CDATA[December 1996 Apple Computer announced that it had acquired NeXT, Inc. for about $400M. January 1997 We had been working our asses off for about 3 years to get our OpenDoc-based database components to a usable and sellable state. Together with a band of other OpenDoc developers, we intended to make a big splash at [...]]]></description>
			<content:encoded><![CDATA[<h3>December 1996</h3>
<p>Apple Computer announced that it had acquired NeXT, Inc. for about $400M.</p>
<h3>January 1997</h3>
<p>We had been working our asses off for about 3 years to get our OpenDoc-based database components to a usable and sellable state. Together with a band of other OpenDoc developers, we intended to make a big splash at MacWorld 1997, San Francisco. And a reasonable splash we made. Customer were excited about our products, other developers were excited about interfacing to our components and international Distributors were lining up to localize &#038; sell our components.</p>
<p>Members of the Apple Enterprise Sales team (yup, back then there was such a thing) had been arranging a meeting at NeXT headquarters with a couple of NeXT engineers for us to promote our components and to get a feeling for where thing are heading. I do vividly remember sitting in a conference room in Redwood city with several NeXT engineers, among them a rather young opinionated guy named Scott Forstall, and the NeXT engineers basically dismissing the idea of loosely coupled, componentized software.</p>
<h3>March 1997</h3>
<p>On March, 14th, Apple Computer was putting OpenDoc into maintenance mode &#8211; which was the marketing weasels way of saying that the platform our product was based on was dead in the water. We were devastated &#8211; For three years, we had been pouring our heart, soul and last, but not least, a lot of our personal money into the product and it was dead.</p>
<p>CeBIT, the world largest computer fair, was upon us and, despite Apple&#8217;s announcement about OpenDoc&#8217;s demise, we were scheduled to show our OpenDoc components at the Apple booth in Hannover. We didn&#8217;t go.</p>
<p>Mark B. Johnson, a fine man and head of European developer relations back then, called us and expressed his hope that, despite the OpenDoc debacle, we would support the Apple platform going forward. He offered us WWDC tickets so we could talk to Apple engineers and get a glimpse on where Apple was heading in the future.</p>
<h3>May 1997</h3>
<p>WWDC was in San Jose Convention Center back then. I do remember sitting in the main hall next to <a href="http://twitter.com/#!/BradHutchings">@BradHutchings</a> during Friday&#8217;s Q&#038;A session. I&#8217;m not 100% sure, but I think it was Brad who was asking the infamous question &#8220;What about OpenDoc?&#8221; at the very beginning of the Q&#038;A session (about 4:30min into the video).</p>
<p>It wasn&#8217;t fun. Steve&#8217;s answer was frank, to the point and, in hindsight, spot on &#8211; but see for yourself:</p>
<p><iframe width="420" height="315" src="http://www.youtube.com/embed/GnO7D5UaDig" frameborder="0" allowfullscreen></iframe></p>
<p>Rest in peace, Steve. I&#8217;ve learned an awful lot from you over the years.</p>
<p>And now I&#8217;m off pre-ordering an iPhone 4S for both me &#038; my oldest daughter.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.spuriousthoughts.com/2011/10/06/my-brief-steve-jobs-encounter/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Developing a Vectorworks 2011 tool plug-in, TDD-style &#8211; Episode 4</title>
		<link>http://www.spuriousthoughts.com/2011/10/03/developing-a-vectorworks-2011-tool-plug-in-tdd-style-episode-4/</link>
		<comments>http://www.spuriousthoughts.com/2011/10/03/developing-a-vectorworks-2011-tool-plug-in-tdd-style-episode-4/#comments</comments>
		<pubDate>Mon, 03 Oct 2011 18:53:34 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Vectorworks]]></category>

		<guid isPermaLink="false">http://www.spuriousthoughts.com/?p=1333</guid>
		<description><![CDATA[Now that we&#8217;re able to create real Vectorworks geometry with our tool, what&#8217;s next? The &#8220;spec&#8221; laid out in Episode 0 calls for creating a red or green line depending on where the user sets the clicks. Tackling the click&#8217;s location test first sounds like an interesting challenge. What&#8217;s the simplest way to start? If [...]]]></description>
			<content:encoded><![CDATA[<p>Now that we&#8217;re able to create real Vectorworks geometry with our tool, what&#8217;s next? The &#8220;spec&#8221; laid out in <a href="http://www.spuriousthoughts.com/2011/06/02/developing-a-v…tyle-episode-0/">Episode 0</a> calls for creating a red or green line depending on where the user sets the clicks. Tackling the click&#8217;s location test first sounds like an interesting challenge.</p>
<p>What&#8217;s the simplest way to start? If the user doesn&#8217;t click on a polygon object, our tool should ignore the clicks. How does <tt>RedGreenLineTool</tt> know if the clicks happen on a polygon object? For know, we let it know by calling <tt>MouseOverPolygonObject()</tt> before adding tool points. Sounds reasonable.</p>
<pre class="brush: cpp; title: ; notranslate">
TEST_N(ToolPointsShouldBeReflectedAsStartEndPointOfLineObject)
{
	MockRedGreenLineTool vwTool;
	vwTool.MouseOverPolygonObject();

	vwTool.AddPoint(WorldPt3(0, 0, 0));
	vwTool.AddPoint(WorldPt3(50, 0, 0));

	CHECK_EQUAL(2, vwTool.GetNumToolPoints());
}
</pre>
<p>If we don&#8217;t call <tt>MouseOverPolygonObject()</tt> before adding points, they shouldn&#8217;t be added to the list of points tracked.</p>
<pre class="brush: cpp; title: ; notranslate">
TEST_N(ToolPointNotOnPolygonShouldBeIgnored)
{
	MockRedGreenLineTool vwTool;

	vwTool.AddPoint(WorldPt3(0, 0, 0));
	vwTool.AddPoint(WorldPt3(50, 0, 0));

	CHECK_EQUAL(0, vwTool.GetNumToolPoints());
}
</pre>
<p>Implementation, of course, is rather trivial (for now <img src='http://www.spuriousthoughts.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> . We just add a <tt>bool fMockMouseOverPolygonObject</tt> to <tt>MockRedGreenLineTool</tt>, set it <tt>MouseOverPolygonObject()</tt>, test it in <tt>AddPoint()</tt> and we&#8217;re done. </p>
<p>Well, not really. We do have an implementation for <tt>MockRedGreenLineTool</tt> only, we need to move the implementation up the inheritance tree to <tt>RedGreenLineTool</tt> to turn it into something useful.</p>
<pre class="brush: cpp; title: ; notranslate">
class RedGreenLineTool {

	virtual bool IsMouseOverPolygonObject() = 0;

	void AddPoint(const WorldPt3&amp; p) {
		if (IsMouseOverPolygonObject())
			fToolPoints.PushData(p);
	}
};
</pre>
<p>Implementation of <tt>IsMouseOverPolygonObject()</tt> is rather trivial for <tt>MockRedGreenLineTool</tt>, we just return <tt>fMockMouseOverPolygonObject</tt>. Of course, <tt>VectorworksRedGreenLineTool</tt> needs a more sophisticated implementation, but (as intended) a rather simple one:</p>
<pre class="brush: cpp; title: ; notranslate">
class VectorworksRedGreenLineTool {

	virtual bool IsMouseOverPolygonObject() {
		MCObjectHandle overObject = NULL;
		short overPart;
		long code;
		gSDK-&gt;TrackTool(overObject, overPart, code);

		return (overObject &amp;&amp; ! VWPolygon2DObj::IsPolygon2DObject(overObject));
	}
};
</pre>
<p>Now this rather straightforward implementation doesn&#8217;t quite work yet, as this code doesn&#8217;t reflect the state Vectorworks is in. every mouse click is registered by Vectorworks first, then an event is sent to the tool to process it. If we choose to ignore the mouse click, we need to notify Vectorworks of this fact. Thus, we need to make some minor changes to the code to accommodate for this behavior. </p>
<pre class="brush: cpp; title: ; notranslate">
class RedGreenLineTool {

	virtual void PopLastToolPoint() = 0;

	void AddPoint(const WorldPt3&amp; p) {
		if (IsMouseOverPolygonObject())
			fToolPoints.PushData(p);
		else
			PopLastToolPoint();
	}
};
</pre>
<p>While <tt>MockRedGreenLineTool</tt> gets away with an empty implementation for <tt>PopLastToolPoint()</tt>, <tt>VectorworksRedGreenLineTool</tt> needs to notify Vectorworks that the last tool point registered should be removed:</p>
<pre class="brush: cpp; title: ; notranslate">
class VectorworksRedGreenLineTool {

	virtual void PopLastToolPoint() {
		gSDK-&gt;PopLastToolPt();
	}
};
</pre>
<p>Where are we at? We do have a basic implementation of mouse tracking in place. <tt>RedGreenLineTool</tt> is able to tell if the mouse is over a polygon object while the mouse is clicked. In the next episode, we will tackle tracking mouse clicks on a single or two different polygons in order to create red or green lines.</p>
<p><a href="http://www.spuriousthoughts.com/2011/07/22/developing-a-vectorworks-2011-tool-plug-in-tdd-style-episode-3/">Previous Episode</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.spuriousthoughts.com/2011/10/03/developing-a-vectorworks-2011-tool-plug-in-tdd-style-episode-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Developing a Vectorworks 2011 tool plug-in, TDD-style &#8211; Episode 3</title>
		<link>http://www.spuriousthoughts.com/2011/07/22/developing-a-vectorworks-2011-tool-plug-in-tdd-style-episode-3/</link>
		<comments>http://www.spuriousthoughts.com/2011/07/22/developing-a-vectorworks-2011-tool-plug-in-tdd-style-episode-3/#comments</comments>
		<pubDate>Fri, 22 Jul 2011 19:16:19 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Vectorworks]]></category>

		<guid isPermaLink="false">http://www.spuriousthoughts.com/?p=1256</guid>
		<description><![CDATA[With quite a sound class structure in place (and after returning from a refreshing summer vacation in Turkey), let&#8217;s see if we can put our new class strcuture to good use while trying to create the actual Vectorworks geometry (a line), test first &#8211; of course. Reading through the first series on TDD with Vectorworks, [...]]]></description>
			<content:encoded><![CDATA[<p>With quite a sound class structure in place (and after returning from a refreshing summer vacation in Turkey), let&#8217;s see if we can put our new class strcuture to good use while trying to create the actual Vectorworks geometry (a line), test first &#8211; of course. Reading through the first series on TDD with Vectorworks, we used a model object for representing the geometric properties of the object and a rather thin layer to create the actual Vectorworks geometry from the model. How about trying this approach with a Vectorworks tool plug-in, too?</p>
<pre class="brush: cpp; title: ; notranslate">
TEST_N(ToolPointsShouldBeReflectedAsStartEndPointOfLineObject)
{
	MockRedGreenLineTool vwTool;

	vwTool.AddPoint(WorldPt3(0, 0, 0));
	vwTool.AddPoint(WorldPt3(50, 0, 0));

	MockRedGreenLineObject* vwObject = vwTool.Create();

	CHECK_EQUAL(WorldPt3(0, 0, 0), vwObject-&gt;GetStartPoint());
	CHECK_EQUAL(WorldPt3(50, 0, 0), vwObject-&gt;GetEndPoint());

	delete vwObject;
}
</pre>
<p>We expect that the tool object will be able to create the line object for us and that the tool will take care of making sure that the start &#038; end point of the line object will reflect the tool points.</p>
<p>In order to get the test to compile, we need to implement <tt>Create()</tt> for <tt>MockRedGreenLineTool</tt>.</p>
<pre class="brush: cpp; title: ; notranslate">
class MockRedGreenLineTool : public RedGreenLineTool {

public:

	MockRedGreenLineObject* Create() const {
		MockRedGreenLineObject* lineObject = new MockRedGreenLineObject();

		lineObject-&gt;SetStartPoint(fToolPoints[0].fPoint);
		lineObject-&gt;SetEndPoint(fToolPoints[1].fPoint);

		return lineObject;
	}		

};
</pre>
<p>Now we need to come up with a simple implementation for <tt>MockRedGreenLineObject</tt>. Not a lot to see here &#8211; just a mock implementation.</p>
<pre class="brush: cpp; title: ; notranslate">
class MockRedGreenLineObject {

public:

	void SetStartPoint(const WorldPt3&amp;amp;amp; p) {
		fStartPoint = p;
	}

	void SetEndPoint(const WorldPt3&amp;amp;amp; p) {
		fEndPoint = p;
	}

	virtual WorldPt3 GetStartPoint() const {
		return fStartPoint;
	}

	virtual WorldPt3 GetEndPoint() const {
		return fEndPoint;
	}

private:

	WorldPt3 fStartPoint;
	WorldPt3 fEndPoint;
};
</pre>
<p>Now the code compiles, links and the test passes. As in episode 1, the code is stuck in the &#8220;Mock&#8221; classes, but we need to drive it from Vectorworks. Let&#8217;s refactor us out of this mess.</p>
<p>First, we push the implementation of <tt>Create()</tt> up to the base class, <tt>RedGreenLineTool</tt>. However, <tt>RedGreenLineTool::Create()</tt> shouldn&#8217;t return an instance of <tt>MockRedGreenLineObject</tt>, but an instance of a more generic RedGreenLineObject class in order to accommodate creation of a Vectorworks-specific subclass. Creation of the particular instance is left to the subclasses of <tt>RedGreenLineTool</tt>.</p>
<p>We move the code from <tt>MockRedGreenLineObject</tt> to a new superclass <tt>RedGreenLineObject</tt>.</p>
<pre class="brush: cpp; title: ; notranslate">
class RedGreenLineObject {

public:

	void SetStartPoint(const WorldPt3&amp;amp;amp; p) {
		fStartPoint = p;
	}

	void SetEndPoint(const WorldPt3&amp;amp;amp; p) {
		fEndPoint = p;
	}

	virtual WorldPt3 GetStartPoint() const {
		return fStartPoint;
	}

	virtual WorldPt3 GetEndPoint() const {
		return fEndPoint;
	}

private:

	WorldPt3 fStartPoint;
	WorldPt3 fEndPoint;
};
</pre>
<p>Code still compiles, links and passes the tests. Now for the surgery concerning <tt>RedGreenLineTool::Create()</tt>:</p>
<pre class="brush: cpp; title: ; notranslate">
class VectorworksRedGreenLineTool : public RedGreenLineTool {

	RedGreenLineObject* CreateRedGreenLineObject() const {
		return VectorworksRedGreenLineObject();
	}
};

class MockRedGreenLineTool : public RedGreenLineTool {

	RedGreenLineObject* CreateRedGreenLineObject() const {
		return MockRedGreenLineObject();
	}
};

class RedGreenLineTool {

public:

	RedGreenLineObject* CreateRedGreenLineObject() const = 0;

	RedGreenLineObject* Create() const {
		RedGreenLineObject* lineObject = CreateRedGreenLineObject();

		lineObject-&gt;SetStartPoint(fToolPoints[0].fPoint);
		lineObject-&gt;SetEndPoint(fToolPoints[1].fPoint);

		return lineObject;
	}		

};
</pre>
<p>Again, code compiles, links and our tests pass. What&#8217;s left? We need to hook up the classes to <tt>CTool_EventSink</tt> and create the Vectorworks geometry.</p>
<pre class="brush: cpp; title: ; notranslate">
long CTool_EventSink::LegacyMain(long action, long message1, long message2)
{
	long result = 0;

	switch (action) {

		case kToolHandleComplete:
			fRedGreenLineTool-&gt;Create();
			break;
	}
};
</pre>
<p>Compiles, links. No surprises here. We start Vectorworks, select our tool, click twice to create a line &#8211; but nothing happens&#8230;.yet. Ah, we forgot to create the geometry. How to do that? Here&#8217;s the simplest way of doing it which comes to my mind:</p>
<pre class="brush: cpp; title: ; notranslate">
class RedGreenLineTool {

public:

	RedGreenLineObject* Create() const {
		RedGreenLineObject* lineObject = CreateRedGreenLineObject();

		lineObject-&gt;SetStartPoint(fToolPoints[0].fPoint);
		lineObject-&gt;SetEndPoint(fToolPoints[1].fPoint);

		lineObject-&gt;CreateGeometry();

		return lineObject;
	}		

};
</pre>
<p>Of course, the implementation of <tt>CreateGeometry()</tt> in <tt>MockRedGreenLineObject</tt> will be empty, whereas <tt>VectorworksRedGreenLineObject::CreateGeometry()</tt> is somewhat beefier:</p>
<pre class="brush: cpp; title: ; notranslate">
class VectorworksRedGreenLineObject {

	virtual void CreateGeometry() {
		VWLine2DObj line(fStartPoint.x, fStartPoint.y, fEndPoint.x, fEndPoint.y);
		line.AddObjectToContainer(gSDK-&gt;GetDefaultContainer());
	}

};
</pre>
<p>We can easily deal with the non-testability of <tt>CreateGeometry()</tt>, as all the logic of the line object&#8217;s &#8220;model&#8221; itself is under test. And if something goes horribly wrong in <tt>CreateGeometry()</tt>, it should be easy to figure out.</p>
<p><tt>RedGreenLineObject</tt> doesn&#8217;t feature an awful lot of sophisticated logic so far, but we are not done yet. The &#8220;spec&#8221; calls for creating a red or green line depending on where the user sets the clicks. Sounds like this attribute will find a good home in the <tt>RedGreenLineObject</tt> class. Speaking of it, determining the location of the clicks test first sounds like an interesting challenge. Let&#8217;s try to tackle that one in the next episode.</p>
<p><a href="http://www.spuriousthoughts.com/2011/06/17/developing-a-vectorworks-2011-tool-plug-in-tdd-style-episode-2/">Previous Episode</a> | <a href="http://www.spuriousthoughts.com/2011/10/03/developing-a-vectorworks-2011-tool-plug-in-tdd-style-episode-4/">Next Episode</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.spuriousthoughts.com/2011/07/22/developing-a-vectorworks-2011-tool-plug-in-tdd-style-episode-3/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>This is why&#8230;</title>
		<link>http://www.spuriousthoughts.com/2011/07/17/this-is-why/</link>
		<comments>http://www.spuriousthoughts.com/2011/07/17/this-is-why/#comments</comments>
		<pubDate>Sun, 17 Jul 2011 12:49:18 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>

		<guid isPermaLink="false">http://www.spuriousthoughts.com/?p=1249</guid>
		<description><![CDATA[&#8230;I opt for moving to Turkey:]]></description>
			<content:encoded><![CDATA[<p>&#8230;I opt for moving to Turkey:</p>
<p><img style="display:block; margin-left:auto; margin-right:auto;" src="http://www.spuriousthoughts.com/wp-content/uploads/2011/07/vergleich.jpg" alt="Vergleich" border="0" width="600" height="450" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.spuriousthoughts.com/2011/07/17/this-is-why/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Developing a Vectorworks 2011 tool plug-in, TDD-style &#8211; Episode 2</title>
		<link>http://www.spuriousthoughts.com/2011/06/17/developing-a-vectorworks-2011-tool-plug-in-tdd-style-episode-2/</link>
		<comments>http://www.spuriousthoughts.com/2011/06/17/developing-a-vectorworks-2011-tool-plug-in-tdd-style-episode-2/#comments</comments>
		<pubDate>Fri, 17 Jun 2011 21:18:50 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Vectorworks]]></category>

		<guid isPermaLink="false">http://www.spuriousthoughts.com/?p=1227</guid>
		<description><![CDATA[With a basic mock implementation of the tool point collecting part of a Vectorworks tool under our belt, let&#8217;s try to connect this class to a &#8220;real&#8221; Vectorworks tool event sink. Using the MockRedGreenLineTool from within a CTool_EventSink doesn&#8217;t sound quite right. After all it&#8217;s supposed to be a mock implementation. We need to use [...]]]></description>
			<content:encoded><![CDATA[<p>With a <a href="http://www.spuriousthoughts.com/2011/06/08/developing-a-vectorworks-2011-tool-plug-in-tdd-style-episode-1/">basic mock implementation</a> of the tool point collecting part of a Vectorworks tool under our belt, let&#8217;s try to connect this class to a &#8220;real&#8221; Vectorworks tool event sink.</p>
<p>Using the <tt>MockRedGreenLineTool</tt> from within a <tt>CTool_EventSink</tt> doesn&#8217;t sound quite right. After all it&#8217;s supposed to be a mock implementation. We need to use a real tool implementation in the <tt>CTool_EventSink</tt>. Let&#8217;s do some restructuring to accomplish that. First, create a new class <tt>RedGreenLineTool</tt> with the code from <tt>MockRedGreenLineTool</tt>.</p>
<pre class="brush: cpp; title: ; notranslate">
class RedGreenLineTool {

public:

	virtual ~RedGreenLineTool() {
	}

 	void AddPoint(const WorldPt3&amp;amp;amp;amp; p) {
		fToolPoints.PushData(p);
	}	

	virtual void PopPoint() {
		fToolPoints.PopData();
	}

	short GetNumToolPoints() const {
		return fToolPoints.NumItems();
	}

	TSmallArray&lt;WorldPt3&gt; fToolPoints;

};
</pre>
<p>Now, make <tt>MockRedGreenLineTool</tt> a subclass of <tt>RedGreenLineTool</tt>:</p>
<pre class="brush: cpp; title: ; notranslate">
class MockRedGreenLineTool : public RedGreenLineTool {
}
</pre>
<p>and create <tt>VectorworksRedGreenLineTool</tt>, which is also a subclass of <tt>RedGreenLineTool</tt>.</p>
<pre class="brush: cpp; title: ; notranslate">
class VectorworksRedGreenLineTool : public RedGreenLineTool {
}
</pre>
<p>This sure looks better to our TDD newbie eye. We have a common implementation for both the <tt>MockRedGreenLineTool</tt> used for testing and a <tt>VectorworksRedGreenLineTool</tt> used to connect the code to Vectorworks. Running the tests shows we didn&#8217;t break anything. Now we are able to use <tt>VectorworksRedGreenLineTool</tt> in a <tt>VWToolDefaultLine_EventSink</tt> implementation:</p>
<pre class="brush: cpp; title: ; notranslate">
long CTool_EventSink::LegacyMain(long action, long message1, long message2)
{
	long result = 0;

	switch (action) {

		case kToolDoSetup:
			result = VWToolDefaultLine_EventSink::LegacyMain(action, message1, message2);

			fRedGreenLineTool = new VectorworksRedGreenLineTool();
			break;

		case kToolDoSetDown:
			result = VWToolDefaultLine_EventSink::LegacyMain(action, message1, message2);

			if (fRedGreenLineTool)
				delete fRedGreenLineTool;
			fRedGreenLineTool = NULL;
			break;

		case kToolPointAdded: {

			WorldPt3 toolPoint;
			if (gSDK-&gt;GetToolPt3D(gSDK-&gt;GetNumToolPts() - 1, toolPoint))
				fRedGreenLineTool-&gt;AddPoint(toolPoint);
			break;
		}

		case kToolPointRemoved:
			fRedGreenLineTool-&gt;PopPoint();
			break;

		default:
			result = VWToolDefaultLine_EventSink::LegacyMain(action, message1, message2);
			break;

	}

	return result;
}
</pre>
<p>Using the debugger, we are able to verify that everything is working out as expected.</p>
<p>Not a lot of functional but structural code changes in this episode, but we ended up with a class hierarchy which hints at things to come. We expect to push code common between the mock and Vectorworks implementation of the tool up the class hierarchy and code specific to the mock or Vectorworks implementation of the tool in the subclasses.</p>
<p>Let&#8217;s see how this class hierarchy holds up in the next episode when we tackle creating a line &#8211; test first, of course.  </p>
<p><a href="http://www.spuriousthoughts.com/2011/06/08/developing-a-vectorworks-2011-tool-plug-in-tdd-style-episode-1/">Previous Episode</a> | <a href="http://www.spuriousthoughts.com/2011/07/22/developing-a-vectorworks-2011-tool-plug-in-tdd-style-episode-3/">Next Episode</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.spuriousthoughts.com/2011/06/17/developing-a-vectorworks-2011-tool-plug-in-tdd-style-episode-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

