<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4809508800731778132</id><updated>2012-01-26T19:41:53.898-08:00</updated><category term='MicroTip'/><category term='Software Craftsmanship'/><category term='Agile2011'/><category term='ReSharper'/><category term='Rants'/><category term='UtahCodeCamp'/><category term='Linux'/><category term='Books'/><title type='text'>Code Obsession</title><subtitle type='html'>I like working with teams to create great software. Writing code is fun. Writing about code is fun, too.&lt;br&gt;&lt;br&gt;&lt;i&gt;Thoughts and impressions fill my mind, once written are clarified, solid.&lt;/i&gt;</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>54</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-8224360590018479706</id><published>2011-12-14T12:19:00.000-08:00</published><updated>2011-12-14T12:28:17.809-08:00</updated><title type='text'>Visual Studio Hotkey for Web Devs: Attach to W3WP</title><content type='html'>Friends keep asking for this, so here are the instructions:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;In VS2010 open the Tools / Macros / Macro IDE menu item&lt;/li&gt;&lt;li&gt;Create or edit the MyMacros project&lt;/li&gt;&lt;li&gt;Add a new Module called "AttachToProcess"&lt;/li&gt;&lt;li&gt;Replace all the code with the following:&lt;/li&gt;&lt;pre class="brush: vbnet"&gt;Imports System&lt;br /&gt;Imports EnvDTE&lt;br /&gt;Imports EnvDTE80&lt;br /&gt;Imports EnvDTE90&lt;br /&gt;Imports EnvDTE90a&lt;br /&gt;Imports EnvDTE100&lt;br /&gt;Imports System.Diagnostics&lt;br /&gt;&lt;br /&gt;Public Module AttachToProcess&lt;br /&gt;    Sub IISWorkerProcess()&lt;br /&gt;        Dim attached As Boolean = False&lt;br /&gt;        Dim process As EnvDTE.Process&lt;br /&gt;&lt;br /&gt;        For Each process In DTE.Debugger.LocalProcesses&lt;br /&gt;            If process.Name.EndsWith("w3wp.exe") Then&lt;br /&gt;                process.Attach()&lt;br /&gt;                attached = True&lt;br /&gt;            End If&lt;br /&gt;        Next&lt;br /&gt;&lt;br /&gt;        If Not attached Then&lt;br /&gt;            MsgBox("Couldn't find w3wp.exe")&lt;br /&gt;        End If&lt;br /&gt;&lt;br /&gt;    End Sub&lt;br /&gt;End Module&lt;br /&gt;&lt;/pre&gt;&lt;li&gt;Save this macro&lt;/li&gt;&lt;li&gt;Close the Macro IDE&lt;/li&gt;&lt;li&gt;Right click the VS2010 menu bar&lt;/li&gt;&lt;li&gt;Select Customize...&lt;/li&gt;&lt;li&gt;Click Keyboard...&lt;/li&gt;&lt;li&gt;Select Macros.MyMacros.AttachToProcess.IISWorkerProcess from the lists of commands&lt;/li&gt;&lt;li&gt;Enter a shortcut in the box (I use Ctrl+Alt+A)&lt;/li&gt;&lt;li&gt;Click Assign, then OK, then Close&lt;/li&gt;&lt;li&gt;Open a web application, browse to the site and test your macro&lt;/li&gt;&lt;/ol&gt;Enjoy!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-8224360590018479706?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/8224360590018479706/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/12/visual-studio-hotkey-for-web-devs.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/8224360590018479706'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/8224360590018479706'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/12/visual-studio-hotkey-for-web-devs.html' title='Visual Studio Hotkey for Web Devs: Attach to W3WP'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-4350967848377371619</id><published>2011-12-04T12:36:00.001-08:00</published><updated>2011-12-04T13:06:13.781-08:00</updated><title type='text'>Global Day of Coderetreat - Attendee Report</title><content type='html'>Yesterday was my first opportunity to attend a Coderetreat. I am so glad I did. What an amazing day. I think every developer should attend a Coderetreat.&amp;nbsp;Using the closing circle format, allow me to share my experience as an attendee of the Salt Lake City event.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;What, if anything, did you learn today?&lt;/h3&gt;I learned that I need to slow down and focus on writing code well. The mute session taught me how hard it is to see an architectural vision from the code. It felt like I was painting a picture using the &lt;a href="http://en.wikipedia.org/wiki/Stippling"&gt;stippling technique&lt;/a&gt; and my pair could only see the dots, not the image. I learned that the idea of intention-revealing, self-documenting code cannot be judged by the author only by another developer.&lt;br /&gt;I also learned that Amber Smalltalk is pretty sweet. Thanks, Johnny T!&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;What, if anything, surprised you today?&lt;/h3&gt;The biggest surprise for me was how many developers said the Coderetreat inspired them to go out and actually do TDD. I had expected that most of the attendees would be rather dogmatic about testing and TDD. I know that at several points, I had to remind my pair to write a test before the code.&lt;br /&gt;I was surprised at how far we got and how many tests we wrote in the mute session. It takes a lot of tests to reveal the intent sometimes. We had close to 40 tests when we deleted the folder.&lt;br /&gt;Also surprising was how hard the last session was. We were allowed to pick our own challenge and we really struggled with that. We kind of lost focus and switched challenges midway and by the end, I think we were just coding trying to get as far as we could in the problem.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;What, if anything, will you do differently in the future?&lt;/h3&gt;I will try harder to value the ideas of others and explore them more deeply. In the last session, my pair told me that was his first session with a bounded world. My pairs and I created a bounded world (array, list, matrix, grid) in every session. I need to open my mind more to alternate ways of accomplishing tasks.&lt;br /&gt;I also need to recognize how attached people can become to the code they write. I had no problem deleting the code I wrote, but more than one person expressed anxiety about it. When others change or remove the code I write, I assume they are improving the application in the best way they understand at that time, so I don't resent the changes. I need to remember that this is not a universally held belief and that changing another developer's code could be considered an insult or attack on them and their abilities.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-4350967848377371619?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/4350967848377371619/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/12/global-day-of-coderetreat-attendee.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/4350967848377371619'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/4350967848377371619'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/12/global-day-of-coderetreat-attendee.html' title='Global Day of Coderetreat - Attendee Report'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-8437675320003981053</id><published>2011-12-04T11:24:00.001-08:00</published><updated>2011-12-04T12:34:25.166-08:00</updated><title type='text'>Global Day of Coderetreat - Organizing</title><content type='html'>Yesterday was the first ever &lt;a href="http://coderetreat.org/"&gt;Global Day of Coderetreat&lt;/a&gt;. Using the closing circle format, allow me to share my experience as an organizer of the Salt Lake City event.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;What, if anything, did you learn today?&lt;/h3&gt;The first lesson I (re-)learned as an organizer is that we have an awesome community both globally and locally. There were so many people willing to help out and make this a great day for coders.&amp;nbsp;Of the many tasks required to make the day happen, I could only do a portion on my own.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Kay Johansen did an amazing job as the facilitator. I don't know how to thank her enough for all she did.&lt;/li&gt;&lt;li&gt;Mike Clement took the lead in communicating with the facility sponsor including making last minute calls to get doors unlocked so we could set up early.&lt;/li&gt;&lt;li&gt;The STG office staff, including Crystal, Kelly, Thayne, Marth, Ron and Chick, took care of our catering needs including correcting a communication error with the restaurant.&lt;/li&gt;&lt;li&gt;All of the attendees helped clean setup and clean up the room.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;The most important lesson I learned through organizing the event is empathy for managers.&amp;nbsp;The lunch mix-up is actually what triggered the epiphany for me. When you delegate an important task to someone else, you have to trust them to do it well. When lunch arrived and was only enough food for 6 people instead of 30, my very first reaction was, &lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;i&gt;"I should not have trusted anyone else to take care of this.&lt;/i&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;i&gt;I should have done it myself!"&lt;/i&gt;&lt;/div&gt;&lt;br /&gt;Fortunately, I have been working in agile development shops for years and I was able to focus on the solution rather than the problem. My excellent team members Martha, Ron and Chick sprang into action and got additional food ordered and delivered and everyone had a great lunch. Kay ran the prelunch session long so that people didn't realize they weren't eating. I think most of the attendees were thrilled for the extra time anyway.&lt;br /&gt;So, the next time a manager tries to micro manage the team or me directly, I will have a lot more empathy for that behavior. Rather than resenting their lack of trust, I will try to remember the way I felt when lunch arrived. Then I will work in a way that inspires trust, so that they don't have to feel let down or the desire to micromanage.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;What, if anything, surprised you today?&lt;/h3&gt;I think the biggest surprise was when lunch showed up.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;What, if anything, will you do differently in the future?&lt;/h3&gt;I'm not really sure what I will do differently. I think that communicating expectations more clearly and communicating with my team more regularly will be part of it. The locked doors and lunch mix-up could have easily been avoided if we had communicated the needs of the event more clearly.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;This was a great experience for me. I will not shy away from participating in the organization of future events.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-8437675320003981053?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/8437675320003981053/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/12/global-day-of-coderetreat-organizing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/8437675320003981053'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/8437675320003981053'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/12/global-day-of-coderetreat-organizing.html' title='Global Day of Coderetreat - Organizing'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-8546113558232953595</id><published>2011-11-13T13:53:00.001-08:00</published><updated>2011-11-13T14:29:22.022-08:00</updated><title type='text'>Linux and Coderetreat</title><content type='html'>So, I haven't posted in a while. I guess I've been busy? I dunno. I have been organizing/coordinating the &lt;a href="http://www.eventbrite.com/event/2460944752"&gt;Salt Lake City event&lt;/a&gt; for &lt;a href="http://blog.coderetreat.com/global-day-of-coderetreat"&gt;Global Day of Coderetreat&lt;/a&gt;. I guess that is keeping me busy. We have a &lt;a href="http://www.neumont.edu/"&gt;facility&lt;/a&gt;, a &lt;a href="https://twitter.com/#!/utahkay"&gt;facilitator&lt;/a&gt; and &lt;a href="http://www.stgutah.com/"&gt;meal sponsor&lt;/a&gt;, so we are getting pretty close to ready. Good thing, since it is only 3 weeks away! Oh yeah, we're almost sold out too, so if you wanna come, you better register soon!&lt;br /&gt;&lt;br /&gt;The other thing eating up my free time is Linux. Specifically Ubuntu. As you may remember, I decided to run an &lt;a href="http://www.ubuntu.com/download/ubuntu/windows-installer"&gt;Ubuntu VM&lt;/a&gt; on my Windows 7 laptop. I really want to expand my skills in new (and somewhat uncomfortable) directions and this seemed like a great option. I have been going through the &lt;a href="http://pragprog.com/book/btlang/seven-languages-in-seven-weeks"&gt;7 Languages in 7 Weeks&lt;/a&gt; book with the Utah Software Craftsmanship group and it seems like the Linux support for a lot of these languages is better/easier.&lt;br /&gt;&lt;br /&gt;Here is my experience and what I have learned so far:&lt;br /&gt;&lt;br /&gt;The first thing I did was use the Wubi installer to create a dual-boot, pseudo-vm of Ubuntu 11.04 on my laptop. I used this for a while and it was fine. I had &lt;a href="http://www.jetbrains.com/ruby/"&gt;RubyMine&lt;/a&gt; running and I had some decent success using it for learning &lt;a href="http://iolanguage.com/"&gt;Io&lt;/a&gt;. Despite my initial assertion that I would use Linux for everything I could and only fall back on Windows when I needed to or felt stuck, I found myself booting Windows more and more often.&lt;br /&gt;&lt;br /&gt;Eventually, Ubuntu 11.10 was released, and on one of the rare days when I loaded up Ubuntu, I decided to accept the upgrade. After the download and install, there was an automatic reboot. That was the end of my VM. It never again booted past grub. I tried several times to fix or reinstall it and never got anywhere. Eventually, I had the Linux guys at my office help me out and they couldn't get it working either, so we started over...&lt;br /&gt;&lt;br /&gt;We used gparted to create a real partition for Ubuntu (60GB) then installed 10.04 LTS Lucid Lynx. It turns out that for me, I have no reason to be on the newest versions of Ubuntu. A nice, stable version is a perfect place for a noob to play. I have learned about some of the nifty UI tools that are build in and I have been enjoying the multiple workspaces even more than I did before I broke my 11.04 install.&lt;br /&gt;&lt;br /&gt;With a moderate amount of struggle, I managed to get RubyMine 3.2 installed (I couldn't work out the environment variables and the java version.) I have also have MonoDevelop up and kinda running (it gets a weird error when I try to run NUnit tests.) &lt;br /&gt;&lt;br /&gt;My next steps are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Learn enough VIm to be dangerous&lt;/li&gt;&lt;li&gt;Get a Rails app running&lt;/li&gt;&lt;li&gt;Run through the Erlang tutorials in 7 Languages&lt;/li&gt;&lt;li&gt;Build an ASP.NET app with MonoDevelop&lt;/li&gt;&lt;li&gt;Continue using Ubuntu daily as my primary, at-home OS&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-8546113558232953595?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/8546113558232953595/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/11/linux-and-coderetreat.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/8546113558232953595'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/8546113558232953595'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/11/linux-and-coderetreat.html' title='Linux and Coderetreat'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-4618056621221234346</id><published>2011-10-06T00:54:00.000-07:00</published><updated>2011-10-06T00:54:01.982-07:00</updated><title type='text'>SOA : RPC : : Object Oriented Design : Procedural Programming</title><content type='html'>Back in 2008, I attended SDBest Practices in Boston. I had recently read Jimmy Nilsson's &lt;a href="http://www.amazon.com/Applying-Domain-Driven-Design-Patterns-Examples/dp/0321268202"&gt;Domain Driven Design&lt;/a&gt; book. One of the contributors to the book was Udi Dahan, so when I say that he was talking at the conference, I was excited to attend his session: How to Avoid a Failed SOA. At that point, I didn't know much about Service Oriented Architecture, but what he described as a failure mode sounded like an architecture I had discussed and planned with coworkers. That session was the start of a journey into learning about SOA.&lt;br /&gt;&lt;br /&gt;I spend my spare time reading about SOA. I read Udi's &lt;a href="http://www.udidahan.com/?blog=true"&gt;blog&lt;/a&gt;. I read Thomas Erl's book &lt;a href="http://www.amazon.com/Service-Oriented-Architecture-SOA-Concepts-Technology/dp/0131858580"&gt;Service Oriented Architecture&lt;/a&gt;. I read &lt;a href="http://www.amazon.com/SOA-Practice-Distributed-System-Design/dp/0596529554"&gt;SOA in Practice&lt;/a&gt;. I played with various ESBs and Message Brokers. I built a pretty sweet prototype of my company's systems using &lt;a href="http://www.nservicebus.com/"&gt;NServiceBus&lt;/a&gt;. I even attended the &lt;a href="http://www.soaworld2009.com/"&gt;SOA World 2009&lt;/a&gt; conference in NYC and a full week immersion course on SOA taught by &lt;a href="http://www.infoq.com/author/Jean~Jacques-Dubray"&gt;Jean-Jacques Dubray&lt;/a&gt;. In the end, I never took any of it to production because it didn't align with the &lt;a href="http://www.youtube.com/watch?v=XZ5TajZYW6Y"&gt;Enterprise Architect&lt;/a&gt;'s vision.&lt;br /&gt;&lt;br /&gt;What I learned is that the naive implementation of SOA is to distribute workload in a system by making Remote Procedure Calls to (web) services running on other systems. Unfortunately, this style of architecture runs into the &lt;a href="http://en.wikipedia.org/wiki/Fallacies_of_Distributed_Computing"&gt;fallacies of distributed computing&lt;/a&gt;. Put simply, you can't take a remote call to a database server from your web server that takes X ms and introduce a web service call in the middle and expect it to take less than X ms.&lt;br /&gt;&lt;br /&gt;Taking into account things like the &lt;a href="http://en.wikipedia.org/wiki/CAP_theorem"&gt;CAP Theorem&lt;/a&gt;, eventual consistency, &lt;a href="http://martinfowler.com/bliki/CQRS.html"&gt;CQRS&lt;/a&gt;, etc leads to a different strategy. In this implementation of SOA, one focuses on Domain Events and the Messages exchanged by the Services rather than emphasizing the Services themselves. I have often contemplated these types of systems and how they lead to simple, autonomous, easily-redundant, horizontally-scalable Services.&lt;br /&gt;&lt;br /&gt;The similarities to OO are striking. Object orientation is also about message passing. In languages such as Smalltalk, we talk about "sending messages to objects" or "objects receiving messages" rather than talking about "calling methods on objects." The characteristics of these OO systems are similar to the what we desire in SOA. They are (or can be) loosely coupled and focus on performing actions rather than requesting at-rest data to be operated on externally.&lt;br /&gt;&lt;br /&gt;So when building software, whether a single application or a collection of inter-operating applications that form a complex network with high availability and scalability requirements, remember to focus on the messages, not the Objects/Services. This is what I was thinking about the other day when I tweeted, "I never understood OO until I studied SOA. It's not the object/services that matter. It's the messages."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-4618056621221234346?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/4618056621221234346/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/10/soa-rpc-object-oriented-design.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/4618056621221234346'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/4618056621221234346'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/10/soa-rpc-object-oriented-design.html' title='SOA : RPC : : Object Oriented Design : Procedural Programming'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-5350820080311503537</id><published>2011-09-21T12:28:00.000-07:00</published><updated>2011-09-21T12:28:51.397-07:00</updated><title type='text'>Into the mine shaft..</title><content type='html'>I think we are all somewhat familiar with the concept of canaries in coal mines. As recently as 25 years ago, canaries were taken into coal mines as a way to detect poisonous gasses such as CO&lt;span class="Apple-style-span" style="font-size: xx-small;"&gt;2&lt;/span&gt; and methane. The canary would sing all day long unless overcome by the gasses. At this point, the miners would realize their environment had become toxic and they would flee for their lives.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-yNPjT3pA324/Tnnq_BQdeMI/AAAAAAAAAF4/dhBPZCe-2Ek/s1600/Canary-In-A-Coal-Mine.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="257" src="http://1.bp.blogspot.com/-yNPjT3pA324/Tnnq_BQdeMI/AAAAAAAAAF4/dhBPZCe-2Ek/s320/Canary-In-A-Coal-Mine.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Development teams sometimes find that they have a canary in their midst. This person seems to point out unseen dangers ahead based on the current path. The things that the canary sings about aren't really affecting the team, but he or she claims they will if not corrected. How do you know if you have a canary or a whiner? That is tricky. The best advice I have is to look to experience. Does the person have experience working with multiple teams in multiple environments? Has she experienced similar situations in the past? Does she give recommendations for alternate courses of action? Is she passionate about achieving success? Is she regularly educating herself on the topic? I find that canaries seem to focus on one or two things that they are really interested in and they take pains to learn as much as they can about those topics. If someone whines about everything, he probably isn't a canary.&lt;br /&gt;&lt;br /&gt;Let's face it, a canary can be pretty annoying with their constant singing about unseen dangers. The good news is that canaries are really easy to kill. You can ignore them to death. Martin Seligman did extensive research into learned helplessness which you can read about in the book &lt;a href="http://www.amazon.com/Learned-Optimism-Change-Your-Mind/dp/1400078393"&gt;Learned Optimism&lt;/a&gt;. The gist of the theory is that if you learn that your actions cannot affect your environment, you will eventually stop trying to change your situation and you will accept whatever comes. Using the techniques described in his experiments, you can easily, if not quickly, kill your annoying canary. He or she will eventually either leave the organization or give up and stop warning about unseen dangers.&lt;br /&gt;&lt;br /&gt;So if they are annoying and easy to eliminate, why not do just that? Well, the obvious answer is that the canary is protecting your team from some real danger. Eliminating the canary doesn't protect miners from CO&lt;span class="Apple-style-span" style="font-size: xx-small;"&gt;2&lt;/span&gt; or methane poisoning; it just reduces their chances of survival once they all start feeling the effects of the problem. They say that an ounce of prevention is worth a pound of cure. The canary allows you to address problems before they become large and difficult. Keeping morale high on a team is often easier than fixing an ongoing morale problem. Eliminating technical debt early means that there is less code depending on that bad code. Study after study in our industry has proven that the longer you wait in your process to fix a defect, the more expensive it becomes.&lt;br /&gt;&lt;br /&gt;So if you are lucky enough to have a canary, you should listen to her and take what she says seriously even if you choose not to act on her advice at that time. And you accidentally kill your canary, my advice is to get out of the mine shaft in a quick and orderly manner lest you suffer the same fate...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-5350820080311503537?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/5350820080311503537/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/09/into-mine-shaft.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/5350820080311503537'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/5350820080311503537'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/09/into-mine-shaft.html' title='Into the mine shaft..'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-yNPjT3pA324/Tnnq_BQdeMI/AAAAAAAAAF4/dhBPZCe-2Ek/s72-c/Canary-In-A-Coal-Mine.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-7979471148829518460</id><published>2011-09-10T14:20:00.000-07:00</published><updated>2011-09-10T14:20:00.511-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='UtahCodeCamp'/><title type='text'>Model View Presenter - A Path Forward from WebForms</title><content type='html'>This post is a review of my September 10th presentation at &lt;a href="http://utahcodecamp.com/"&gt;Utah Code Camp&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;"So you read and hear about Test Driven Development, MVC Frameworks, Continuous Integration and the safety net provided by high levels of unit test coverage. But you work on a WebForms app that has been around since .NET 1.1. It has thousands of lines of code in the code behind classes and you know that isn't easy to test. How can you experience all of these wonderful things you read about? The Model View Presenter pattern is here to rescue you. We will discuss the purpose and structure of MVP as it is applied to WebForms. We will go through a demonstration of some relatively safe refactorings that allow you to start bringing your unruly code under test. We will then add tests using NUnit and Moq. We will wrap up the discussion with a road map from WebForms chaos through Model View Present into the promised land of the MVC frameworks."&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Having worked on ASP.NET web sites/apps since .NET 1.0 beta 1, I have seen plenty of messy code. I have certainly added my fair share to the pile. I have seen 3,000 line code behind files, data access in the markup file and any number of things that make me cringe. If you work on a large or old ASP.NET WebForms site, I am sure you have seen it all too.&lt;br /&gt;&lt;br /&gt;Some of the design decisions of the WebForms team have made it really easy to make a mess. That is unfortunate, but it is what it is. WebForms has accomplished its goal of getting VB6 developers into web programming, and, I for one am happy that I was able to easily make that move. The problem many of us face now is that we created web applications without truly understanding web technologies and now we feel like we are stuck in a swamp with no way out.&lt;br /&gt;&lt;br /&gt;Software development has changed a lot in the last 10 years. Automated testing has gone from fringe to mainstream. Many development shops &lt;a href="http://cleancoder.posterous.com/100-test-coverage"&gt;require&lt;/a&gt; unit tests and even &lt;a href="http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd"&gt;TDD&lt;/a&gt;. &lt;a href="http://testobsessed.com/2008/12/08/acceptance-test-driven-development-atdd-an-overview/"&gt;ATDD&lt;/a&gt; is becoming a big deal. MVC frameworks, such as &lt;a href="www.rubyonrails.org"&gt;Rails&lt;/a&gt;, &lt;a href="fubumvc.com"&gt;FubuMVC&lt;/a&gt;, &lt;a href="openrasta.org"&gt;OpenRasta&lt;/a&gt; or even &lt;a href="www.asp.net/mvc"&gt;ASP.NET MVC&lt;/a&gt;, have taken over the web. Object oriented design principles such as &lt;a href="http://c2.com/cgi/wiki?CouplingAndCohesion"&gt;low coupling and high cohesion&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/SOLID_(object-oriented_design)"&gt;SOLID&lt;/a&gt; and patterns are hot topics in the industry. &lt;br /&gt;&lt;br /&gt;So as a developer, you want to know about and use all these cool, new things, right? But your code sucks. You can't see any way to use any of these tools or techniques without a rewrite of the system. And the short sited &lt;a href="http://dilbert.com/strips/comic/2011-09-09/"&gt;management&lt;/a&gt; still puts the business' needs ahead of your career development. Fortunately, there is hope!&lt;br /&gt;&lt;br /&gt;&lt;a href="http://codebetter.com/jeremymiller/2006/02/02/test-driven-development-with-asp-net-and-the-model-view-presenter-pattern/"&gt;Model View Presenter&lt;/a&gt;, specifically &lt;a href="http://martinfowler.com/eaaDev/PassiveScreen.html"&gt;Passive View&lt;/a&gt;, provides a path from where you are to where you want to be.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.flickr.com/photos/sdenham/439040539/" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="300" width="400" src="http://1.bp.blogspot.com/-zfCOi5Z_iLs/TmqnD94JUnI/AAAAAAAAAFw/ulNbPg-thXA/s400/439040539_dcdfb5332b_z.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font: smallest; font-style:italic;"&gt;thanks to &lt;a href="http://www.flickr.com/photos/sdenham/439040539/"&gt;Scott Denham&lt;/a&gt; for the image&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;To see an example of refactoring a WebForms application to implement the MVP pattern, walk through the commits on &lt;a href="https://github.com/davidadsit/Utah-Code-Camp-MVP-Sample"&gt;this&lt;/a&gt; github repository.&lt;br /&gt;&lt;br /&gt;Now that you know how to refactor your code, what have you bought with all that hard work? The bad news is, you have added complexity to the code base. The good news is you are now ready to start implementing several of the patterns you wanted in the first place:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Test Driven Development&lt;/b&gt; - Breaking your dependencies allows you to really test isolated units of your code. You can start to write these tests &lt;i&gt;before&lt;/i&gt; you write the code that makes them pass.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Inversion of Control&lt;/b&gt; - Speaking of breaking dependencies, injecting your dependencies makes it really easy to hand off object construction to an IoC container as well.&lt;/li&gt;&lt;li&gt;&lt;b&gt;MVC&lt;/b&gt; - You probably already noticed that HandleSomeEvent() methods look an awful lot like ASP.NET MVC actions. And the fact that you already have ViewModels makes the MVC transition that much simpler. Using DI and an IoC container take you even closer.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Domain Driven Design&lt;/b&gt; - Pushing the business logic out of the UI is just the first step. Now you can start to push it out of the Application Layer and into your Domain Model where it belongs.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Acceptance Test Driven Development&lt;/b&gt; - When you have a classic WebForms app, where do you hook your &lt;a href="fitnesse.org"&gt;FitNesse&lt;/a&gt; fixtures? You know the UI is the wrong answer because of the problems you had with &lt;a href="watin.org"&gt;WatiN&lt;/a&gt;, &lt;a href="watir.org"&gt;Watir&lt;/a&gt;, &lt;a href="seleniumhq.org"&gt;Selenium&lt;/a&gt; and other UI testing tools. Presenters introduce an Application Layer (or Service Layer) into your app that make ATDD not just possible, but actually pretty easy.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;That's about it. MVP isn't a destination, it is just a step on the path to something better. The best part of the pattern is that it allows you to take small, iterative steps forward.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-7979471148829518460?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/7979471148829518460/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/09/model-view-presenter-path-forward-from.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/7979471148829518460'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/7979471148829518460'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/09/model-view-presenter-path-forward-from.html' title='Model View Presenter - A Path Forward from WebForms'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-zfCOi5Z_iLs/TmqnD94JUnI/AAAAAAAAAFw/ulNbPg-thXA/s72-c/439040539_dcdfb5332b_z.jpg' height='72' width='72'/><thr:total>0</thr:total><georss:featurename>Neumont University, 10701 River Front Pkwy # 300, South Jordan, UT 84095-3524, USA</georss:featurename><georss:point>40.5562479 -111.910814</georss:point><georss:box>40.5441839 -111.930555 40.568311900000005 -111.891073</georss:box></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-1936880227604224317</id><published>2011-09-03T15:27:00.000-07:00</published><updated>2011-09-03T15:27:48.029-07:00</updated><title type='text'>Premature Configurability Design Smell</title><content type='html'>Premature Configurability is making some aspect of your application configurable (or data driven) before anyone has ever asked for a change to that part of the system.&lt;br /&gt;&lt;br /&gt;This is a topic I have been contemplating for a while. I started writing this post at least 5 different times, but I was never satisfied with my results. Fortunately, Alex Papadimoulis of &lt;a href="http://thedailywtf.com/"&gt;The Daily WTF&lt;/a&gt; recently presented on the topic at Code PaLOUsa and he said everything I wanted to say. He refers to the smell as Soft Coding. Please watch his &lt;a href="http://www.infoq.com/presentations/Infinitely-Extensible"&gt;presentation&lt;/a&gt; and read his &lt;a href="http://thedailywtf.com/Articles/Soft_Coding.aspx"&gt;post&lt;/a&gt; on the topic.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-1936880227604224317?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/1936880227604224317/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/09/premature-configurability-design-smell.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/1936880227604224317'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/1936880227604224317'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/09/premature-configurability-design-smell.html' title='Premature Configurability Design Smell'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-4405403114987605829</id><published>2011-08-30T21:26:00.001-07:00</published><updated>2011-08-31T00:01:50.331-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Rants'/><title type='text'>No More Ninjas</title><content type='html'>Movie ninjas are awesome with the kicking, punching, jumping, etc. Code ninjas are unwelcome on my team.&lt;br /&gt;&lt;br /&gt;Let's take a brief look at the characteristics of the ninja:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Ninjas have great skill&lt;/li&gt;&lt;li&gt;Ninjas work alone&lt;/li&gt;&lt;li&gt;Ninjas are stealthy&lt;/li&gt;&lt;li&gt;Ninjas use unorthodox tactics&lt;/li&gt;&lt;li&gt;Ninjas are specialists in espionage, sabotage and assassination&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Great Skill&lt;/span&gt; - That sounds like what I want in members of my team, provided of course that it doesn't come with Great Arrogance.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Working Alone&lt;/span&gt; - Uh oh. No thanks. I want people who collaborate and act as a team. Paired programming for a large portion of the day is a must.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Stealthy&lt;/span&gt; - I really don't want anyone sneaking around in my code. I want clear names and explicit abstractions. Make your movements obvious. Create work that you are proud to sign (and then sign it on check in, not in comments.)&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Unorthodox Tactics&lt;/span&gt; - I liken this to creating your own ORM or web framework. Sure, there may be advantages sometimes, but these are most often outweighed by the constant maintenance work required on the framework, not to mention the requirement that you train new developers not just in the domain, but also your nonstandard tools.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Espionage, Sabotage and Assassination&lt;/span&gt; - When I get into a code base that has been written by ninjas, I often feel like they must have been spies from a competitor come to sabotage the code. The code written by these ninjas is full of traps and tricks and kills productivity.&lt;br /&gt;&lt;br /&gt;What I want on my team are Samurai. A Samurai follow a code of conduct that emphasizes the following:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Martial Arts Mastery&lt;/li&gt;&lt;li&gt;Loyalty&lt;/li&gt;&lt;li&gt;Frugality&lt;/li&gt;&lt;li&gt;Honor&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Martial Arts Mastery&lt;/span&gt; - Skill mastery is definitely something desirable for team members. Like the Ninja, the Samurai focuses on constantly improving his already formidable skills.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Loyalty&lt;/span&gt; - Who doesn't want loyal team members? These are the guys who treat each other with respect and who will work together to complete the tasks at hand.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Frugality&lt;/span&gt; - With regard to code, I like to think of frugality in the terms of good architecture. This means minimizing the number of classes, methods and abstractions while still expressing all of the necessary concepts of the domain.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Honor&lt;/span&gt; - This means always doing your best. Do what is right for your team and your code even when it is hard. Write your tests first even when you're under a deadline. Remove duplication even when it's hard. Complete the highest priority tasks first, even if others seem more fun.&lt;br /&gt;&lt;br /&gt;Anyway, please try to be less of a ninja and more of a samurai.&lt;hr&gt;As for Rock Stars, if the perks of your job don't include an unlimited supply of illicit drugs and slutty groupies, you are not a rock star! KTHXBAI!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-4405403114987605829?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/4405403114987605829/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/08/no-more-ninjas-please.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/4405403114987605829'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/4405403114987605829'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/08/no-more-ninjas-please.html' title='No More Ninjas'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-169501721303661700</id><published>2011-08-12T21:21:00.000-07:00</published><updated>2011-08-12T23:08:30.139-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Agile2011'/><title type='text'>Agile 2011 - Day 4-5</title><content type='html'>Thursday I went to WIP and Kaizen: Key Tools for Enabling Continuous Improvement: Michael DePaoli. It was a really interesting talk about how you need to make change slowly, incrementally and steadily to arrive at the organizational goal without causing a fight or flight reaction in your people. I enjoyed it though I expected it to be more about personal improvement for some reason.&lt;br /&gt;&lt;br /&gt;I wasn't really excited about any of the late morning sessions, so I bailed and went to Coach's Corner to hang out with Tim Ottinger and ended up meeting Colin Jones from 8th Light and then talking with Matt Barcomb from LeanDog for nearly an hour. &lt;br /&gt;&lt;br /&gt;Around noon, Evana Fredricko, my dance partner for Brian Marick's session on Tango, The Stance of Reaction, and Pair Programming arrived. We went out for a slice of pizza near the hotel, then returned for a very fun intro to tango and a great discussion on paired programming. A correlation was drawn between the way dance is taught and the way we should teach software practices: demonstrate, practice in isolation, then practice in the full context of dancing/working.&lt;br /&gt;&lt;br /&gt;After thanking Evana for her time, I returned late to the hotel so I missed How Functional Programming Changes Developer Practices and went to  The Fundamental Agile Apologetic: Tim Ottinger instead. I chatted with Tim and Rachael Davies about how the constraints of an average software project will lead you toward a set of practices similar to those of XP or other agile methodologies.&lt;br /&gt;&lt;br /&gt;The Open Jam was pretty crowded so I wandered around the quiet halls until I found an ex-coworker. We talked shop and how things were going at his company. All too soon, the end-of-conference party started and I went around and said goodbye to my new friends and went home early.&lt;br /&gt;&lt;br /&gt;Friday, Dave Brady carpooled to the conference with me. We both really enjoyed Kevlin Henney and Linda Rising's talks and spent some time talking to them after. From there, we went back to the Open Jam to hang out with GeePawHill, Tim Ottinger and Angela Harms. Tim and I left for a late lunch and I dropped him off at the airport.&lt;br /&gt;&lt;br /&gt;I am now exhausted and yet completely energized. This was an amazing week full of learning and friendship.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-169501721303661700?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/169501721303661700/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/08/agile-2011-day-4-5.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/169501721303661700'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/169501721303661700'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/08/agile-2011-day-4-5.html' title='Agile 2011 - Day 4-5'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-3666848726465712488</id><published>2011-08-11T21:10:00.000-07:00</published><updated>2011-08-11T21:46:38.186-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Agile2011'/><title type='text'>Agile 2011 - Day 3</title><content type='html'>I was too tired to post last night. So I am in the Coach's Corner doing the write up now.&lt;br /&gt;&lt;br /&gt;The Plan:&lt;br /&gt;Who even cares?&lt;br /&gt;&lt;br /&gt;Actual:&lt;br /&gt;I started the day in Agile isn't Enough: Jeremy Lightsmith. The key discussions were on:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;What have you read besides books on agile that has helped your job?&lt;/li&gt;&lt;li&gt;A/B Testing&lt;/li&gt;&lt;li&gt;Paper Prototyping&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.davidco.com/individuals"&gt;Getting Things Done&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Theory of Constraints Current Reality Tree&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;The item that was new to me was the Current Reality Tree. I am adding that to my queue of things to study.&lt;br /&gt;&lt;br /&gt;The second session of the day was Flow Games: Karl Scotland, Eric Willeke. We played a game where we had to toss 20 balls around the group and the WIP and cycle time were tracked by the presenters. We were able to see the affects of our changes to the system and how we could shorten cycle time.&lt;br /&gt;&lt;br /&gt;I had lunch at Squatter's with one of my closest friends and that was a great break in the middle of the day.&lt;br /&gt;&lt;br /&gt;The first afternoon session was Tests as a Means of Abstraction: Brian Marick, Michael Feathers. This was an interesting talk in that Brian presented and Michael was the respondent. We got to see how Brian uses Midge to write tests in Clojure that don't rely on implementations only on behaviors of the data structures passed around. It was a nice example of TDD to do top down design and the test doubles (meta-constants) were a really interesting concept.&lt;br /&gt;&lt;br /&gt;After that, I went to Courageous Curiosity: Agile from the Inside Out: Angela Harms. This was a very powerful and emotionally challenging session. After the crowd left, I was fortunate to get an additional 30 minutes with Angela and GeePawHill. Truly powerful conversations. I am glad that they are both people I trust so that I could really open up and share with them.&lt;br /&gt;&lt;br /&gt;I needed to relax and decompress, so I went to Open Jam. There were some people just starting the &lt;a href="http://www.getkanban.com/"&gt;getKanban&lt;/a&gt; game. It was a nice way to relax and also informative about the way that cycle time and WIP relate.&lt;br /&gt;&lt;br /&gt;Wandering the expo was a fun way to run into some new friends. After a couple of laps I made my way over to Open Jam again where I was able to watch 3-way, big-screen-projector pairing on Smalltalk between Dave Brady, Pat Maddox and Johnny T. After a few minutes, Johnny split off and started teaching me the basics of Smalltalk. I'm more tempted than ever to go to the Utah Smalltalk User Group.&lt;br /&gt;&lt;br /&gt;Dave and I drove home together (we're nearly neighbors) and had an awesome conversation about job satisfaction, business models, etc.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-3666848726465712488?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/3666848726465712488/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/08/agile-2011-day-3.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/3666848726465712488'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/3666848726465712488'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/08/agile-2011-day-3.html' title='Agile 2011 - Day 3'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-548551124418731081</id><published>2011-08-09T22:30:00.000-07:00</published><updated>2011-08-09T23:29:55.501-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Agile2011'/><title type='text'>Agile 2011 - Day 2</title><content type='html'>This is basically my 3rd day a the conference hotel and I am starting to feel it. I had to unfollow the Twitter hashtag because of information overload. Despite that, this is still exactly where I want to be.&lt;br /&gt;&lt;br /&gt;The Plan:&lt;br /&gt;Attend the following: keynote on positivity, "What we have learned so far" by Chet Hendrickson and Ron Jeffries, "Deliberate Discovery" by Liz Keogh and Pat Maddox, "It Depends on Context" by Ainsley Nies and Diana Larsen, "Getting Software Projects Done Right" by Bob Martin, "Industry Experts Panel," and "Dinner with a Stranger."&lt;br /&gt;&lt;br /&gt;Actual:&lt;br /&gt;The keynote on positivity by Barbara Fredrickson was very interesting. It seems very closely correlated with the work of Martin Seligman whose book "Learned Optimism" I have been reading. A quick search on google reveals that this correlation is not just in my head, but I am too tired to dig deeper tonight. I tried to pick up her book and ask her about the similarities, but the bookstore sold out, so I just went on to my next session.&lt;br /&gt;&lt;br /&gt;Chet and Ron were hilarious. Their slides all used Comic Sans and had kittens on them. I suspect Ron did that to poke at the UX guys. Anyway, I wasn't surprised by what they said about the learning of the last ten years, but I did enjoy the presentation. I also stuck around to chat with Ron and thank him for pushing me out of my comfort and forcing me to think in our past Twitter discussion. I also received one of the gifts he brought to the conference. :)&lt;br /&gt;&lt;br /&gt;At lunch, I met Mary Poppendieck and chatted briefly about flow and the construction of the Empire State Building. I also had a nice chat about agility at NASA and decided to attend the Atlassian party in the evening rather than the panel (I can't wait for my Angry Nerds tshirt.) &lt;br /&gt;&lt;br /&gt;The session on Deliberate Discover was excellent. I can't tell you about the game we played, but you should find Liz and ask her when and where you can play it. The discussions we had made me start to ponder the decisions we make early in the development process and how many can we safely delay. It seems like we take away our own options far too early far to often. The chat with Pat was excellent. That man knows how to shake your hand!&lt;br /&gt;&lt;br /&gt;Rather than the session on context, I opted for "Code Sense" by Micah Martin. It was interesting to see a bunch of different snippets and rate them. It was also fun after Bob showed up to hear his chuckles about the really bad stuff. I was starting to get worried because I rated almost every snippet as bad or terrible.&lt;br /&gt;&lt;br /&gt;After that, the schedule completely fell apart (in a great way.) I sat and chatted with Tim Ottinger and Jeff Langr about FitNesse testing and team problems. Jeff gave me some insight into how he has seen teams use FitNesse and Tim gave me suggestions on better retrospectives and the value of single piece flow over time-boxed iterations.&lt;br /&gt;&lt;br /&gt;At that point, I was hungry and luckily, Angela and GeePawHill were nearby and hungry as well. We went to the Little America lounge with a few people from DC and Gary Bernhardt. Dave Brady joined us after a while and we had some wonderful conversations. Gary told me (and Dave) to quit our jobs. Dave agreed that mine is holding me back from achieving my full potential, but neither of them offered me the magical replacement. Angela and I made plans to pair on some C# code before Friday.&lt;br /&gt;&lt;br /&gt;Now I am exhausted and having a hard time keeping my eyes open to keep writing this post, so I think I must be done.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-548551124418731081?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/548551124418731081/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/08/agile-2011-day-2.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/548551124418731081'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/548551124418731081'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/08/agile-2011-day-2.html' title='Agile 2011 - Day 2'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-3387324479012167430</id><published>2011-08-08T22:21:00.000-07:00</published><updated>2011-08-08T23:12:54.219-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Agile2011'/><title type='text'>Agile 2011 - Day 1</title><content type='html'>Holy shit! The internet isn't just a series of tubes, it's real! This may affect the way I interact in here... ;-) Anyway, I actually got to meet and shake hands with so many amazing people today including: Michael Feathers, Bob Martin, Angela Harms, Michael Hill, Tim Ottinger, Jeff Langr, Martin Fowler. My mind is nearly blown. There is so much talent and experience here I almost can't believe it.&lt;br /&gt;&lt;br /&gt;The Plan:&lt;br /&gt;Attend Refactoring in the 4th Dimension: Michael Feathers in the morning and The Transformation Priority Premise: Robert Martin in the afternoon.&lt;br /&gt;&lt;br /&gt;Actual:&lt;br /&gt;The Refactoring session was really interesting. Thinking about how your code base evolves as opposed to just looking at a point in time leads to some interesting metrics. A lot of research needs to be done in this area. Also, my Ruby skills are teh suck. I really need to practice and build a nice breakable toy.&lt;br /&gt;&lt;br /&gt;Lunch was better than I expected and worth the wait. The highlight was a brief conversation with Angela Harms and Micheal Hill. I ate with a random attendee whose name I have forgotten.&lt;br /&gt;&lt;br /&gt;The afternoon session with Uncle Bob was everything I expected. It was entertaining and educational I ended up pairing on the samples with the same guy I met at lunch. If you weren't able to make the session, it was a longer, hands-on version of his &lt;a href="http://ndc2011.macsimum.no/mp4/Day1%20Wednesday/Track5%201740-1840.mp4"&gt;NDC 2011&lt;/a&gt; talk.&lt;br /&gt;&lt;br /&gt;After that we had there was a humorous and informative Q&amp;A session with 15 of the original 17 authors of the manifesto.&lt;br /&gt;&lt;br /&gt;The day ended with the Ice Breaker event with had amazing food and the opportunity to chat with several of the presenters I am so excited to see this week.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-3387324479012167430?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/3387324479012167430/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/08/agile-2011-day-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/3387324479012167430'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/3387324479012167430'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/08/agile-2011-day-1.html' title='Agile 2011 - Day 1'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-1231749994847434111</id><published>2011-08-07T21:59:00.000-07:00</published><updated>2011-08-07T22:17:34.424-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Agile2011'/><title type='text'>Agile 2011 - Day 0</title><content type='html'>While there were no sessions, I think that the Agile 2011 conference technically started today. I was there anyway. Here is the report.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Plan:&lt;br /&gt;&lt;/b&gt;Head up to the Grand America for the 5:15 First Time Attendees session. Hang out until 7:00 then go over to the &lt;a href="http://www.slczombiewalk.blogspot.com/"&gt;Zombie Walk&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Actual:&lt;br /&gt;&lt;/b&gt;I went to SLC Airport to pick up &lt;a href="http://www.exampler.com/"&gt;Brian Marick&lt;/a&gt; and take him to the hotel at noon. He treated me to an excellent lunch at &lt;a href="http://www.squatters.com/default.aspx"&gt;Squatters&lt;/a&gt;. I had the Black and Bleu burger which is at least as delicious as it sounds. While the food was great, the conversation was better. It was a wonderful opportunity for me to &lt;a href="http://www.amazon.com/Passionate-Programmer-Remarkable-Development-Pragmatic/dp/1934356344"&gt;make the hang&lt;/a&gt; and learn directly from a well-known master. We spoke at length about software, languages, pets, programming jobs, XP, psychology and gift economies. It was an amazing lunch.&lt;br /&gt;After dropping Brian off at his hotel, I didn't really have time to drive home and back before the 5:15 session, so I decided to wonder around the Grand America. Soon I was helping the volunteers sort shirts and prep welcome packets. After that, I went to the Agile Alliance lounge and hung out until the session.&lt;br /&gt;I skipped the Zombie walk because I was missing Nikki and the kids and I know that, even as a local, I am going to be busy around the clock with the conference this week and I won't see them much. Spending time with them at the splash pad in The Ranches is more fun than hanging out with hipster zombies any day.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-1231749994847434111?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/1231749994847434111/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/08/agile-2011-day-0.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/1231749994847434111'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/1231749994847434111'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/08/agile-2011-day-0.html' title='Agile 2011 - Day 0'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-8561427174596422004</id><published>2011-07-27T07:49:00.000-07:00</published><updated>2011-07-27T08:03:44.732-07:00</updated><title type='text'>Current Status: Optimism and Ruby</title><content type='html'>So I am reading this book: &lt;a href="http://www.amazon.com/dp/1400078393"&gt;Learned Optimism&lt;/a&gt;. It isn't the usual tech fair, but it is full of scientific research rather than fluff, and the topic is something I need right now.&lt;br /&gt;&lt;br /&gt;I went to the &lt;a href="http://utruby.org/"&gt;Salt Lake Ruby Brigade&lt;/a&gt; last night. Those guys are awesome. They only made fun me for using Windows once. ;-)&lt;br /&gt;&lt;br /&gt;I should be studying &lt;a href="http://www.amazon.com/dp/193435659X"&gt;Clojure&lt;/a&gt; so I am ready for Michael Feathers and Brian Marick's talk at &lt;a href="http://program2011.agilealliance.org/event/873f7801c8b4f23fc1f0cfe0a45de2f5"&gt;Agile&lt;/a&gt; this year.&lt;br /&gt;&lt;br /&gt;Not to mention prepping for my talk(s) at &lt;a href="http://utahcodecamp.com/"&gt;Utah Code Camp&lt;/a&gt;...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-8561427174596422004?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/8561427174596422004/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/07/current-status-optimism-and-ruby.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/8561427174596422004'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/8561427174596422004'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/07/current-status-optimism-and-ruby.html' title='Current Status: Optimism and Ruby'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-2731342390198572479</id><published>2011-06-29T14:42:00.000-07:00</published><updated>2011-06-29T14:42:00.417-07:00</updated><title type='text'>Inspiring Developers to Greatness</title><content type='html'>How freaking pretentious is that title! And you thought my arrogance knew no bounds. Silly mortal.&lt;br /&gt;&lt;br /&gt;Anyway, this is a question that I have been pondering, and asking, for a while. I wish there were a simple answer, but I also wish I could lose weight while continuing to eat like I do and never exercise.&lt;br /&gt;&lt;br /&gt;What I have come up with so far are two factors that contribute greatly to the inspiration of developers, but do not actually guarantee anything.&lt;br /&gt;&lt;br /&gt;First, you need to give developers &lt;i&gt;some&lt;/i&gt; ability to control their destiny. Developers are naturally curious and creative people, so given a little freedom, they are likely to do something interesting. Or maybe they won't, but they will do &lt;span style="font-style:italic;"&gt;something&lt;/span&gt; out of the ordinary and they will extend their way of thinking and that can only help their ability to do their jobs. [Thanks to &lt;a href="http://twitter.com/#!/statenjason"&gt;Jason Staten&lt;/a&gt; for crystallizing this for me.]&lt;br /&gt;&lt;br /&gt;The second common thread in these discussions is "where I work, we do..." The company culture of giving a crap about &lt;a href="http://blog.scottbellware.com/2011/01/kaizen-relentless-rather-than.html"&gt;continual improvement&lt;/a&gt; seems to be a key ingredient. I know that before I worked with a team of excited developers, I just thought of this as a job. Their passion spread to me and I am trying to spread it to others. This is a pattern that I have heard over and over. (This usually, but not always, includes time to work on what you care about as part of your workday.) &lt;br /&gt;&lt;br /&gt;Conversely, if you work in a culture of disinterest, you will either find your interest waning, or you will get frustrated and leave. Chad Fowler would tell you to &lt;a href="http://www.amazon.com/Passionate-Programmer-Remarkable-Development-Pragmatic/dp/1934356344/"&gt;just get out&lt;/a&gt;. I have applied this strategy a couple of times. It isn't worth your sanity or your passion to stick it out at a crappy, soul-sucking job.&lt;br /&gt;&lt;br /&gt;Things like reading books on development, trying new languages, attending conferences, watching videos, going to user groups and participating in forums all keep the flames hot and help me continue on the path, but I don't know that any of them will get someone on the path. I have noticed that most of the dispassionate developers I know don't (and won't) do any of those things because they are &lt;a href="http://c2.com/cgi/wiki?OrdersOfIgnorance"&gt;third or fourth order ignorant&lt;/a&gt;. They don't even recognize the existence of the problem.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you have any thoughts, suggestions, tips, tricks or money for me, please leave them in the comments.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-2731342390198572479?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/2731342390198572479/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/06/inspiring-developers-to-greatness.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/2731342390198572479'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/2731342390198572479'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/06/inspiring-developers-to-greatness.html' title='Inspiring Developers to Greatness'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-7103395689413652423</id><published>2011-06-29T11:03:00.000-07:00</published><updated>2011-06-29T18:05:19.057-07:00</updated><title type='text'>Utah Ruby Users Group - First Impression</title><content type='html'>So, last night I went to the &lt;a href="http://utruby.org/"&gt;URUG&lt;/a&gt; meeting. I have been dabbling in Ruby in the evenings for a while now and I decided it was time for a mentor.  &lt;a href="http://twitter.com/#!/dbrady"&gt;Dave Brady&lt;/a&gt; has been unwittingly filling that role, and in addition to telling me to go through the &lt;a href="http://rubykoans.com/"&gt;Ruby Koans&lt;/a&gt;, he suggested a little community involvement. I am thrilled that he did because it was the best user group I have attended.&lt;br /&gt;&lt;br /&gt;It started off with the AA style My-name-is-and-I-have-been-doing-Ruby-for-X-years introductions. This was a nice change from the anonymous sea of faces at the .NET User Group.&lt;br /&gt;&lt;br /&gt;We got right down to the business of blowing my mind with a presentation on EigenClasses. Basically, this seems to be a private class on the instance object that allows you to modify the instance without modifying all instances of the actual class. If I got that wrong, please flame the comments.&lt;br /&gt;&lt;br /&gt;Next was &lt;a href="http://rack.rubyforge.org/"&gt;Rack&lt;/a&gt; middleware. I drew a lot of analogies to &lt;a href="http://fubumvc.com/"&gt;FubuMVC&lt;/a&gt;. Again, flames in the comments, please.&lt;br /&gt;&lt;br /&gt;I couldn't get wireless connectivity, and my &lt;a href="http://www.ubuntu.com/"&gt;Ubuntu&lt;/a&gt; VM crashed for the first time ever at about that point, so I just kind of watched the &lt;a href="http://postrank-labs.github.com/goliath/"&gt;Goliath&lt;/a&gt; interactive presentation.&lt;br /&gt;&lt;br /&gt;When the conversation moved to topics for which I had no context, I worked on the Koans. I actually finished them around 1:30 last night.&lt;br /&gt;&lt;br /&gt;So, after the meeting wrapped up, the "Hall Track" started and we discussed SmallTalk, OO vs Procedural paradigms, how languages encourage certain styles of code, estimates, working in broken organizations, how to inspire/motivate developers, etc. Several of us ended up talking in the hall and the parking lot until around 11. I am pretty sure that, if the conversation had gone on all night, it would have stayed just as interesting.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-7103395689413652423?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/7103395689413652423/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/06/utah-ruby-users-group-first-impression.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/7103395689413652423'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/7103395689413652423'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/06/utah-ruby-users-group-first-impression.html' title='Utah Ruby Users Group - First Impression'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-8827764179487921780</id><published>2011-06-26T09:45:00.000-07:00</published><updated>2011-06-26T10:12:23.582-07:00</updated><title type='text'>Status Update: Videos for Great Good</title><content type='html'>The NDC 2011 videos are available via torrent: &lt;a href="http://thezendev.com/blog/ndc-2011-video-torrent"&gt;http://thezendev.com/blog/ndc-2011-video-torrent&lt;/a&gt; (&lt;a href="http://goo.gl/IKrBh"&gt;direct link&lt;/a&gt;). My download is still in progress, but the handful I have already watched are as excellent as the last 2 years, so I highly recommend them.&lt;br /&gt;&lt;br /&gt;Also, I just downloaded and started watching the &lt;a href="http://groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures/"&gt;Structure and Interpretation of Computer Programs&lt;/a&gt; video series. Mind expansion in process. Updates as events warrant.&lt;br /&gt;&lt;br /&gt;Not a video, but more like a video game: &lt;a href="http://rubykoans.com/"&gt;http://rubykoans.com/&lt;/a&gt;. I am determined to learn me some Ruby. I started last night and I'm about a third of the way through.&lt;br /&gt;&lt;br /&gt;That is all for now.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-8827764179487921780?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/8827764179487921780/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/06/status-update-videos-for-great-good.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/8827764179487921780'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/8827764179487921780'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/06/status-update-videos-for-great-good.html' title='Status Update: Videos for Great Good'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-1267601396905600522</id><published>2011-06-18T12:08:00.000-07:00</published><updated>2011-06-18T12:35:11.585-07:00</updated><title type='text'>Review: Apprenticeship Patterns</title><content type='html'>We have been reading &lt;a href="http://ofps.oreilly.com/titles/9780596518387/"&gt;Apprenticeship Patterns: Guidance for the Aspiring Software Craftsman&lt;/a&gt; as part of our &lt;a href="http://www.industriallogic.com/papers/kh.html"&gt;Sequential Learning&lt;/a&gt; in the &lt;a href="https://groups.google.com/forum/#!forum/ut-software-craftsmanship"&gt;Utah Software Craftsmanship Group&lt;/a&gt;. The discussions have been excellent and have lead to greater understanding of the material, at least for me.&lt;br /&gt;&lt;br /&gt;The explicit discussion of how to improve has been enlightening for me. There are many patterns that I am now or have in the past applied to my career. There are a few that are new to me. Many of the recommended Actions push me out of my comfort zone.&lt;br /&gt;&lt;br /&gt;The assertion that there are not yet any Master Software Craftsmen came as a surprise. There are quite a few people whose works I follow who I have considered masters for a while. Either way, there is a lot of room for improvement all around, so I am excited to &lt;a href="http://ofps.oreilly.com/titles/9780596518387/accurate_self_assessment.html#rubbing_elbows"&gt;Rub Elbows&lt;/a&gt; with other aspiring craftsmen.&lt;br /&gt;&lt;br /&gt;My favorite quote from the book was "Moreover, most programmers think they are above average. The sad reality is that, due to the skewed distribution of skill illustrated by the following chart, most programmers are actually below average." I know that this has applied to me at multiple points during my career and I assume it always will. That won't keep me from learning and trying and constantly improving though.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-1267601396905600522?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/1267601396905600522/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/06/review-apprenticeship-patterns.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/1267601396905600522'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/1267601396905600522'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/06/review-apprenticeship-patterns.html' title='Review: Apprenticeship Patterns'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-7447500410385595677</id><published>2011-06-14T22:43:00.000-07:00</published><updated>2011-06-15T23:18:31.050-07:00</updated><title type='text'>Interaction Tests with Mocks</title><content type='html'>I seem to always be working on large, unwieldy WebForms apps. Because I am &lt;a href="http://junit.sourceforge.net/doc/testinfected/testing.htm"&gt;test infected&lt;/a&gt;, this means I often find myself refactoring large amounts of code out of code behind classes into Presenters a la &lt;a href="http://martinfowler.com/eaaDev/PassiveScreen.html"&gt;Model-View-Presenter&lt;/a&gt; so that I can unit test the &lt;a href="http://codeobsession.blogspot.com/2011/03/application-layers.html"&gt;Application&lt;/a&gt; logic as the first step toward a proper Domain model, separation of concerns and, eventually, &lt;a href="http://fubumvc.com/"&gt;MVC&lt;/a&gt;. Because the only way to know that most of these pages is working is by looking at the UI, I use interaction style tests to verify that the UI is displaying the correct data. &lt;a href="http://martinfowler.com/articles/mocksArentStubs.html"&gt;Mocks and Stubs&lt;/a&gt; become crucial elements of my tests. I used to use &lt;a href="http://ayende.com/wiki/Rhino+Mocks.ashx"&gt;Rhino Mocks&lt;/a&gt;, but for nearly a year, I have been using &lt;a href="http://code.google.com/p/moq/"&gt;Moq&lt;/a&gt;. Overall, I prefer Moq, though I don't have any specific reasons why.&lt;br /&gt;&lt;br /&gt;Here is a (somewhat contrived) example of how I have been writing these tests using Rhino Mocks:&lt;br /&gt;&lt;pre class="brush: csharp"&gt;&lt;br /&gt;[Test]&lt;br /&gt;public void HandlePageLoad_displays_client_full_name()&lt;br /&gt;{&lt;br /&gt; var clientRepositoryMock = MockRepository.GenerateMock&amp;lt;IClienRepository&amp;gt;();&lt;br /&gt; var viewMock = MockRepository.GenerateMock&amp;lt;IView&amp;gt;();&lt;br /&gt;&lt;br /&gt; var client = new Client { FirstName = "First", LastName = "Last" };&lt;br /&gt;&lt;br /&gt; clientRepositoryMock.Stub(x =&amp;gt; x.GetClientId(0)).IgnoreArguments().Return(client);&lt;br /&gt; viewMock.Expect(x =&amp;gt; x.DisplayFullName("First Last"));&lt;br /&gt;&lt;br /&gt; new ClientPresenter(clientRepositoryMock , viewMock).HandlePageLoad();&lt;br /&gt;&lt;br /&gt; viewMock.VerifyAllExpectations();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Add a second test...&lt;br /&gt;&lt;pre class="brush: csharp"&gt;&lt;br /&gt;[Test]&lt;br /&gt;public void HandlePageLoad_displays_client_phone()&lt;br /&gt;{&lt;br /&gt; var clientRepositoryMock = MockRepository.GenerateMock&amp;lt;IClienRepository&amp;gt;();&lt;br /&gt; var viewMock = MockRepository.GenerateMock&amp;lt;IView&amp;gt;();&lt;br /&gt;&lt;br /&gt; var client = new Client { Phone = new PhoneNumber(800, 555, 1212, "00000") };&lt;br /&gt;&lt;br /&gt; clientRepositoryMock.Stub(x =&amp;gt; x.GetClientId(0)).IgnoreArguments().Return(client);&lt;br /&gt; viewMock.Expect(x =&amp;gt; x.DisplayPhoneNumber(client.Phone.ToString()));&lt;br /&gt;&lt;br /&gt; new ClientPresenter(clientRepositoryMock, viewMock).HandlePageLoad();&lt;br /&gt;&lt;br /&gt; viewMock.VerifyAllExpectations();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Of course, now I see duplication, so I want to refactor:&lt;br /&gt;&lt;pre class="brush: csharp"&gt;&lt;br /&gt;IClienRepository clientRepositoryMock;&lt;br /&gt;IView viewMock;&lt;br /&gt;ClientPresenter presenter;&lt;br /&gt;&lt;br /&gt;[SetUp]&lt;br /&gt;public void SetUp()&lt;br /&gt;{&lt;br /&gt; clientRepositoryMock = MockRepository.GenerateMock&amp;lt;IClienRepository&amp;gt;();&lt;br /&gt; viewMock = MockRepository.GenerateMock&amp;lt;IView&amp;gt;();&lt;br /&gt; presenter = new ClientPresenter(clientRepositoryMock, viewMock);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[TearDown]&lt;br /&gt;public void TearDown()&lt;br /&gt;{&lt;br /&gt; viewMock.VerifyAllExpectations();&lt;br /&gt; clientRepositoryMock.VerifyAllExpectations();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[Test]&lt;br /&gt;public void HandlePageLoad_displays_client_full_name()&lt;br /&gt;{&lt;br /&gt; var client = new Client { FirstName = "First", LastName = "Last" };&lt;br /&gt;&lt;br /&gt; clientRepositoryMock.Stub(x =&amp;gt; x.GetClientId(0)).IgnoreArguments().Return(client);&lt;br /&gt; viewMock.Expect(x =&amp;gt; x.DisplayFullName("First Last"));&lt;br /&gt;&lt;br /&gt; presenter.HandlePageLoad();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[Test]&lt;br /&gt;public void HandlePageLoad_displays_client_phone()&lt;br /&gt;{&lt;br /&gt; var client = new Client { Phone = new PhoneNumber(800, 555, 1212, "00000") };&lt;br /&gt;&lt;br /&gt; clientRepositoryMock.Stub(x =&amp;gt; x.GetClientId(0)).IgnoreArguments().Return(client);&lt;br /&gt; viewMock.Expect(x =&amp;gt; x.DisplayPhoneNumber(client.Phone.ToString()));&lt;br /&gt;&lt;br /&gt; presenter.HandlePageLoad();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I might add a bunch of other tests after that, and they would be short and expressive like these two.&lt;br /&gt;&lt;br /&gt;So I have taken that form and translated it directly in to my Moq use.&lt;br /&gt;&lt;pre class="brush: csharp"&gt;&lt;br /&gt;Mock&amp;lt;IClienRepository&amp;gt; clientRepositoryMock;&lt;br /&gt;Mock&amp;lt;IView&amp;gt; viewMock;&lt;br /&gt;ClientPresenter presenter;&lt;br /&gt;&lt;br /&gt;[SetUp]&lt;br /&gt;public void SetUp()&lt;br /&gt;{&lt;br /&gt; clientRepositoryMock = new Mock&amp;lt;IClienRepository&amp;gt;();&lt;br /&gt; viewMock = new Mock&amp;lt;IView&amp;gt;();&lt;br /&gt; presenter = new ClientPresenter(clientRepositoryMock.Object, viewMock.Object);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[TearDown]&lt;br /&gt;public void TearDown()&lt;br /&gt;{&lt;br /&gt; viewMock.VerifyAll();&lt;br /&gt; clientRepositoryMock.VerifyAll();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[Test]&lt;br /&gt;public void HandlePageLoad_displays_client_full_name()&lt;br /&gt;{&lt;br /&gt; var client = new Client { FirstName = "First", LastName = "Last" };&lt;br /&gt;&lt;br /&gt; clientRepositoryMock.Setup(x =&amp;gt; x.GetClientId(It.IsAny&amp;lt;int&amp;gt;())).Return(client);&lt;br /&gt; viewMock.Setup(x =&amp;gt; x.DisplayFullName("First Last")).Verifiable();&lt;br /&gt;&lt;br /&gt; presenter.HandlePageLoad();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[Test]&lt;br /&gt;public void HandlePageLoad_displays_client_phone()&lt;br /&gt;{&lt;br /&gt; var client = new Client { Phone = new PhoneNumber(800, 555, 1212, "00000") };&lt;br /&gt;&lt;br /&gt; clientRepositoryMock.Setup(x =&amp;gt; x.GetClientId(It.IsAny&amp;lt;int&amp;gt;())).Return(client);&lt;br /&gt; viewMock.Setup(x =&amp;gt; x.DisplayPhoneNumber(client.Phone.ToString())).Verifiable();&lt;br /&gt;&lt;br /&gt; presenter.HandlePageLoad();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;While pairing the other day, we started discussing that the intent of the TearDown method is to undo any setup what was put in place before the test, NOT to assert anything. The VerifyAll() call is effectively an assertion that the mocks were interacted with properly. This it what was recommended instead: &lt;br /&gt;&lt;pre class="brush: csharp"&gt;&lt;br /&gt;Mock&amp;lt;IClienRepository&amp;gt; clientRepositoryMock;&lt;br /&gt;Mock&amp;lt;IView&amp;gt; viewMock;&lt;br /&gt;ClientPresenter presenter;&lt;br /&gt;&lt;br /&gt;[SetUp]&lt;br /&gt;public void SetUp()&lt;br /&gt;{&lt;br /&gt; clientRepositoryMock = new Mock&amp;lt;IClienRepository&amp;gt;();&lt;br /&gt; viewMock = new Mock&amp;lt;IView&amp;gt;();&lt;br /&gt; presenter = new ClientPresenter(clientRepositoryMock.Object, viewMock.Object);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[Test]&lt;br /&gt;public void HandlePageLoad_displays_client_full_name()&lt;br /&gt;{&lt;br /&gt; var client = new Client { FirstName = "First", LastName = "Last" };&lt;br /&gt;&lt;br /&gt; clientRepositoryMock.Setup(x =&amp;gt; x.GetClientId(It.IsAny&amp;lt;int&amp;gt;())).Return(client);&lt;br /&gt;&lt;br /&gt; presenter.HandlePageLoad();&lt;br /&gt;&lt;br /&gt; viewMock.Verify(x =&amp;gt; x.DisplayFullName("First Last"));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[Test]&lt;br /&gt;public void HandlePageLoad_displays_client_phone()&lt;br /&gt;{&lt;br /&gt; var client = new Client { Phone = new PhoneNumber(800, 555, 1212, "00000") };&lt;br /&gt;&lt;br /&gt; clientRepositoryMock.Setup(x =&amp;gt; x.GetClientId(It.IsAny&amp;lt;int&amp;gt;())).Return(client);&lt;br /&gt;&lt;br /&gt; presenter.HandlePageLoad();&lt;br /&gt;&lt;br /&gt; viewMock.Verify(x =&amp;gt; x.DisplayPhoneNumber(client.Phone.ToString()));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I have to admit that this is a much more Arrange-Act-Assert manner of writing tests with mock objects. It also seems to be the intent of the Moq library. I think my Playback-Record experience with early mocking tools was holding me back from seeing this way of writing my tests. I am going to try it for a while and report my experience...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-7447500410385595677?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/7447500410385595677/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/06/interaction-tests-with-mocks.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/7447500410385595677'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/7447500410385595677'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/06/interaction-tests-with-mocks.html' title='Interaction Tests with Mocks'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-6010669322543727699</id><published>2011-05-31T08:44:00.000-07:00</published><updated>2011-05-31T10:47:51.469-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Software Craftsmanship'/><category scheme='http://www.blogger.com/atom/ns#' term='Books'/><title type='text'>Review: The Clean Coder</title><content type='html'>TL;DR - If you care about software development at all, read this book now!&lt;hr /&gt;This book is a condensation and distillation of more than 40 years of industry experience. It is an amazing read. The book expresses the concept of professionalism in the clear, simple (not simplistic,) unapologetic style that Bob uses in all his writing. At a short 204 pages, you can read it in a weekend (like I did.)&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Having been involved in Agile (XP, XPish, ScrumBut) projects for several years and recently in the software craftsmanship movement, many of the concepts in the book were familiar.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The chapters on Saying Yes, Saying No and Estimation really spoke to me. I have had many experiences where I have agreed to "try." Now I see the danger of that statement clearly. I have also had experiences where I have stayed firm on my estimates and been encouraged to feel as though I was not a committed team player. I now have additional tools to help me combat that feeling and take professional actions despite pressure (from management or the team) to do otherwise.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For me, the most powerful section of the whole book is the commitments section of the Chapter 10 - Estimates. "Professionals don't make commitments unless they &lt;i&gt;know &lt;/i&gt;they can achieve them. It's really as simple as that." Wow. I have reread that section several times.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-6010669322543727699?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/6010669322543727699/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/05/review-clean-coder.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/6010669322543727699'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/6010669322543727699'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/05/review-clean-coder.html' title='Review: The Clean Coder'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-8431064456385631986</id><published>2011-05-06T20:35:00.000-07:00</published><updated>2011-05-09T20:46:43.259-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ReSharper'/><category scheme='http://www.blogger.com/atom/ns#' term='MicroTip'/><title type='text'>MicroTip: Searching</title><content type='html'>Finding the correct code to edit is essential. Here are a few shortcuts to make that easier:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Ctrl+I&lt;/b&gt; =&amp;gt; Incremental search. Just hit the keystroke and start typing. Your cursor will move to the next match.&lt;/div&gt;&lt;div&gt;&lt;b&gt;Ctrl+F&lt;/b&gt; =&amp;gt; You better know this one!&lt;/div&gt;&lt;div&gt;&lt;div style="font-weight: normal; "&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal; "&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal; "&gt;&lt;div&gt;&lt;div&gt;&lt;b&gt;Ctrl+Shift+F&lt;/b&gt; =&amp;gt; Find All.&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;F3&lt;/b&gt; =&amp;gt; Next match.&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;b&gt;Ctrl+Shift+F7&lt;/b&gt; =&amp;gt; Highlight usages. &lt;b&gt;Esc&lt;/b&gt; clears the highlight. Use it more than once is you will see it is a stack.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Alt+F7&lt;/b&gt; =&amp;gt; Find usages. Excellent for detecting the scope of a refactoring.&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Practice these until they are burned into your fingers. I honestly had to execute the command and watch my fingers.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-8431064456385631986?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/8431064456385631986/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/05/microtip-searching.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/8431064456385631986'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/8431064456385631986'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/05/microtip-searching.html' title='MicroTip: Searching'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-7241914577370495552</id><published>2011-05-06T19:53:00.000-07:00</published><updated>2011-05-06T19:56:49.059-07:00</updated><title type='text'>Ubuntu 11.04</title><content type='html'>I updated yesterday. So far, so good. Well, mostly. The top 2 options in my boot menu don't actually work, they just load a black screen and I have to power off the machine and try again. But the next option works like a champ and I get some nifty new features. I hope to figure out what those are in the near future . . .&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-7241914577370495552?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/7241914577370495552/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/05/ubuntu-1104.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/7241914577370495552'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/7241914577370495552'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/05/ubuntu-1104.html' title='Ubuntu 11.04'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-5645868623360047008</id><published>2011-05-05T22:17:00.000-07:00</published><updated>2011-05-06T20:58:46.632-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ReSharper'/><category scheme='http://www.blogger.com/atom/ns#' term='MicroTip'/><title type='text'>MicroTip: ReSharper Navigation</title><content type='html'>&lt;span style="font-style:italic;"&gt;I've read a couple times that the difference between the apprentice and the master performing a the same task isn't one big thing, it is many, many small things that together make a big difference. To that end, I am going to share the small things that help me work more efficiently under the title MicroTips. Here is the first of (hopefully) many:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.jetbrains.com/resharper/"&gt;ReSharper&lt;/a&gt; is a very powerful add-on for Visual Studio that improves the way one develops .NET code, but only if you know how to use it. (To see a ReSharper Jedi in action, go &lt;a href="http://www.viddler.com/explore/Lostechies/videos/1/"&gt;here&lt;/a&gt;.) One of the primary ways it improves one's ability to express thought in code is to eliminate the need to context switch from keyboard to mouse for navigation.&lt;br /&gt;&lt;br /&gt;First of all, you need to configure the keyboard shortcuts. Do yourself a favor and learn the IntelliJ IDEA shortcuts now, because you will eventually find the Visual Studio flavored shortcuts are inefficient as they each require 2 keystrokes for common activities while the IDEA shortcuts only require 1.&lt;br /&gt;&lt;br /&gt;Memorize and use (practice) these every time you need to navigate in your code:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Ctrl+N&lt;/b&gt; =&amp;gt; Navigate to Type by Name. Learn to use the CamelHumps to save typing and time.&lt;br /&gt;&lt;b&gt;Ctrl+B&lt;/b&gt; =&amp;gt; Navigate to Type under the cursor. This is the same as &lt;b&gt;Ctrl+Click&lt;/b&gt;, but better.&lt;br /&gt;&lt;b&gt;Ctrl+Shift+B&lt;/b&gt; =&amp;gt; Navigate to Derived Type (Implementation/Inheritor.) You will need this when properly coding to interfaces.&lt;br /&gt;&lt;b&gt;Ctrl+-&lt;/b&gt; =&amp;gt; Navigate back to previous location.&lt;br /&gt;&lt;b&gt;Ctrl+F12&lt;/b&gt; =&amp;gt; Navigate to class member by Name.&lt;br /&gt;&lt;b&gt;Ctrl+Alt+L&lt;/b&gt; =&amp;gt; Locate File in Solution Explorer. This one is useful when you need to move from the code behind to the markup in a web project. [&lt;b&gt;Ctrl+Alt+L&lt;/b&gt;, &lt;b&gt;Up Arrow&lt;/b&gt;, &lt;b&gt;Enter&lt;/b&gt;]&lt;br /&gt;&lt;b&gt;Ctrl+Shift+N&lt;/b&gt; =&amp;gt; Navigate to File by Name.&lt;br /&gt;&lt;br /&gt;Thats it for this time. Just getting around in your code. If you can't live without your mouse, try unplugging it for an hour and see if you can't figure out how to navigate your code with your keyboard.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-5645868623360047008?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/5645868623360047008/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/05/microtip-resharper-navigation.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/5645868623360047008'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/5645868623360047008'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/05/microtip-resharper-navigation.html' title='MicroTip: ReSharper Navigation'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-7624243322212542058</id><published>2011-04-27T20:08:00.000-07:00</published><updated>2011-04-28T14:14:22.744-07:00</updated><title type='text'>You’re not a software craftsman if…</title><content type='html'>Software craftsmanship is the new fad to replace ALT.NET and Agile as the cool thing to do if you actually like writing software.  This post is inspired by a recent post by &lt;a href="http://whitneyhess.com/blog/2011/04/23/youre-not-a-user-experience-designer-if/"&gt;Whitney Hess&lt;/a&gt; about UX designers.&lt;br /&gt;&lt;br /&gt;There is a lot of debate about that software craftsmanship means. See my &lt;a href="http://codeobsession.blogspot.com/2011/04/what-is-craftsman-what-is-software.html"&gt;previous post&lt;/a&gt; so you can get started on your education.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;YOU’RE NOT A SOFTWARE CRAFTSMAN IF… &lt;/h3&gt;&lt;ol style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 1.5em; margin-left: 40px; "&gt;&lt;/ol&gt;&lt;ol&gt;&lt;li&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal; "&gt;&lt;b&gt;You don't write code as a primary function of your job.&lt;/b&gt; Software craftsmanship is about &lt;i&gt;crafting software&lt;/i&gt;. It isn't about being a manager, scrum master or (PowerPoint) architect. It's about creating code that helps people. If you are &lt;i&gt;once&lt;/i&gt; involved directly in code, this doesn't count. A craftsman is involved in the craft, not a parallel/supporting craft.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;You aren't reading.&lt;/b&gt; Blogs, books, magazines (really? do people still get magazines?) are great sources of collective experience. You can't learn do it all on your own, so a wise programmer (person) attempts to learn from the experience of others. Personally, I would say you need to read at least 1 book per quarter and subscribe to a few blogs as well. My RSS feed list is over to the right somewhere. I don't read all the posts of course, but I read a lost of them.&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;You aren't working to solve a business need. &lt;/b&gt;Coding is great fun! Code can be art. If you aren't concerned with RIO (and this includes schedule,) you are not respecting the craft or the client. Artesanal software is lovely. Save it for open source projects done on your own time. Don't make your client pay for art, unless they ask for art. 999 times out of 1000, they ask for features. (There should probably be more 9s there.)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;You aren't participating in your community. &lt;/b&gt;There are plenty of ways to get involved. You can &lt;a href="http://codeobsession.blogspot.com/" title="You are here" alt="You are here"&gt;blog&lt;/a&gt;, &lt;a href="http://twitter.com/#!/davidadsit"&gt;tweet&lt;/a&gt;, go to &lt;a href="https://groups.google.com/forum/#!forum/ut-software-craftsmanship"&gt;user groups&lt;/a&gt; (&lt;a href="http://utahdnug.org/"&gt;.NET&lt;/a&gt;, &lt;a href="http://utruby.org/"&gt;Ruby&lt;/a&gt;) and contribute to &lt;a href="https://github.com/davidadsit"&gt;open source&lt;/a&gt;. You need to be involved to be a craftsman. You can't work in isolation. If you don't have a user group in your area, create one at work. I have done this at my last few jobs and it is an amazing way to improve the quality and quantity of the output of your shop.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;You aren't willing to learn from others.&lt;/b&gt; No one knows everything. &lt;a href="http://apprenticeship-patterns.labs.oreilly.com/ch02.html#expose_your_ignorance"&gt;Expose Your Ignorance&lt;/a&gt; isn't just for beginners. Almost everyone on your team knows more than you about something: (one of) the language(s), the domain, the data, something. Let them teach you. Seek out the knowledge they have. Paired programming is the easiest way I know to share knowledge amongst the developers on a team. Try it out.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;You horde your knowledge or act superior when you share it.&lt;/b&gt; We all learned from someone and we all need to learn from others. Sure you have original thoughts, ideas, and solutions, but they are based on what you learned from others and you shouldn't keep them from your team. If you are a dick when you explain set-based logic or design patterns, etc., people will stop asking you questions. This will prevent you from sharing and succeeding as a craftsman.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;You aren't improving your skills.&lt;/b&gt; Craftsmen value skill both in themselves and in others. &lt;a href="http://codingdojo.org/"&gt;Practice&lt;/a&gt;, &lt;a href="http://codekata.pragprog.com/"&gt;practice&lt;/a&gt;, &lt;a href="http://katas.softwarecraftsmanship.org/"&gt;practice&lt;/a&gt;. Then you can produce finer work when it is time to produce. Find your weaknesses and do something to improve in those areas. My C# and TSQL are strong, but web-fu (CSS, JavaScript) is kinda weak and so is my PL/SQL. I'm working on 'em.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;You aren't validating your code.&lt;/b&gt; For me this means automated tests both at the unit level and the acceptance level. For you this could mean manual regression after each feature. Actually, I think I would need to be convinced of the second option. You are in the business of automating work, but you do your own manually? Really? WTF? Automate that! We all know manual regression tests are boring and error prone.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;You only know one technology stack.&lt;/b&gt; This one is hard for me because I am a .NET developer. I have been doing C# since it came out and VB6/ASP/Visual C++ before that. I have been on the Microsoft stack for almost my whole career.  I know ASP.NET (WebForms &amp;amp; MVC), WinForms, WCF, SQLServer, IIS and Windows Server configuration. I don't know much about everything else. A craftsman needs to be able to compare and contrast more than one paradigm. I have been &lt;i&gt;trying&lt;/i&gt; to learn Ruby (w/Rails) development on Ubuntu for a year+. I have read about half of &lt;a href="http://www.amazon.com/Seven-Languages-Weeks-Programming-Programmers/dp/193435659X"&gt;Seven Languages in Seven Weeks&lt;/a&gt; and some of &lt;a href="http://www.amazon.com/Rails-NET-Developers-Facets-Ruby/dp/1934356204/"&gt;Rails for .NET Developers&lt;/a&gt;. It is hard to learn just for the sake of learning. The truth is you need to. Ruby has taught me &lt;a href="http://codeobsession.blogspot.com/2011/04/ruby-inspired-sugary-syntactical.html"&gt;better ways to C#&lt;/a&gt;.  My JavaScript has improved once I learned what a prototype language is and (some of) how jQuery works.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;You aren't passionate about code.&lt;/b&gt; When was the last time you were in an argument about what to name a variable? Software craftsmen care deeply about doing the right thing for the code and for the client. If this is just a way to pay the bills (and buy toys,) you are a laborer (code monkey.) If you aren't passionate, you aren't a craftsman.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;You aren't regularly delivering value.&lt;/b&gt; This means releasing on a scheduled cycle. It should be a short cycle.&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;You don't take responsibility for your own education.&lt;/b&gt; It is &lt;i&gt;awesome&lt;/i&gt; when employers provide training&lt;b&gt;.&lt;/b&gt; If yours doesn't, you can't use that as an excuse to stagnate. Find a mentor. Be a mentor. You and you alone is responsible to ensure that you stay current and relevant in this industry. I have never seen an resume with an "Excuses for why I only know a dead technology" section. If I did, I might laugh, but I wouldn't hire the guy.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;So, what would you add to this list? What would you take off?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I have written 3 previous versions of this article and thrown them all away because they didn't quite say what I meant. Hopefully this time it came together well.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-7624243322212542058?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/7624243322212542058/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/04/youre-not-software-craftsman-if.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/7624243322212542058'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/7624243322212542058'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/04/youre-not-software-craftsman-if.html' title='You’re not a software craftsman if…'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-7454535353999524071</id><published>2011-04-27T20:06:00.000-07:00</published><updated>2011-04-28T14:13:37.433-07:00</updated><title type='text'>What is a Software Craftsman?</title><content type='html'>What is a craftsman? What is a Software Craftsman? There is a lot of debate. Educate yourself and make up your own mind...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;This is a little old, but I wanted to make it available so that I could reference it in another post.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The Manifesto&lt;br /&gt;&lt;a href="http://manifesto.softwarecraftsmanship.org/" class="external-link" rel="nofollow"&gt;The Software Craftsmanship Manifesto&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The Book&lt;br /&gt;&lt;a href="http://www.amazon.com/Software-Craftsmanship-Imperative-Pete-McBreen/dp/0201733862/" class="external-link" rel="nofollow"&gt;Software Craftsmanship: The New Imperative&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The Other Book&lt;br /&gt;&lt;a href="http://apprenticeship-patterns.labs.oreilly.com/"&gt;Apprenticeship Patterns - Guidance for the Aspiring Software Craftsman&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Pete McBreen's Response to The Manifesto&lt;br /&gt;&lt;a href="http://www.improvingwetware.com/2011/01/20/software-craftsmanship-revisited" class="external-link" rel="nofollow"&gt;Software Craftsmanship Revisited&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;David Harvey speaks to the topic&lt;br /&gt;&lt;a href="http://www.infoq.com/presentations/Danger-Software-Craftsmen-at-Work" class="external-link" rel="nofollow"&gt;Danger! Software Craftsmen at Work&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Dan North starts a war&lt;br /&gt;&lt;a href="http://dannorth.net/2011/01/11/programming-is-not-a-craft/" class="external-link" rel="nofollow"&gt;Programming is not a craft&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Liz Keogh explains her discomfort with the software craftsmanship manifesto&lt;br /&gt;&lt;a href="http://lizkeogh.com/2011/01/14/why-i-didnt-sign-the-software-craftsmanship-manifesto/" class="external-link" rel="nofollow"&gt;Why I didn’t sign the Software Craftsmanship manifesto&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Gil Zilberfeld draws a comparison between software craftsmanship and alt.net&lt;br /&gt;&lt;a href="http://www.gilzilberfeld.com/2011/01/path-already-taken.html" class="external-link" rel="nofollow"&gt;The Path Already Taken&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Jason Gorman wants us to avoid getting hung up on labels&lt;br /&gt;&lt;a href="http://parlezuml.com/blog/?postid=992" class="external-link" rel="nofollow"&gt;Enough With The Software Holy Wars!&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Michael Feathers looks for more deliberate practice in our work&lt;br /&gt;&lt;a href="http://michaelfeathers.typepad.com/michael_feathers_blog/2011/01/the-thing-of-software-development.html" class="external-link" rel="nofollow"&gt;The Thing of Software Development&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;George Dinwiddie provides a physical example of why quality work is important to a customer, and how certification and licensing doesn't help&lt;br /&gt;&lt;a href="http://blog.gdinwiddie.com/2011/01/17/trades-crafts-and-certification/" class="external-link" rel="nofollow"&gt;Trades, Crafts, and Certification&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Martin Fowler summarizes and aggregates links&lt;br /&gt;&lt;a href="http://martinfowler.com/bliki/CraftmanshipAndTheCrevasse.html" class="external-link" rel="nofollow"&gt;CraftmanshipAndTheCrevasse&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Dan North expands and clarifies some his earlier points&lt;br /&gt;&lt;a href="http://dannorth.net/2011/01/15/on-craftsmanship/" class="external-link" rel="nofollow"&gt;On Craftsmanship&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Bob Martin says software craftsmanship is only about programmers tired of writing crap&lt;br /&gt;&lt;a href="http://cleancoder.posterous.com/software-craftsmanship-things-wars-commandmen" class="external-link" rel="nofollow"&gt;Software Craftsmanship: What it's all about.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Bob Martin thinks Martin Fowler's fears are groundless&lt;br /&gt;&lt;a href="http://cleancoder.posterous.com/individuals-and-interactions" class="external-link" rel="nofollow"&gt;Bringing Balance to the Force&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Glenn Vanderburg clarifies Software Engineering&lt;br /&gt;&lt;a href="http://confreaks.net/videos/282-lsrc2010-real-software-engineering"&gt;Real Software Engineering&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Mark Haskamp...it's kinda related and I liked it, so just watch it OK? You made it this far for a reason, here is your reward.&lt;br /&gt;&lt;a href="http://www.infoq.com/presentations/The-Code-is-the-Design"&gt;Code is the Design&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-7454535353999524071?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/7454535353999524071/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/04/what-is-craftsman-what-is-software.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/7454535353999524071'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/7454535353999524071'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/04/what-is-craftsman-what-is-software.html' title='What is a Software Craftsman?'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-6036905183292986671</id><published>2011-04-21T18:43:00.000-07:00</published><updated>2011-05-05T22:16:12.933-07:00</updated><title type='text'>Ruby Inspired Sugary Syntactical Goodness for C#</title><content type='html'>I have been playing with Ruby recently and it has lead me to want a couple of methods off of commonly used objects.  I have found myself typing each and times into my VS editor regularly rather than curse my primary language, I decided that I should just implement the the missing functions.  It is surprisingly easy to do.  Here are some snippets for you to drop into a static class:&lt;br /&gt;&lt;pre class="brush: csharp"&gt;&lt;br /&gt;//Each &amp; Times&lt;br /&gt;public static void Each&amp;lt;T&amp;gt;(this IEnumerable&amp;lt;T&amp;gt; enumerable, Action&amp;lt;T&amp;gt; block)&lt;br /&gt;{&lt;br /&gt; foreach (T item in enumerable)&lt;br /&gt; {&lt;br /&gt;  block.Invoke(item);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public static void Times(this int count, Action block)&lt;br /&gt;{&lt;br /&gt; for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt; {&lt;br /&gt;  block.Invoke();&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public static void Times(this int count, Action&amp;lt;int&amp;gt; block)&lt;br /&gt;{&lt;br /&gt; for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt; {&lt;br /&gt;  block.Invoke(i);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The usage should be fairly straightforward, but just in case you need a pointer, here is some code I took from one of my Bowling Game Kata practice sessions:&lt;br /&gt;&lt;pre class="brush: csharp"&gt;&lt;br /&gt;21.Times(() =&amp;gt; _game.Roll(0));&lt;br /&gt;...&lt;br /&gt;private void MultipleRolls(params int[] rolls)&lt;br /&gt;{&lt;br /&gt; rolls.Each(x =&amp;gt; _game.Roll(x));&lt;br /&gt;}&lt;br /&gt;...&lt;br /&gt;5.Times(x =&amp;gt; Console.Out.WriteLine("x = {0}", x));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Ok, so I faked the last one, but I think you get the picture.  Let me know if you think this is useful and please post any similar tips that you use in your code.&lt;br /&gt;&lt;br /&gt;UPDATE: I found some issues with the Each method. It works just find if you are using a concrete Enumerable. If you are using an Enumerable that is evaluated lazily like the results of Select, you will find that it cannot modify the content of your list because each time you enumerate, you will get new objects. I tried several options to resolve this, and they mostly turned the Each back into a Select, so I'm not sure about a clean solution for this one. If you call ToList() on your Enumberable before you call each, you might as well just use the ForEach() method on List&lt;T&gt;(). Still pondering if there is value. Every solution I think of reduces the clarity of the code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-6036905183292986671?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/6036905183292986671/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/04/ruby-inspired-sugary-syntactical.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/6036905183292986671'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/6036905183292986671'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/04/ruby-inspired-sugary-syntactical.html' title='Ruby Inspired Sugary Syntactical Goodness for C#'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-2342843610553270146</id><published>2011-04-10T18:34:00.000-07:00</published><updated>2011-04-10T20:44:34.496-07:00</updated><title type='text'>Review: Adrenaline Junkies and Template Zombies</title><content type='html'>This is another book in the project management vein. I put it in my &lt;a href="http://www.amazon.com/Adrenaline-Junkies-Template-Zombies-Understanding/dp/0932633676"&gt;Amazon&lt;/a&gt; wish list about a year and a half ago, though I only recently got around to buying it. I had a manager strongly dissuade me from reading it based on title. Apparently, Zombies are not approved work fare. ;-)&lt;br /&gt;&lt;br /&gt;On the one hand, this book was a fascinating read because so many of the patterns were familiar. Seeing that my experiences haven't been unique, but are often common enough that they have been identified and named was interesting to me. On the other hand, it was a little bit depressing because I had hoped that the industry was more mature than what I have experienced.  Apparently, there is a lot of opportunity for improvement everywhere.&lt;br /&gt;&lt;br /&gt;The idea of using patterns to describe software development project behaviors struck me as quite appropriate. Unfortunately, the book mostly just presents anecdotes and stories. The patterns all have catchy, if sometimes misleading, names and all have a distillation of the observations of the authors. They do not have any consistent presentation structure. Some patterns mention pros and cons. Some tell you when they should be applied. Some mention ways to implement them, while others just say what behaviors would destroy the pattern when it is already functioning. Maybe this is natural for a book on behavior patterns. In some way it feels unfinished, like the notes for a more detailed book to follow.&lt;br /&gt;&lt;br /&gt;Despite the anecdotal feel to the pattern presentation, this was an enjoyable read. I wish I had read the book earlier, it might have helped me identify and then avoid or correct some problems I have seen on teams I've worked with. After a quick review of the pattern names and summaries, I believe I have observed every one of them in the wild. Some only lasted for short periods, while others were long-running.&lt;br /&gt;&lt;br /&gt;This book will be of value to any managers/team leaders who are honestly seeking organizational improvement. Because of the natural proclivity humans have for pattern matching, being exposed to these patterns will help identify them when they occur. This, in turn, could facilitate guiding an organization or team away from the detrimental ones and toward the desirable ones.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-2342843610553270146?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/2342843610553270146/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/04/review-adrenaline-junkies-and-template.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/2342843610553270146'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/2342843610553270146'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/04/review-adrenaline-junkies-and-template.html' title='Review: Adrenaline Junkies and Template Zombies'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-1166813087470727656</id><published>2011-03-22T19:50:00.000-07:00</published><updated>2011-03-22T21:07:08.962-07:00</updated><title type='text'>Utah Code Camp</title><content type='html'>Saturday I attended the &lt;a href="http://www.utahcodecamp.com/"&gt;Utah Code Camp&lt;/a&gt;. Despite my previous lack of interest, I decided that this time I would attend out of curiosity if nothing else. I have been invited before, but it never seemed like a good way to spend a Saturday.  I have attended a few of the larger software conferences including SD Best Practices and SOA World/AJAX World as well as watching session videos from &lt;a href="http://www.ndc2010.no/"&gt;NDC&lt;/a&gt; and &lt;a href="http://www.infoq.com/"&gt;QCon&lt;/a&gt;. I wasn't really expecting much from a free, local conference.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Wow! I couldn't have been more wrong!  Saturday was amazing! I attended 4 sessions that introduced me to new technology and 2 sessions on topics that I a quite passionate about already.  All of the speakers were well prepared and interesting. The free lunch (provided by my employer: &lt;a href="http://www.stgutah.com/"&gt;STG&lt;/a&gt;) was also nice. I didn't win any prizes, but I wasn't really that interested in them anyway.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Introduction to Erlang&lt;/b&gt;&lt;/div&gt;&lt;div&gt;I have been meaning to learn a little about functional programming for a while. I am reading &lt;a href="http://www.amazon.com/Seven-Languages-Weeks-Programming-Programmers/dp/193435659X"&gt;7 Languages in 7 Weeks&lt;/a&gt; partially for the exposure to functional programming. The fact that &lt;a href="http://aspnetresources.com/home/about"&gt;Milan Negovian&lt;/a&gt; flew in from out of state to provide us with some insight into the how and why of FP was awesome. I am inspired to dive deeper into this different paradigm and especially Erlang thanks to his excellent talk.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Android Development&lt;/b&gt;&lt;/div&gt;&lt;div&gt;This was another new technology for me. I love my Droid 2 and I got it partially because of the open platform, but honestly, I haven't seriously considered writing any software for it. Now that I have seen how easy it can be, I am going to take a hard look at doing something there. Thanks to Jacob Glines for the intro.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Software Craftsmanship&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Obviously, this is a topic about which I am quite passionate. I enjoyed the solid introductory presentation by &lt;a href="http://blog.softwareontheside.com/"&gt;Mike Clement&lt;/a&gt;. The discussion afterward was quite enjoyable as well. I apologize to everyone if I talked &lt;i&gt;too&lt;/i&gt; much. ;-) Anyway, I wasn't even aware we had a local &lt;a href="https://groups.google.com/forum/#!forum/ut-software-craftsmanship"&gt;software craftsmanship&lt;/a&gt; group, but I have already put the monthly meetings on my calendar, so I hope to see you all there next month!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;What is FubuMVC?&lt;/b&gt;&lt;/div&gt;&lt;div&gt;I have followed &lt;a href="http://codebetter.com/jeremymiller/"&gt;Jeremy Miller&lt;/a&gt; on Code Better since I was first introduced to &lt;a href="http://www.jbrains.ca/permalink/how-test-driven-development-works-and-more"&gt;test driven development&lt;/a&gt; and the &lt;a href="http://martinfowler.com/eaaDev/PassiveScreen.html"&gt;MVP&lt;/a&gt; pattern in ASP.NET several years ago.  I have been aware of and interested in &lt;a href="http://fubumvc.com/"&gt;FubuMVC&lt;/a&gt; since its inception, but I haven't really researched it because I haven't had any opportunity to use it at work. I have been missing out. All of the rough spots in Microsoft's ASP.NET MVC are handled so much easier in FubuMVC. The lack of coupling to the framework is amazing. The conventions are elegant. I cannot wait to try this on a serious application. Thanks to &lt;a href="http://twitter.com/#!/murrayondotnet"&gt;Michael Murray&lt;/a&gt; did a great job presenting.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Distributed Systems&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://blog.jonathanoliver.com/"&gt;Jonathan Oliver&lt;/a&gt; is like an energetic version of &lt;a href="http://www.udidahan.com/"&gt;Udi Dahan&lt;/a&gt;. I saw Udi speak on &lt;a href="http://www.infoq.com/presentations/SOA-Business-Autonomous-Components"&gt;How to Avoid a Failed SOA&lt;/a&gt; at SD Best a few years ago. I have since been fascinated with the concept of building highly scalable distributed systems via pub/sub. I have worked hard to spread these ideas as a software architect and developer. Know I know who to call in for consulting when I need that outside voice of reason.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;RIAs and Node.js&lt;/b&gt;&lt;/div&gt;&lt;div&gt;This was new to me. I went with &lt;a href="https://github.com/dannycoates"&gt;Danny Coates&lt;/a&gt; who is the maintainer of &lt;a href="https://github.com/dannycoates/node-inspector"&gt;Node Inspector&lt;/a&gt; perhaps hoping that some of his genius would transfer during the presentation. Unfortunately, I didn't really learn much about Node.js in the talk except that it is going in the queue of things to learn, but not moving to the front for now. It seems interesting as an alternative, but I am not ready to invest much. The website that Jeff Willden presented was pretty slick and the reuse of models from client to server was quite interesting, however.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This was an excellent day of learning and (re-)connecting with other Utah developers. I can't wait for the next one and I encourage you all to attend!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-1166813087470727656?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/1166813087470727656/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/03/utah-code-camp.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/1166813087470727656'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/1166813087470727656'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/03/utah-code-camp.html' title='Utah Code Camp'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-6542283835011942286</id><published>2011-03-20T09:41:00.001-07:00</published><updated>2011-03-20T10:56:40.994-07:00</updated><title type='text'>Object Oriented Design Resources</title><content type='html'>I was recently asked where one might find some good resources on object oriented design.  Since the internet is full of free resources on the topic, I thought it might be useful to point out the ones that have helped me most.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Let's start with the &lt;a href="http://en.wikipedia.org/wiki/Solid_(object-oriented_design)"&gt;SOLID&lt;/a&gt; principles.  Roy Osherove is kind enough to host a &lt;a href="http://osherove.com/blog/2009/8/19/ndc-video-robert-martin-solid-principles-of-oo-class-design.html"&gt;video&lt;/a&gt; of the talk Uncle Bob Martin gave at the Norwegian Developers Conference in 2009 describing these principles.  Of course, you can always read the about the principles on Uncle Bob's &lt;a href="http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod"&gt;blog&lt;/a&gt;.  In addition to SOLID, Uncle Bob encourages us to create &lt;a href="http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882"&gt;Clean Code&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.jbrains.ca/permalink/how-test-driven-development-works-and-more"&gt;Test Driven Development&lt;/a&gt; is a known technique for building consistently well designed of software systems. As Michael Feathers &lt;a href="http://www.testingtv.com/2010/12/13/the-deep-synergy-between-testability-and-good-design/"&gt;demonstrates&lt;/a&gt;, unit testing in an excellent way to expose the flaws in your design.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Of course, one needs some idea of where to start, so learning about &lt;a href="http://www.infoq.com/minibooks/domain-driven-design-quickly"&gt;domain driven design&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Design_pattern_(computer_science)"&gt;design patterns&lt;/a&gt; and &lt;a href="http://martinfowler.com/eaaCatalog/"&gt;architectural patterns&lt;/a&gt; are all crucial.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-6542283835011942286?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/6542283835011942286/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/03/object-oriented-design-resources.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/6542283835011942286'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/6542283835011942286'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/03/object-oriented-design-resources.html' title='Object Oriented Design Resources'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-2140837273764006567</id><published>2011-03-15T18:24:00.000-07:00</published><updated>2011-04-10T20:47:53.567-07:00</updated><title type='text'>Wrapper Classes</title><content type='html'>A couple of the developers involved in our hiring process seem to be obsessed with the different wrapper patterns. That got me thinking about the differences between the &lt;a href="http://en.wikipedia.org/wiki/Decorator_pattern"&gt;Decorator&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Adapter_pattern"&gt;Adapter&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Facade_pattern"&gt;Facade&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Proxy_pattern"&gt;Proxy&lt;/a&gt; patterns.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here is a quick summary that compares and contrasts these four patterns:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;The &lt;b&gt;Decorator&lt;/b&gt; wraps a &lt;i&gt;single class&lt;/i&gt;, exposes the &lt;i&gt;same interface&lt;/i&gt; and &lt;i&gt;adds functionality&lt;/i&gt; to the wrapped class which is injected into the Decorator.&lt;/li&gt;&lt;li&gt;The &lt;b&gt;Adapter&lt;/b&gt; wraps a &lt;i&gt;single class&lt;/i&gt; and &lt;i&gt;changes its interface&lt;/i&gt; while &lt;i&gt;maintaining functionality&lt;/i&gt;. Usually this is done to make the class easier to use in the consuming system.&lt;/li&gt;&lt;li&gt;The &lt;b&gt;Facade&lt;/b&gt; wraps &lt;i&gt;multiple classes&lt;/i&gt; and provides a &lt;i&gt;simplified interface&lt;/i&gt; for using them together.&lt;/li&gt;&lt;li&gt;The &lt;b&gt;Proxy&lt;/b&gt; wraps a &lt;i&gt;single class&lt;/i&gt; and is similar to the Decorator in implementation, though it &lt;i&gt;does not extend the functionality&lt;/i&gt; of the class, but &lt;i&gt;hides an implementation detail&lt;/i&gt; such as network transport or lazy loading. The consumer shouldn't know it has a proxy rather than the real object.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;This isn't a lot of detail and includes no implementation examples, but it is enough to get you through our interview phone if you can talk about about each of those logically.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-2140837273764006567?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/2140837273764006567/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/03/wrapper-classes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/2140837273764006567'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/2140837273764006567'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/03/wrapper-classes.html' title='Wrapper Classes'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-1888426468254997575</id><published>2011-03-12T13:16:00.001-08:00</published><updated>2011-05-31T09:03:08.063-07:00</updated><title type='text'>Software Layers</title><content type='html'>TL;DR: Please learn the currently accepted definitions terms so that you can use them correctly.&lt;hr/&gt;I am regularly amazed to see developers, whose primary job function is &lt;a href="http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882"&gt;Applying Proper Names to Things&lt;/a&gt;, misapply new (to them) terms to well-known definitions. The most common example is probably calling your process &lt;a href="http://agilemanifesto.org/"&gt;agile&lt;/a&gt; whether or not it follows any of the &lt;a href="http://agilemanifesto.org/principles.html"&gt;principles&lt;/a&gt;. Who hasn't worked on a fixed bid, fixed scope, fixed date project and been told all along how "agile" the project is? The second you hear the phrase "scope creep," you know the customer isn't a priority and agile never made it to the table. While I am a huge proponent of XP (and I mean, by-the-book XP), I won't bore you with a rant on that topic.&lt;br /&gt;What concerns me is &lt;a href="http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215"&gt;Domain Driven Design&lt;/a&gt;. Domain Driven Design is a large subject that takes 100 pages to define &lt;a href="http://www.infoq.com/minibooks/domain-driven-design-quickly"&gt;&lt;span style="font-style:italic;"&gt;quickly&lt;/span&gt;&lt;/a&gt;. I supposed this contributes to the misuse of the term.&lt;br /&gt;Domain Driven Design defines 4 layers of an application: (User) Interface, Application, Domain, Infrastructure. Each of these layers contains business logic that is specific to a certain task.  Each of these layers relies on the layers (plural!) below it.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The Interface is pretty simple to define.  This is what is consumed by or visible to the user. It could be a rich desktop UI, a web site or a REST/WS-* service.  The Interface layer uses the Application layer, Domain layer and Infrastructure layer to accomplish it's task.&lt;/li&gt;&lt;li&gt;The Application layer is the coordinator of &lt;span style="font-style:italic;"&gt;what&lt;/span&gt; to &lt;span style="font-style:italic;"&gt;how&lt;/span&gt;. This thin layer expresses the rules of what the users want the application to do (use cases) in terms of the Domain. The Application layer is unlikely to contain any "reusable" code that could be put in another application.&lt;/li&gt;&lt;li&gt;The Domain layer is where the invariants of the business are expressed.  Entities, Value Objects and Services are part of this layer. This is likely to be a small nugget of solid gold in the heart of your application. This code has the most potential for reuse (if you believe in that kind of thing).  The Domain should be Persistence Ignorant.&lt;/li&gt;&lt;li&gt;The Infrastructure layer provides supporting libraries and state persistence mechanisms for the other layers.&lt;/li&gt;&lt;/ul&gt;OK, so what is the bazillion foot view of DDD. So, if that is how DDD is defined, why do I keep seeing a much different structure in the actual code on "Domain Driven" projects? Is there some algorithm that I haven't been exposed to that reduces the 4 layers of DDD to the three layers: Presentation, Business and Data? These sound an awful lot like the tiers of an n-Tier app, but I am regularly assured that they are layers now that we have learned &lt;a href="http://en.wikipedia.org/wiki/Fallacies_of_Distributed_Computing"&gt;RPC&lt;/a&gt; doesn't &lt;a href="http://en.wikipedia.org/wiki/CAP_theorem"&gt;scale&lt;/a&gt;.&lt;br /&gt;What causes me the most heartburn is the lack of an Application layer in this model. Where do I encode use cases of this software? If they aren't easy to express in the Business classes, they seem to end up in the Presentation...or sometimes the Database.&lt;br /&gt;The second thing that makes me uncomfortable is those Business classes. What purpose do they serve? Most often, they are placeholders for some future logic that we might discover someday but for now they just delegate directly to the Data layer. I will call your bluff on that one every single time. &lt;a href="http://en.wikipedia.org/wiki/YAGNI"&gt;YAGNI&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/David_Wheeler_(computer_scientist)"&gt;Dave Wheeler's&lt;/a&gt; famous quotation on indirection spring immediately to mind. I suppose could just be because I believe in the XP Value of Simplicity. Maybe it is because I have the Courage to change the software and it's architecture later if I find that it isn't meeting new needs. What ever it is, eliminate these pass-through classes and call the interface you really wanted to begin with.&lt;br /&gt;In summary, please learn the definition of a term &lt;a href="http://www.infoq.com/presentations/Deliberate-Discovery"&gt;before&lt;/a&gt; you use it. Don't redefine the unfamiliar term to mean something you already know. Don't assume you understand a complex definition just because you have heard all the word in the term before.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-1888426468254997575?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/1888426468254997575/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/03/application-layers.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/1888426468254997575'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/1888426468254997575'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/03/application-layers.html' title='Software Layers'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-8897867649519704521</id><published>2011-03-11T07:15:00.000-08:00</published><updated>2011-03-11T07:54:07.037-08:00</updated><title type='text'>Utah .NET User Group</title><content type='html'>Last night I attended the local &lt;a href="http://utahdnug.org/"&gt;.NET User Group&lt;/a&gt; for the first time. The speaker presented on MEF.  It was quite informative.  I fulling intend to use MEF to support the plugin feature of the &lt;a href="https://github.com/davidadsit/TeamFoundationServerDesktopBuildMonitor"&gt;TFS build notifier&lt;/a&gt; I am working on.&lt;br /&gt;&lt;br /&gt;It was fun to get the chance to talk to other .NET devs in the area, eat free pizza and hear about another tool for the toolbox.  I am not really convinced that MEF is a full IoC container and I am wasn't thrilled that all the examples were in Silverlight, but the talk was well prepared and Joe McBride (@XamlCoder) knew what he was talking about enough to stand up to Q&amp;A. :-)&lt;br /&gt;&lt;br /&gt;I actually was picked for 2 of the door prizes, but I declined them both.  I have been a die-hard &lt;a href="http://www.jetbrains.com/resharper/"&gt;ReSharper&lt;/a&gt; user for 4 years now, so &lt;a href="http://www.devexpress.com/Products/Visual_Studio_Add-in/Coding_Assistance/"&gt;CodeRush&lt;/a&gt; doesn't interest me in the slightest.  I also haven't done a desktop app in years (just Web and Server side development) so I declined the Infragistics components so that someone who will actually use them can have them.  It was funny how hard it was for them to give away &lt;a href="http://www.devexpress.com/Products/Visual_Studio_Add-in/Coding_Assistance/"&gt;CodeRush&lt;/a&gt;. I wasn't the only one who declined it.  They asked what software we &lt;span style="font-style:italic;"&gt;would&lt;/span&gt; want and I recommended &lt;a href="http://www.jetbrains.com/profiler/"&gt;dotTrace&lt;/a&gt; because (unlike &lt;a href="http://www.jetbrains.com/resharper/"&gt;ReSharper&lt;/a&gt;, &lt;a href="http://www.jetbrains.com/dotcover/"&gt;dotCover&lt;/a&gt; and &lt;a href="http://www.jetbrains.com/ruby/"&gt;RubyMine&lt;/a&gt;) I haven't been able to justify the cost for my personal projects.  ;-)&lt;br /&gt;&lt;br /&gt;I fully intend to make attendance at this user group part of my monthly schedule.  See you there next month!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-8897867649519704521?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/8897867649519704521/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/03/utah-net-user-group.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/8897867649519704521'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/8897867649519704521'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/03/utah-net-user-group.html' title='Utah .NET User Group'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-1974154479025487961</id><published>2011-02-28T08:55:00.001-08:00</published><updated>2011-02-28T08:55:14.542-08:00</updated><title type='text'>CodeRetreat - Conway's Game of Life</title><content type='html'>&lt;div&gt;&lt;p&gt;I wasn't able to justify a trip to Boulder for the CodeRetreat, but I wished I were there, so I watched JBrains virtual session video instead.&amp;#160; That inspired me to implement Game of Life in C#.&amp;#160; I created a GitHub repository and started test driving some code.&amp;#160; Eventually, I got something working, but I have some more ideas I want to try.&amp;#160; I want to add a World ctor that parses a string representing the initial state of the World.&amp;#160; I would also like to try putting a few different UIs on this including an MVC3 + Knockout.js view and maybe a WPF view.&lt;/p&gt;&lt;p&gt;Here is what I learned:&lt;br&gt;Get a pairing partner. I started to get tired around 1130 and I got lazy with the testing.&amp;#160; Now I need to go back and add tests and clean up some of the design that wasn't test driven.&lt;br&gt;Timebox things like this. CodeRetreat sessions ar 45 min. I realized I had been playing for hours when my wife asked if I was ever coming to bed.&lt;br&gt;Git is pretty frigging sweet.&amp;#160; I'm just getting familiar with it, but I like this DVCS stuff so far.&lt;br&gt;Game of Life is an interesting problem. The wikipedia article is worth a read.&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-1974154479025487961?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/1974154479025487961/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/02/coderetreat-conway-game-of-life.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/1974154479025487961'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/1974154479025487961'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/02/coderetreat-conway-game-of-life.html' title='CodeRetreat - Conway&amp;#39;s Game of Life'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-3817204925053149897</id><published>2011-02-21T14:00:00.000-08:00</published><updated>2011-02-21T14:07:16.163-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Books'/><title type='text'>Review: The Cathedral &amp; The Bazaar</title><content type='html'>I read it, I liked it, Blogger ate my post.&lt;br /&gt;&lt;br /&gt;First, it helped inspire me to try Linux, which is no mean feat for a die hard Windows guy like me.  (I haven't even turned on my iMac in the last year.)&lt;br /&gt;&lt;br /&gt;Second, the management essay added at the end was the most important part to me.  The main point being that OSS works well because the participants self select and are passionate about that they are spending their precious time on.  Cube dwelling devs may not be so passionate or skilled, and their output reflects that.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-3817204925053149897?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/3817204925053149897/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/02/review-cathedral-bazaar.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/3817204925053149897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/3817204925053149897'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/02/review-cathedral-bazaar.html' title='Review: The Cathedral &amp;amp; The Bazaar'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-7397623258900740577</id><published>2011-02-13T15:26:00.000-08:00</published><updated>2011-02-13T15:26:58.853-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Books'/><title type='text'>Review: The Passionate Programmer</title><content type='html'>&lt;p&gt;Chad Fowler's book is all about building a successful career in software development. &amp;nbsp;When I read that sentence, 2 questions immediately come to mind: what's in it for me (as a developer)? and what's in it for me (as a business owner/manager/project manager/etc)? &amp;nbsp;Well the answer to the first question is pretty obvious: what I get out of a successful career is happiness, money, purpose, etc. &amp;nbsp;What does my employeer get out of it? &amp;nbsp;Well, a happy, motivated, driven developer. &amp;nbsp;Why does that matter? &amp;nbsp;Happy, motivated people produce more and better work. &amp;nbsp;So now we have covered the most rudimentary of why, let's look at how this book helps.&lt;/p&gt;&lt;div&gt;There are 5 sections in the book:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Choosing your market&lt;/li&gt;&lt;li&gt;Investing in your product&lt;/li&gt;&lt;li&gt;Executing&lt;/li&gt;&lt;li&gt;Marketing... not just for suits&lt;/li&gt;&lt;li&gt;Maintaining your edge&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Choosing your market&lt;/strong&gt; talks to the importance of being aware of what you do and how it related to the larger picture. &amp;nbsp;Are you .NET developer? &amp;nbsp;Why? &amp;nbsp;Why aren't you a Ruby developer? &amp;nbsp;Or a Java developer? &amp;nbsp;Or a COBOL developer? &amp;nbsp;Or a DBA? &amp;nbsp;Did you make a conscious decision to go into this area or did it just happen? &amp;nbsp;Are you in control of the direction of your career? &amp;nbsp;Are you specialized? &amp;nbsp;Will that help you or hurt you in the short term? &amp;nbsp;Medium term? Long term? &amp;nbsp;Make sure that you know what path you are on, why you are on it and how you will change if that path disappears.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Investing in your product&lt;/strong&gt; is about improving in the areas you have chosen. &amp;nbsp;Learn continuously from those around you. &amp;nbsp;Help those you can. &amp;nbsp;Read, study, practice.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Executing&lt;/strong&gt;&amp;nbsp;is make yourself indispensable (not because no one can do what you do, but because you are constantly bringing so much new value to the team/project.) &amp;nbsp;Executing is also being honest: working hard and saying "No" when the answer really is "no."&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Marketing&lt;/strong&gt; is about managing perceptions because they really do matter. &amp;nbsp;Make sure people around you know who you are, what you do and why that matters. &amp;nbsp;Become a brand. &amp;nbsp;Get your name known on not just in your company, but in the industry.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Maintaining your edge&lt;/strong&gt; is a pretty obvious need. &amp;nbsp;You have to always be improving because the industry is always moving and if you stand still, you will be left behind.&lt;/p&gt;&lt;div&gt;The 53 short essays in this book will help you focus on what you need to do to have an exceptional career that takes you where YOU want to go. &amp;nbsp;I was pleasantly surprised at how many of the recommendations I am already following. &amp;nbsp;I was also amazed at how much work I still have ahead of me. &amp;nbsp;This book can be very useful in providing you with a direction and a starting point. &amp;nbsp;Each essay has an Act On It section that gives you specific advice on how to improve your career right now.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-7397623258900740577?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/7397623258900740577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/02/review-passionate-programmer.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/7397623258900740577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/7397623258900740577'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/02/review-passionate-programmer.html' title='Review: The Passionate Programmer'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-1282730692938120013</id><published>2011-02-13T12:35:00.000-08:00</published><updated>2011-02-13T13:21:24.066-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Ubuntu...</title><content type='html'>Well, after 10+ years of exclusively using Windows, I am now dual booting Win7 and Ubuntu on my laptop.  So far, so good.  Only complaint so far is that when I tried to install Ruby from the command shell, apt-get was out of date and as a noob to this platform, the error messages didn't make any sense.  A quick google search and I had the answer: sudo apt-get update.  Anyway, Ruby is installed.  Vim is installed.  Chrome is installed.  I wrote this post in Chrome from Ubuntu.  More to come.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-1282730692938120013?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/1282730692938120013/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/02/ubuntu-vm.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/1282730692938120013'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/1282730692938120013'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/02/ubuntu-vm.html' title='Ubuntu...'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-6247556776338354556</id><published>2011-02-12T19:36:00.000-08:00</published><updated>2011-02-12T20:19:27.721-08:00</updated><title type='text'>Respect - The Currency of IT</title><content type='html'>Just ready Jeff Ello's article &lt;a href="http://www.computerworld.com/s/article/9137708/Opinion_The_unspoken_truth_about_managing_geeks"&gt;The Unspoken Truth About Managing Geeks&lt;/a&gt; (thanks to Michael Feathers for tweeting it.)  Jeff talks about the stereotypically negative behaviors of software developers and how organizations can deal effectively with these behaviors.&lt;br /&gt;&lt;br /&gt;The part of the article that I found most interesting is the discussion of respect: how to earn it, how to keep it, how to lose it.  I can attest to the fact that respect is the number one factor in my reactions to those I work with.  I have worked with a team lead who was pushy, bossy, rude and consistently corrected my code and coding style (he even took away my mouse because it was a crutch.)  Why did I put up with it?  Well, he was an order of magnitude better than I was and I &lt;del&gt;wanted&lt;/del&gt; needed to learn from him.  I would go home from work mentally exhausted from paired programming, but at the end of several months, I felt like Neo in the training construct: I knew TDD.  I knew how to separate concerns and used dependency injection and refactor bad code.  I had never have learned so much so quickly in my previous 7 years as a professional coder.  The best part was that as I began to actually understand the concepts, not just the forms, he listened to me and talk to me as a peer.  I was gaining his respect.  Had the company we worked for managed their finances better, I imagine I would still be working and following the lead of this great developer today.&lt;br /&gt;&lt;br /&gt;Contrast that with another job where I worked for a team lead who had completely stagnated.  He would quote from books that he studied at university 15 years earlier as though they were the final word on technology.  He clung tightly to his outdated data and information.  While a fun guy to hang out with, he never earned the respect of the team and, though regularly promoted, he has become completely irrelevant to the ongoing development efforts of the company.  In large part, my departure from that company was due to the fact that I couldn't bring myself to respect the leadership team.  They would regularly make deeply technical decisions for the teams for which they were completely unprepared (and counter to the advice of the expert developers on those teams.)  The advice from on high was often illogical and sometimes contradictory.&lt;br /&gt;&lt;br /&gt;All in all, the idea that technical prowess leads to respect and respect leads to effective cooperation rings very true to me.  I feel as though reading this article has helped me more fully understand my own psyche and motivations in the workplace.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-6247556776338354556?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/6247556776338354556/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/02/respect-currency-of-it.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/6247556776338354556'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/6247556776338354556'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/02/respect-currency-of-it.html' title='Respect - The Currency of IT'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-338753830115463078</id><published>2011-02-07T18:49:00.000-08:00</published><updated>2011-02-07T20:53:06.749-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Software Craftsmanship'/><title type='text'>What Software Craftsmanship Means to Me</title><content type='html'>Throughout the recent debate catalyzed by &lt;a href="http://dannorth.net/2011/01/11/programming-is-not-a-craft/"&gt;Dan North&lt;/a&gt;, I have spent a significant amount of time thinking about what this profession is that I have chosen to pursue and what it means to me.  During the debate Corey Haines and Dan had on Twitter today, my thoughts crystallized and I felt compelled to record them.  I doubt that many will read this, but if nothing else, it will allow me to measure my progress when I come back and reread it later.&lt;br /&gt;&lt;br /&gt;While I self identify as a Software Craftsman, like Corey, I find that I agree with Dan regarding the movement.  Maybe I agree with Dan &lt;span style="font-style:italic;"&gt;because&lt;/span&gt; I self identify as a craftsman.  No one else calls me a craftsman.  There was no exam, no council of masters, just me and a desire to write less crappy software.  So what does it all mean?  What is Software Craftsmanship?&lt;br /&gt;&lt;br /&gt;Well, it means &lt;a href="http://cleancoder.posterous.com/software-craftsmanship-things-wars-commandmen"&gt;not writing crap code&lt;/a&gt;, obviously!  But what is crap code?  I have never in the last 10 years worked with a developer who set out to write crap code.  Working at a Fortune 100 company with annual releases, a team that laughed at the one guy doing unit testing and code that could fill hundreds of &lt;a href="http://thedailywtf.com/"&gt;Daily WTF&lt;/a&gt; posts, we were all doing the best we knew how and trying to regularly (every single year!) produce value for our customers.  Were we Software Craftsmen?  I guess so.  I mean, nothing in the &lt;a href="http://manifesto.softwarecraftsmanship.org/"&gt;manifesto&lt;/a&gt; would contradict that assertion.&lt;br /&gt;&lt;br /&gt;So what is Software Craftsmanship?  More importantly, what &lt;span style="font-style:italic;"&gt;isn't&lt;/span&gt; Software Craftsmanship?  I think the Ri answer is "Software Craftsmanship is doing the right thing."  That isn't likely the Shu or Ha answer.  Who knows what they are?  I guess it depends, right?  ;-)&lt;div&gt;&lt;br /&gt;I'm in no position to define this movement, but I will share my thoughts anyway.  What else are blogs for, right?&lt;ul&gt;&lt;li&gt;First and foremost, Software Craftsmanship requires constant self improvement through study and practice.  This includes learning from the experience of others (books, blogs, discussion groups, Twitter, etc.) and willingly sharing your knowledge and experience with those in the community, especially your coworkers. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;Software Craftsmanship favors &lt;a href="http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882"&gt;Clean Code (as defined by Robert Martin)&lt;/a&gt;: concise, expressive code with limited duplication, (many) single responsibility classes and clear abstractions.  Learn about and apply the correct design principles and patterns for your solution.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Software Craftsmanship insists on testable code with high levels of code coverage.  This is more important than some grand design with perfect abstractions and encapsulation.  Let the tests guide your design.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Software Craftsmanship emphasizes maintenance and enhancement of existing systems rather than regularly attempting to recreate what a business has already paid to build.  It can take years for a new system to repay the high initial development investment.  If we let it fall into disrepair and demand a rewrite just as the company breaks even, we are not adding business value, we are destroying it. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;Software Craftsmanship favors Domain Driven Design rather than Data Driven Design or RAD.  RAD tools emphasize the creation phase at the expense of the maintenance phase of a system's life cycle.  Data Driven Design produces systems that are bound to a database implementation, generally less expressive of the intentions of the solution and likely run into performance and scalability limitations (vendor promises not withstanding.) &lt;/li&gt;&lt;br /&gt;&lt;li&gt;Software Craftsmanship prefers simple over configurable, Little Design Up Front over Big Design Up Front, flexible code over extensive frameworks.&lt;/li&gt;&lt;/ul&gt;Well crap!  That looks like it could have been part of a manifesto for &lt;a href="http://www.gilzilberfeld.com/2011/01/path-already-taken.html"&gt;Alt.NET&lt;/a&gt;!  Is Software Craftsmanship repeating the past?  What have we learned that makes this time different?  I don't know.  All I know is that I have been trying to regularly and consistently improve my skills, share what I know and inspire those around me to improve so we can stop producing quite so much crap.  Any advice on how to do that better is certainly welcome.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-338753830115463078?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/338753830115463078/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/02/what-software-craftsmanship-means-to-me.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/338753830115463078'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/338753830115463078'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/02/what-software-craftsmanship-means-to-me.html' title='What Software Craftsmanship Means to Me'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-3661597132693722349</id><published>2011-01-30T21:47:00.000-08:00</published><updated>2011-01-30T22:27:38.225-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Books'/><title type='text'>Review: Domain-Driven Design Quickly</title><content type='html'>This book, available for free download on InfoQ.com, is an excellent intro to/summary of Evans' DDD book.  What I really appreciate about this book is that at 104 pages it is short enough I can recommend it even to my near-illiterate developer friends who would never attempt to tackle Evans' 560 pages. ;-)&lt;br /&gt;The definitions of the key terms in Domain Modeling are clear and concise.  The examples are short and simple which forces them to cut straight to the heart of the concept they demonstrate.&lt;br /&gt;While this book doesn't go as deep as Evans' book, it is excellent as a review or intro.  I intend to have my entire team read through it asap during our ongoing training.  &lt;br /&gt;Key to Domain-Driven Design is the concept of the Ubiquitous Language.  This book helps define the terms used in the Ubiquitous Language of software development.  Communication is the key to success in our industry and having a common language facilitates quick, clear communication between developers.  Read the book, learn the language, communicate more clearly, build better software.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-3661597132693722349?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/3661597132693722349/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/01/review-domain-driven-design-quickly.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/3661597132693722349'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/3661597132693722349'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/01/review-domain-driven-design-quickly.html' title='Review: Domain-Driven Design Quickly'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-5984584343224933348</id><published>2011-01-28T22:36:00.000-08:00</published><updated>2011-01-28T22:49:31.158-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Books'/><title type='text'>Review: Facts and Fallacies of Software Engineering</title><content type='html'>Robert Glass' Facts and Fallacies of Software Engineering was an interesting read because it focuses so much on the research that has been done in our field.  Contrast that with the much more common anecdotal teaching style and this book becomes very valuable for the industry.  Honestly, most of the facts are well known, they just may not be accepted as facts.  This is a quick read and worthwhile.  The emphasis on research and evidence alone is worthwhile.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-5984584343224933348?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/5984584343224933348/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/01/review-facts-and-fallacies-of-software.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/5984584343224933348'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/5984584343224933348'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/01/review-facts-and-fallacies-of-software.html' title='Review: Facts and Fallacies of Software Engineering'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-2657578642817310480</id><published>2011-01-28T22:16:00.001-08:00</published><updated>2011-01-28T22:36:01.070-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Books'/><title type='text'>Review: Software Craftsmanship</title><content type='html'>I recently read Pete McBreen's Software Craftsmanship: The New Imperative.  This was a pretty interesting book and it was excellent timing because I finished it just before Dan North published his &lt;a href="http://dannorth.net/2011/01/11/programming-is-not-a-craft/"&gt;post&lt;/a&gt; that set off an avalanche of debate about the topic.&lt;br /&gt;&lt;br /&gt;What can I say... Hmm.  After all the debate, I still consider myself to be a craftsman.  Why?  That is an interesting question.  I think that there is misunderstanding about the movement.  I think craftsmanship is all about building maintainable software and training the next generation of programmers to build maintainable software.  As a professional, ROI is king.  Everything I do, from personal study to TDD to CI to leading group discussions about the craft is so that my team can produce better, more maintainable software that produces &lt;b&gt;long term&lt;/b&gt; business value.  This is what makes me a craftsman.  I have seen too many projects lose focus and become unmaintainable piles of crap.  I have seen too many failed rewrites.  I have seen too much money wasted by people who should know better.&lt;br /&gt;&lt;br /&gt;The training aspect of craftsmanship alone intrigues me.  When I think about the early part of my career, I get pissed off at the vast about of time I spent following blind alleys and being essentially undirected.  I have to thank Ross and the guys at FARVV for getting me started in the right direction.  I only wish I had received that kind of instruction much earlier.&lt;br /&gt;&lt;br /&gt;There are a lot of other interesting points made in the book and in the follow up posts that responded to Dan.  I think that anyone who considers himself a craftsman/tradesman/professional software engineer of any sort would be well served to be aware of the debate and why it is ongoing.  The more we know, the better off our industry as a whole will operate.&lt;br /&gt;&lt;br /&gt;Ok, so that wasn't a very focused review.  I think you should read the book.  Put it at the front of your reading queue.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-2657578642817310480?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/2657578642817310480/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2011/01/review-software-craftsmanship.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/2657578642817310480'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/2657578642817310480'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2011/01/review-software-craftsmanship.html' title='Review: Software Craftsmanship'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-5381904242395218092</id><published>2010-12-30T22:54:00.000-08:00</published><updated>2010-12-30T23:18:13.340-08:00</updated><title type='text'>Why I don't post on this blog</title><content type='html'>When I started the blog, I thought I would share a lot of my experiences and thoughts about software development.  After all, I am code obsessed.  I read and think about code almost as much as I actually code.  &lt;br /&gt;&lt;br /&gt;What I have learned about myself is that I don't really have much desire to write about what I read and think about.  The reason for this is simple: I feel it is all derivative.  What I mean by that is that any serious developer has read read Clean Code, Pragmatic Programmer, Refactor, Refactoring to Pattern, Patterns of Enterprise Application Architecture, Agile Software Development, Service Oriented Architecture, SOA in Practice, Domain Driven Design, Applying Domain-Driven Design and Patterns, Head First Design Patterns, Facts and Fallacies of Software Engineering, Pro ASP.NET MVC Framework, Practices of an Agile Developer, the 97 Things books, etc, etc. He/she also probably follows blogs like Los Techies, DotNetKicks, Object Mentor, InfoQ, Joel on Software, Martin Fowler, Dan North, Ayende, Jeremy D Miller, etc, etc.  And he/she undoubtedly attended or watched the session videos from conferences like SDBest or NDC.&lt;br /&gt;&lt;br /&gt;Anyway, what I'm saying is that I think that most of my thoughts on software craftsmanship aren't new.  They are all regurgitated wisdom of smarter people than me.  With only 11 years in this craft, I'm just a journeyman with so much to learn.  I advise you to follow some of the masters of our craft and only involve me if you are having an interesting conversation that I won't detract from too much.  I do LOVE to talk about software development after all... ;-)&lt;br /&gt;&lt;br /&gt;-DA&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-5381904242395218092?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/5381904242395218092/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2010/12/why-i-dont-post-on-this-blog.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/5381904242395218092'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/5381904242395218092'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2010/12/why-i-dont-post-on-this-blog.html' title='Why I don&apos;t post on this blog'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-2902972867886884159</id><published>2009-05-10T01:06:00.000-07:00</published><updated>2009-05-10T01:15:51.286-07:00</updated><title type='text'>StructureMap</title><content type='html'>I've been using a ServiceLocator class for IoC for the last year and a half.  Never really got the point of the containers until the last week.  We had a strange API requirement for a component for another group.  I didn't agree with it, but basically, they wouldn't let us do constructor or setter injection of the dependencies.  Let's not get into that, but lets just say that grabbing StructureMap 2.5 and throwing it into the mix saved me a ton of time.  Also, I now get it.  The container took what would have been 30-50 lines of ServiceLocator.cs and made it less than a dozen.  And they were very clean and easy to read.  And since you can initialize the objectfactory where ever you need to, I was still able to test those blocks and get a high level of coverage.&lt;br /&gt;&lt;br /&gt;I have been using RhinoMocks since I first started TDD and I am pretty fond of it.  The AutoMocker in StuctureMap has forced me to shift from the using(mocks.Record()){}... style to the Arrange-Act-Assert style.  I'm comfortable with the other style, but I will admit that this would be easier to teach to beginners (provided you leave the AutoMocking out of it, of course!)&lt;br /&gt;&lt;br /&gt;Anyway, I wonder now if I should spend a little time looking into Castle Windor and see which I prefer. . .&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-2902972867886884159?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/2902972867886884159/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2009/05/structuremap.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/2902972867886884159'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/2902972867886884159'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2009/05/structuremap.html' title='StructureMap'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-5963262952601098832</id><published>2009-05-10T00:41:00.000-07:00</published><updated>2009-05-10T01:02:58.031-07:00</updated><title type='text'>Training Materials...</title><content type='html'>So after realizing that the 10,000 page book on ASP.NET is better as a reference than as a training guide (seems like someone said that several times before we started this book), we voted on whether to read Clean Code or Refactoring to Patterns next.  Considering the make up of our team and the state of our code, I lobbied fairly hard to get Clean Code in front of everyone before we dive into patterns (again).&lt;br /&gt;&lt;br /&gt;It seems that a lot of our more experienced developers are pretty resistant to reading Clean Code.  I think there is a mentality that "the way I do it is right and there is no need to change or improve."  I think that is pretty sad.  I read Clean Code a few months ago, and it has helped me vastly.  It is amazing how much more maintainable my code is now.&lt;br /&gt;&lt;br /&gt;Anyway, I think that for my team (we have not quite a 3 to 1 ratio of juniors to seniors) we need to have a purpose to our refactoring.  Making our code more readable and reducing our coupling seems like a pretty worthy purpose.  I shudder at the thought of a couple of juniors pairing together and going pattern crazy on some code block that should be simple and straight forward.  Don't get me wrong, I think that design patterns are a great idea.  I look forward to reading Refactoring to Patterns when it comes up in my personal queue.  I just prefer that our mentoring/training take a more methodical approach.&lt;br /&gt;&lt;br /&gt;When I finally convinced my team to start using MVP, I had juniors come up to me and tell me that "this new pattern doesn't make my code any more testable at all!"  When I looked at the implementations, they had usually done a Supervising Controller and but all of the business logic in the view.  Go figure.  When you implement the wrong pattern, or misunderstand the pattern, you don't see any of the benefits of the pattern.  It seems likely to me that reading a patterns book is going to take us right down that path again.&lt;br /&gt;&lt;br /&gt;Ah well, democracy worked and the correct book was selected.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-5963262952601098832?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/5963262952601098832/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2009/05/training-materials.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/5963262952601098832'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/5963262952601098832'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2009/05/training-materials.html' title='Training Materials...'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-7717676772120505445</id><published>2009-02-06T18:27:00.000-08:00</published><updated>2009-02-06T18:39:49.160-08:00</updated><title type='text'>Friends don't let friends leave code dirty</title><content type='html'>So it turns out that I prefer writing code to writing about code, but I just finished reading Uncle Bob's "Clean Code: A Handbook of Agile Software Craftsmanship."  I highly recommend it.  This book very clearly addresses the large majority of the issues I face every day at work.  Our environment is full of code that works, but was never finished.  In other words, the code is a mess.  I'm passing the book around work hoping that it will help spread the vision.  Hopefully, we pick it up as one of our next training books for the whole team.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-7717676772120505445?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/7717676772120505445/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2009/02/friends-dont-let-friends-leave-code.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/7717676772120505445'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/7717676772120505445'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2009/02/friends-dont-let-friends-leave-code.html' title='Friends don&apos;t let friends leave code dirty'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-3706078975886317085</id><published>2008-11-10T21:12:00.000-08:00</published><updated>2008-11-14T08:52:57.577-08:00</updated><title type='text'>Software Design Speak</title><content type='html'>I went to SD Best in Boston, and I have been thinking a lot about what made some of those sessions. While I continue to gather my thoughts about that experience, here is something to keep you entertained:&lt;br /&gt;&lt;br /&gt;Often I say things to my coworkers about software design that are the result of a lot of research and time spent in contemplation. The problem is that I usually just give a 1 or 2 sentence summary of the idea and expect my coworkers to just get it. Or at least they could just assume I am right and we can move forward from there (too bad that doesn't ever happen).&lt;br /&gt;I think that the biggest problem I have communicating my thoughts and ideas is one of nomenclature. We use a lot of terms that are heavily overloaded and can have a lot of definitions. I think it will help if I define some terms as I understand them based on my study. I have shared this with my coworkers and invited them to comment and add their own definitions. So far, there are no takers. I'm pretty sure none of them have even read it. I guess they would rather argue with me than speak a common language.&lt;br /&gt;&lt;br /&gt;Anyway, here goes the Dictionary of Dave as well as what I think of as the more traditionalist approach to these topics.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="LINE-HEIGHT: 115%;font-size:130%;" &gt;Business Object&lt;br /&gt;&lt;/span&gt;My Opinion&lt;/b&gt; - A business object is any representation of a business rule, requirement or concept as a code structure. Examples include: ThankYou page, Order object, RxDAO repository, etc.&lt;br /&gt;&lt;b&gt;What I think of as a more traditionalist view&lt;/b&gt; - A business object is a specific type of component that fits between the UI and the database. These objects have a lot of functionality like loading themselves from the data layer, saving themselves to the data layer, executing rules validation on themselves, etc. Basically, these are buffers that completely isolate the UI from the Database. They most often (if not always) instantiate the data layer object(s) that they need to perform persistence work. Examples include: most of the classes in the CTAC.Core namespace (not child namespaces), anything CSLA, most objects that I wrote between 2002 and 2006, etc.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="LINE-HEIGHT: 115%;font-size:130%;" &gt;Domain Object&lt;br /&gt;&lt;/span&gt;Dave&lt;/b&gt; - A domain object is a specific type of business object that encapsulates a business concept. Often these are referred to as Entities when reading about code. They are composed of primitives and other Domain objects. They enforce rules related to the data they represent and provide a simple, yet specific (read type-safe) way to deal with that data. Examples include: Rx, Customer, etc.&lt;br /&gt;&lt;b&gt;Traditionalist&lt;/b&gt; - What's a Domain object? Did you mean data transfer object, cause we have plenty of those, if you need to push an instance of a business object somewhere over a wire or something.&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="LINE-HEIGHT: 115%;font-size:130%;" &gt;Service (Module)&lt;br /&gt;&lt;/span&gt;Dave&lt;/b&gt; - Well, this is a fairly simple and ubiquitous type of object. Basically, Services are any object that performs work on Domain objects. Common types of services are Repositories and Presenters. Since the Domain objects have no knowledge of persistence, UI or any other external component, the Services must perform these types of actions on the Domain objects. Services should always implement an interface to loosen the coupling, allow for mocking and facilitate inversion of control. Examples include: the SessionState wrapper, all the DAOs, etc.&lt;br /&gt;&lt;b&gt;Traditionalist&lt;/b&gt; - All of this functionality is encompassed by the business objects, so there isn't really a need for these Services of which you speak.&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="LINE-HEIGHT: 115%;font-size:130%;" &gt;Service (SOA)&lt;br /&gt;&lt;/span&gt;Dave&lt;/b&gt; - An SOA service is basically a business unit. It can be implemented using any type of design or architecture and doesn't need to share any of these decisions with its sister Services. It can have a separate data store of a different type than its sisters also. Basically, a service is an application or business silo that exposes part of its functionality to other parts of a company for their consumption. Because it owns the rules, logic, data, etc for the entire process, it can share its functionality by exposing web services, COM+, MSMQ or any other communication method. Examples include: the Email Sending Service and the Tax Service (I think).&lt;br /&gt;&lt;b&gt;Traditionalist&lt;/b&gt; - Well, this is easy! It is anything that has a web service, duh! The more the better! In fact, every single business object should have at least one web service that is somehow related to it. We should probably implement the Data Layer as web services too. That way, we can use those Data Transfer objects more. Yippee!&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="LINE-HEIGHT: 115%;font-size:130%;" &gt;n-Tier Architecture&lt;br /&gt;&lt;/span&gt;Dave&lt;/b&gt; - This is a step in the evolution of software development and it was a big one. Before this, everything was procedural or event driven and we didn't have a lot of structure. N-Tier gave us some structure and helped protect us from the retardedness of having data access in the UI or HTML generated in a stored procedure, etc. There are some problems, but every solution brings problems and overall, we were much better off than ever before.&lt;br /&gt;&lt;b&gt;Traditionalist&lt;/b&gt; - What do you think we have been talking about this whole time? N-Tier is the only way to make software. You have to have layers, just like an onion...or is it a cake? Anyway, the layers protect us and wrap us in warm goodness. Layers rule and we should try to have at least N of them.&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="LINE-HEIGHT: 115%;font-size:130%;" &gt;Modular Architecture&lt;br /&gt;&lt;/span&gt;Dave&lt;/b&gt; - This is the next step in evolution. The tiers were heavy and sometimes seemed contrived or difficult to work with. We had separation of layers, but we didn't really gain much by way of decoupling. In fact, we were often more coupled than before we adopted n-Tier because creating the UI objects automatically created business and data layer objects. The basic idea of the Modular software design is to create Domain objects and Services that are self contained and can be used independently. You don't restrict who has access to what; you just make sure that each piece does what it says it will do. When you need a thing, you grab that thing and use it (hopefully using the dependency injection pattern). This means that sometimes a UI component (like a Presenter) will have a reference to a Repository or some such.&lt;span style="font-size:+0;"&gt; &lt;/span&gt;Under n-Tier, it was considered a huge rules violation for the UI to even have knowledge that a data layer (or data service under my definition), but under the modular design, there is no such restriction, so no problem. Components are loosely coupled and can be assembled as needed to create whatever components or features the business requires.&lt;span style="font-size:+0;"&gt; &lt;/span&gt;No heavy infrastructure has to be created to make use of the components you need. Part of the advantage to this design is that you can create software vertically in slices rather than horizontally in layers (meaning that a feature can be implemented from UI to data as a single story). Because of the fact that every component is separate and loosely coupled, the components can be developed and tested independently. This allows for a more agile approach to development and results in software that is more maintainable.&lt;br /&gt;&lt;b&gt;Traditionalist&lt;/b&gt; - I'm not sure what you are even talking about here. N-Tier is the final evolution of software design. There is no need for anything beyond that.&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-3706078975886317085?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/3706078975886317085/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2008/11/software-design-speak.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/3706078975886317085'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/3706078975886317085'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2008/11/software-design-speak.html' title='Software Design Speak'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-1482431218467443972</id><published>2008-10-19T18:18:00.001-07:00</published><updated>2008-10-19T22:23:51.020-07:00</updated><title type='text'>Paired Programming - Who? What? When? Where? Why? and How? . . .</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Cheese Pairing for this Post: &lt;/span&gt;&lt;span style="font-style: italic;"&gt;blue stilton&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;[ugh.  much like the meeting, this cheese leaves me irritated and with a slight taste of vomit in my mouth that I can't seem to shake for the rest of the day]&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;So the other day at work, we had a meeting to discuss Paired Programming.  The Outlook invite said something about "Improving Paired Programming," but from the time we started, it felt a lot more like "Bitching about Paired Programming."  At one point, while we were listing a few things we like about it, one of our managers actually said, "Let's stop giving text book answers and talk about the real world."  As I am a huge fan of the technique, I have to vent/rant a little and get my opinions out there.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What&lt;/span&gt; (is&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;Paired Programming)&lt;span style="font-weight: bold;"&gt;?&lt;br /&gt;&lt;/span&gt;Just so we are on the same page, allow me to assert some preconditions for the follow discussion.  When I say paired programming, I am talking about 2 developers, 1 computer, 1 story/bug/issue to work on.  I prefer to have 2 keyboards and 2 mice as well, but that is a matter of personal taste and I can understand why some people prefer to only have one of each.  Anyway, that is it.  That is all I am talking about.  Two programmers, one driving, one navigating (when done properly) or sleeping (when not done properly).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Why&lt;/span&gt; (do&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;Paired Programming)&lt;span style="font-weight: bold;"&gt;?&lt;br /&gt;&lt;/span&gt;This is the big one, eh?  For those of us who have been doing it for a while, it seems like a no brainer, but let's review for the heck of it.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Let's start with the reason that is least important.  We have a business requirement that all production code be reviewed before going to QA and paired programming satisfies that requirement.  I called this the least important reason why to do paired programming, but it is actually pretty significant.  The alternative is that we perform code reviews after the code has been written.  Scientific studies (I read a couple somewhere. . . .you have google, you find 'em) as well as lots of personal, anecdotal evidence prove to me that code reviews after the fact are a less effective way of preventing faults from reaching QA.  Time is always a constraint during a review.  How many minutes does it take to properly cover all the enhancements, refactorings and reasons behind them that went into 35 hours of work in the last week?  And who wants to take that time when they have their own 35 hours of work to get done? If it compiles and passes the tests that the developer wrote for it, that has often been enough to pass any code reviews I have seen.  And, since we already mentioned time constraints, if the review happens at the end of the cycle, and the reviewer(s) see an architectural or design flaw, do they mention it?  Do you just let it go to get the feature out and add that to the technical debt pile?  Do you throw it back to the developer, or another developer, to rework it for the next iteration?  These types of issues are reduced when you have 2 sets of eyes on the thing throughout.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Two heads are better than one!  I just touched on this a little, but let's face it; two developers looking at the same issue are going to come up with a better design/solution than one developer.  If they see the solution differently, they can discuss it and come up with something better than either would have done alone.  Even if they have the same solution, that at the least is confirmation that it is a workable one.&lt;/li&gt;&lt;li&gt;It is less likely that 2 people are going to break the rules than one alone.  Let's be honest, how many times have you been under a deadline and, even though you know that you need to test, and you are totally committed to working test driven and then you hit up against some legacy code that is just not designed for testability, and you just say, "Screw it, I don't have time to do this right! Add it to the technical debt.  QA will do integration testing on this anyway, right?"  If your pair is sitting there, you will probably just man up and do it, right?  Another flavor of this is coding standards.  If your company uses one that isn't the same as you use at home, you may just slip into your own habits.  A pair is going to say, "What are you doing?" before you get to the second private field without an underscore.  I've tried, honest, but I'm just not feeling that underscore, guys.&lt;/li&gt;&lt;li&gt;This is a simple one, but important.  That second set of eyes is going to notice your goofs quicker than you are.  If you are really in the groove and you instantiate a CardProcessor where you needed a CartProcessor, a pair who is awake will take away the keyboard and call you a moron or at the very least ask you why you are doing it.  Even when it isn't a logic flaw, but just something that the compiler or the tests will catch, it is still quicker to get it before that, eh?&lt;/li&gt;&lt;li&gt;Here is a BIG one: Training.  None of us knows everything.  I know, that hurts to hear, huh?  Well, I said it so I think I may need a Vicodin.  But let's face it, there are so many things to know from CSS, JQuery, ASP.NET, C#, T-SQL, TDD, not to mention the Domain itself, that having someone there who may have more experience in at least part of one of these areas can be a big benefit.  The good thing about it is that you can just ask them right there and then you own the knowledge too.  You don't have to go in search of that-one-guy-who-works-wierd-hours-and-lives-in-a-cave-and-drinks-too-much-Monster and admit to him that you don't know why the subprocessor written in assembly when you were 3 years old is returning a certain value when you pass it the following parameters.  Your pair has that knowledge already. . . .or at least he has your back when you are in the C-monster's lair.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;In summary, the whys include: Cause I said so!, Code Reviews Suck, 2 Big Brains &gt; 1 Big Brain, Standards, You Can't Type, It's Not a Ubiquitous Language if Only One Person Speaks It.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;How&lt;/span&gt; (should you&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;Pair)&lt;span style="font-weight: bold;"&gt;?&lt;br /&gt;&lt;/span&gt;There are lots of ways.  Just do it comes to mind.  Recommendations I have are as follows:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Change pairs often!  Daily ought to be enough.  Twice a day if you work 4-Tens (lucky jerk).  This rule applies even when you are working on a multiday story.  I would say even especially when it is a long story.  I would put 2 guys on it on day 1, take one of those guys off on day 2 and replace him with someone else.  On day 3, take the remaining guy from day 1 off and replace him.  There are several advantages to this.  Getting stale means getting sloppy.  Bringing on the new guy means explaining what you did.  This will probably happen pretty quickly. . . .Unless he asks you, "Uh, are you high?  Why did you do it like that?"  Then you get to hear his solution.  Between where you were and where he thinks you should be, you may find a better solution.  Good thing he showed up on day 2, rather than day 25, huh?&lt;/li&gt;&lt;li&gt;Also, change pairs often!  You know that one guy you can't stand?  Working with him all week could make you even crazier than you already are, eh?  It is worth noting that you are that guy, at least to one member of your team.&lt;/li&gt;&lt;li&gt;Team Leads ought to select the pairs.  Or at least be involved.  The reason for this is that, given the option, we are most likely to just work with our friends every day.  Let me tell you, that is fun.  Also, it is fairly inefficient when it comes to knowledge transfer.  Team leads ought to be making pairing assignments based on some overall plan for the team.  Certain members may be weak in some areas and should be paired with those who are stronger in those areas to bring them up to speed.  They also may chose to pair a couple of seniors together on particularly challenging issues, at least for the initial design. There may also be some constraints, such as one on our team that states that a pair may not consist entirely of contractors.  Assigning the pairs will also cause more mixing and this can help the team members become closer and make communication easier and more open.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;When pairing, the more knowledgeable member should be the one navigating and writing the tests.  By having the guy who knows what is going on write the tests, he can make sure they are correct, and he can also explain to the other guy the why it needs to be done in a certain way.  This means that you will be changing drivers often.  Coder A writes a little test, Coder B writes a little code.  Repeat.  When you are of equal knowledge on the subject, just mix it up.  A writes a test.  B implements it.  B writes the next test.  A implements it.  Repeat.  By swapping drivers often, you make sure that you are both involved.&lt;/li&gt;&lt;li&gt;Ask Questions!  This shouldn't even need to be said, but it does.  Whether you are the junior pair, senior pair, new guy on the team, expert with 20 years experience, it doesn't matter.  That guy sitting next to you knows something you don't.  He may be using a hotkey you don't know, or possibly a design pattern you aren't familiar with.  Big or small, he has some knowledge you need, and you need to ask him for it.  Don't be afraid to ask for it.&lt;/li&gt;&lt;/ol&gt;In summary, the hows include: Change Pairs, Change Drivers, Ask Questions.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;When &lt;/span&gt;(should you&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;Pair)&lt;span style="font-weight: bold;"&gt;?&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;br /&gt;This depends on your environment.  I say, as much as possible.  At the very least, for everything that is going into production.  For us, we start pairing right after Morning Standup and pair until the end of the day.  Since this is about 7 hours for us, that means only 35 hours a week of pairing.  I heard some of the guys whining about how they never get a chance to do any personal research on the domain, tools, etc, and I gotta say, that is pretty weak, 'cause we really are supposed to work 40+ hours a week.  Since all of our meetings fall inside the pairing hours, it seems like there are at least 5 hours a week when you could be doing personal research, or writing more tests (as long as you aren't writing any production code), or asking questions, or whatever.  Do you need a list of things to research that you may not be an expert on?  Start here: .NET 3.5 framework, ASP.NET, Ajax, JQuery, CSS, C#, TSQL, NAnt, CruiseControl.NET, TDD, NUnit, RhinoMocks, WatiN, ReSharper (and its plugins), TFS, Better source control than TFS (why can't we all just use SVN?), GoF Patterns, Patterns of Enterprise Architecture, Inversion of Control and the Dependency Injection Pattern, .NET MVC framework, Linq, MFP, MFC, MVP, Our Domain.  If you are an expert on all that, you are hired 'cause we don't have one on staff.  On second thought, you are not hired, cause you are lying.  And if you aren't lying, and you really are an expert on all that, we can't afford you.  Anyway, there is a lot to learn and you don't need to pair to do it.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;Where &lt;/span&gt;(should you&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;Pair)&lt;span style="font-weight: bold;"&gt;?&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;br /&gt;I think you ought to pair in the same room with the rest of the team.  This allows for easier communication and greater camaraderie.   You know how you don't know everything? (Sorry to bring that up again)  Well, your pairing partner doesn't either, so it might help if you don't have to go trekking around to find the guy who does.  I know that this doesn't work in every environment, but if you can do it, I think you should.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Who &lt;/span&gt;(should Pair)&lt;span style="font-weight: bold;"&gt;?&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;     &lt;/span&gt;Simple.  Everyone who is working on production code.&lt;/li&gt;&lt;li&gt;Teams who want to make high quality software quickly, with few defects.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Also, everyone who wants to learn from another member of the team.&lt;/li&gt;&lt;li&gt;Anyone who thinks they know something worth teaching to another member of the team.&lt;/li&gt;&lt;li&gt;Umm, if you aren't in one of those categories, do you even have source code access?  Please say no.&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-weight: bold;"&gt;Summary&lt;/span&gt;&lt;br /&gt;Paired programming is an excellent methodology if you want to create a software package that is maintainable.  Done right, it enhances the quality and the velocity of software development.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Well, there's my ten cents, my two cents is free. . . &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Sorry.  If you made it this far, you didn't deserve an Eminem quote.  I really do apologize.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-1482431218467443972?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/1482431218467443972/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2008/10/paired-programming-who-what-when-where.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/1482431218467443972'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/1482431218467443972'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2008/10/paired-programming-who-what-when-where.html' title='Paired Programming - Who? What? When? Where? Why? and How? . . .'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-5359680871051429946</id><published>2008-10-08T06:00:00.000-07:00</published><updated>2008-10-19T22:54:15.695-07:00</updated><title type='text'>Live Templates . . .</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Cheese Pairing for this Post: &lt;/span&gt;&lt;span style="font-style: italic;"&gt;Beecher's One-Year Aged Flagship Cheddar&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;[mmm.  that's tasty]&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Live templates in ReSharper are an excellent time saving tool.  They allow you to put code that you use over and over into a shortcut that you don't have to retype it all the time or maintain it in files external to Visual Studio.&lt;br /&gt;&lt;br /&gt;I have a few that I've created to make my life easier.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;test&lt;/span&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;[Test]&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; $TESTNAME$()&lt;br /&gt;{&lt;br /&gt; $END$&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;rhino&lt;/span&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;[Test]&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; $TESTNAME$()&lt;br /&gt;{&lt;br /&gt; $END$&lt;br /&gt; &lt;span class="kwrd"&gt;using&lt;/span&gt;(mocks.Record())&lt;br /&gt; {&lt;br /&gt;  &lt;br /&gt; }&lt;br /&gt; &lt;span class="kwrd"&gt;using&lt;/span&gt;(mocks.Playback())&lt;br /&gt; {&lt;br /&gt;  &lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;tostring&lt;/span&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ToString()&lt;br /&gt;{&lt;br /&gt;  MemoryStream memoryStream = &lt;span class="kwrd"&gt;new&lt;/span&gt; MemoryStream();&lt;br /&gt;  XmlSerializer xmlSerializer = &lt;span class="kwrd"&gt;new&lt;/span&gt; XmlSerializer(GetType());&lt;br /&gt;  XmlTextWriter xmlTextWriter = &lt;span class="kwrd"&gt;new&lt;/span&gt; XmlTextWriter(memoryStream, Encoding.UTF7)&lt;br /&gt;                                    {&lt;br /&gt;                                        Formatting = Formatting.Indented,&lt;br /&gt;                                        Indentation = 1,&lt;br /&gt;                                        IndentChar = &lt;span class="str"&gt;'\t'&lt;/span&gt;&lt;br /&gt;                                    };&lt;br /&gt;  xmlSerializer.Serialize(xmlTextWriter, &lt;span class="kwrd"&gt;this&lt;/span&gt;);&lt;br /&gt;  memoryStream = (MemoryStream) xmlTextWriter.BaseStream;&lt;br /&gt;  UTF7Encoding encoding = &lt;span class="kwrd"&gt;new&lt;/span&gt; UTF7Encoding();&lt;br /&gt;  &lt;span class="kwrd"&gt;return&lt;/span&gt; encoding.GetString(memoryStream.ToArray()).Replace(&lt;span class="str"&gt;"&amp;gt;&amp;lt;"&lt;/span&gt;, &lt;span class="str"&gt;"&amp;gt;\r\n&amp;lt;"&lt;/span&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This last one works great for figuring out where the differences are when you get an expectation error in one of your tests.  Just throw that XML string from the test output into WinMerge and done.  Also, I would like to point out for anyone who isn't aware, there is a hotkey in R# to automatically implement IEquatable and override Equals: Alt+Ins, E.  Brilliant stuff.  The only issue is that you need to update it (Alt+Ins, E will do that too) every time you change your object.  That helps with those stubborn objects that tend to get compared by reference when you want to just compare their values. &lt;br /&gt;&lt;br /&gt;Sorry about the delay on this post.  Apparently, my blog was flagged as spam for a while.  All is better not though.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-5359680871051429946?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/5359680871051429946/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2008/10/live-templates.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/5359680871051429946'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/5359680871051429946'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2008/10/live-templates.html' title='Live Templates . . .'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-5043783598621985721</id><published>2008-10-06T06:00:00.000-07:00</published><updated>2008-10-06T06:00:01.234-07:00</updated><title type='text'>ReSharper Code Cleanup . . .</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Cheese Pairing for this Post: &lt;/span&gt;&lt;span style="font-style: italic;"&gt;Jarlsberg&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;[my favorite emmentaler; jarlsberg is excellent for snacking or sandwiches]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;ReSharper will automatically clean and organize your code for you according to your specifications.  The default specs are great; however, I find that I like to put my methods, field, etc in a slightly different order.  Here is the config that I use.  The only enhancement I still want to add is sorting auto properties before properties that have a backing member rather than intermixed.  I haven't figured out how to accomplish that yet, so if anyone knows, please post the answer in the comments, thanks.&lt;br /&gt;&lt;br /&gt;Without further ado:&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="html"&gt;xml&lt;/span&gt; &lt;span class="attr"&gt;version&lt;/span&gt;&lt;span class="kwrd"&gt;="1.0"&lt;/span&gt; &lt;span class="attr"&gt;encoding&lt;/span&gt;&lt;span class="kwrd"&gt;="utf-8"&lt;/span&gt; ?&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Patterns&lt;/span&gt; &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;="urn:shemas-jetbrains-com:member-reordering-patterns"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;&amp;lt;!--Do not reorder COM interfaces--&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Pattern&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;And&lt;/span&gt; &lt;span class="attr"&gt;Weight&lt;/span&gt;&lt;span class="kwrd"&gt;="100"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Kind&lt;/span&gt; &lt;span class="attr"&gt;Is&lt;/span&gt;&lt;span class="kwrd"&gt;="interface"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;HasAttribute&lt;/span&gt; &lt;span class="attr"&gt;CLRName&lt;/span&gt;&lt;span class="kwrd"&gt;="System.Runtime.InteropServices.InterfaceTypeAttribute"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;And&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Pattern&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;&amp;lt;!--Special formatting of NUnit test fixture--&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Pattern&lt;/span&gt; &lt;span class="attr"&gt;RemoveAllRegions&lt;/span&gt;&lt;span class="kwrd"&gt;="true"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;And&lt;/span&gt; &lt;span class="attr"&gt;Weight&lt;/span&gt;&lt;span class="kwrd"&gt;="100"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Kind&lt;/span&gt; &lt;span class="attr"&gt;Is&lt;/span&gt;&lt;span class="kwrd"&gt;="class"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;HasAttribute&lt;/span&gt; &lt;span class="attr"&gt;CLRName&lt;/span&gt;&lt;span class="kwrd"&gt;="NUnit.Framework.TestFixtureAttribute"&lt;/span&gt; &lt;span class="attr"&gt;Inherit&lt;/span&gt;&lt;span class="kwrd"&gt;="true"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;And&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;&amp;lt;!--Setup/Teardow--&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;And&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Kind&lt;/span&gt; &lt;span class="attr"&gt;Is&lt;/span&gt;&lt;span class="kwrd"&gt;="method"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Or&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;HasAttribute&lt;/span&gt; &lt;span class="attr"&gt;CLRName&lt;/span&gt;&lt;span class="kwrd"&gt;="NUnit.Framework.SetUpAttribute"&lt;/span&gt; &lt;span class="attr"&gt;Inherit&lt;/span&gt;&lt;span class="kwrd"&gt;="true"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;HasAttribute&lt;/span&gt; &lt;span class="attr"&gt;CLRName&lt;/span&gt;&lt;span class="kwrd"&gt;="NUnit.Framework.TearDownAttribute"&lt;/span&gt; &lt;span class="attr"&gt;Inherit&lt;/span&gt;&lt;span class="kwrd"&gt;="true"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;HasAttribute&lt;/span&gt; &lt;span class="attr"&gt;CLRName&lt;/span&gt;&lt;span class="kwrd"&gt;="NUnit.Framework.FixtureSetUpAttribute"&lt;/span&gt; &lt;span class="attr"&gt;Inherit&lt;/span&gt;&lt;span class="kwrd"&gt;="true"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;HasAttribute&lt;/span&gt; &lt;span class="attr"&gt;CLRName&lt;/span&gt;&lt;span class="kwrd"&gt;="NUnit.Framework.FixtureTearDownAttribute"&lt;/span&gt; &lt;span class="attr"&gt;Inherit&lt;/span&gt;&lt;span class="kwrd"&gt;="true"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Or&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;And&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;&amp;lt;!--All other members--&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;&amp;lt;!--Test methods--&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;And&lt;/span&gt; &lt;span class="attr"&gt;Weight&lt;/span&gt;&lt;span class="kwrd"&gt;="100"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Kind&lt;/span&gt; &lt;span class="attr"&gt;Is&lt;/span&gt;&lt;span class="kwrd"&gt;="method"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;HasAttribute&lt;/span&gt; &lt;span class="attr"&gt;CLRName&lt;/span&gt;&lt;span class="kwrd"&gt;="NUnit.Framework.TestAttribute"&lt;/span&gt; &lt;span class="attr"&gt;Inherit&lt;/span&gt;&lt;span class="kwrd"&gt;="false"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;And&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Pattern&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;&amp;lt;!--Default pattern--&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Pattern&lt;/span&gt; &lt;span class="attr"&gt;RemoveAllRegions&lt;/span&gt;&lt;span class="kwrd"&gt;="true"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;&amp;lt;!--delegate--&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;And&lt;/span&gt; &lt;span class="attr"&gt;Weight&lt;/span&gt;&lt;span class="kwrd"&gt;="100"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Access&lt;/span&gt; &lt;span class="attr"&gt;Is&lt;/span&gt;&lt;span class="kwrd"&gt;="public"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Kind&lt;/span&gt; &lt;span class="attr"&gt;Is&lt;/span&gt;&lt;span class="kwrd"&gt;="delegate"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;And&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Access&lt;/span&gt; &lt;span class="attr"&gt;Order&lt;/span&gt;&lt;span class="kwrd"&gt;="public protected internal private"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;&amp;lt;!--enums--&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Kind&lt;/span&gt; &lt;span class="attr"&gt;Is&lt;/span&gt;&lt;span class="kwrd"&gt;="enum"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Access&lt;/span&gt; &lt;span class="attr"&gt;Order&lt;/span&gt;&lt;span class="kwrd"&gt;="public protected internal private"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;&amp;lt;!--constants--&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Kind&lt;/span&gt; &lt;span class="attr"&gt;Is&lt;/span&gt;&lt;span class="kwrd"&gt;="constant"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Access&lt;/span&gt; &lt;span class="attr"&gt;Order&lt;/span&gt;&lt;span class="kwrd"&gt;="public protected internal private"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;&amp;lt;!--static and readonly fields--&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;And&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Kind&lt;/span&gt; &lt;span class="attr"&gt;Is&lt;/span&gt;&lt;span class="kwrd"&gt;="field"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Or&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Static&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Readonly&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Or&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;And&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Access&lt;/span&gt; &lt;span class="attr"&gt;Order&lt;/span&gt;&lt;span class="kwrd"&gt;="public protected internal private"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;&amp;lt;!--fields--&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Kind&lt;/span&gt; &lt;span class="attr"&gt;Is&lt;/span&gt;&lt;span class="kwrd"&gt;="field"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Access&lt;/span&gt; &lt;span class="attr"&gt;Order&lt;/span&gt;&lt;span class="kwrd"&gt;="public protected internal private"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;&amp;lt;!--Constructors. Place static one first--&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Kind&lt;/span&gt; &lt;span class="attr"&gt;Is&lt;/span&gt;&lt;span class="kwrd"&gt;="constructor"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Static&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Access&lt;/span&gt; &lt;span class="attr"&gt;Order&lt;/span&gt;&lt;span class="kwrd"&gt;="public protected internal private"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;&amp;lt;!--Destructors. Place static one first--&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Kind&lt;/span&gt; &lt;span class="attr"&gt;Is&lt;/span&gt;&lt;span class="kwrd"&gt;="destructor"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Static&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Access&lt;/span&gt; &lt;span class="attr"&gt;Order&lt;/span&gt;&lt;span class="kwrd"&gt;="public protected internal private"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;&amp;lt;!--Instance indexers--&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;And&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Kind&lt;/span&gt; &lt;span class="attr"&gt;Is&lt;/span&gt;&lt;span class="kwrd"&gt;="indexer"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Not&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Static&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Not&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;And&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Access&lt;/span&gt; &lt;span class="attr"&gt;Order&lt;/span&gt;&lt;span class="kwrd"&gt;="public protected internal private"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Abstract&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Virtual&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Override&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;&amp;lt;!--instance properties--&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;And&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Kind&lt;/span&gt; &lt;span class="attr"&gt;Is&lt;/span&gt;&lt;span class="kwrd"&gt;="property"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Not&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Static&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Not&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Not&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Kind&lt;/span&gt; &lt;span class="attr"&gt;Is&lt;/span&gt;&lt;span class="kwrd"&gt;="indexer"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Not&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;And&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Access&lt;/span&gt; &lt;span class="attr"&gt;Order&lt;/span&gt;&lt;span class="kwrd"&gt;="public protected internal private"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Abstract&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Virtual&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Override&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;&amp;lt;!--Methods--&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;And&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Kind&lt;/span&gt; &lt;span class="attr"&gt;Is&lt;/span&gt;&lt;span class="kwrd"&gt;="method"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Not&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Static&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Not&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Not&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;HandlesEvent&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Not&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Not&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Kind&lt;/span&gt; &lt;span class="attr"&gt;Is&lt;/span&gt;&lt;span class="kwrd"&gt;="destructor"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Not&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;And&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Access&lt;/span&gt; &lt;span class="attr"&gt;Order&lt;/span&gt;&lt;span class="kwrd"&gt;="public protected internal private"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Abstract&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Virtual&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Override&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;&amp;lt;!--Event Handling--&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;HandlesEvent&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Access&lt;/span&gt; &lt;span class="attr"&gt;Order&lt;/span&gt;&lt;span class="kwrd"&gt;="public protected internal private"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Abstract&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Virtual&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Override&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;&amp;lt;!-- event --&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Kind&lt;/span&gt; &lt;span class="attr"&gt;Is&lt;/span&gt;&lt;span class="kwrd"&gt;="event"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Access&lt;/span&gt; &lt;span class="attr"&gt;Order&lt;/span&gt;&lt;span class="kwrd"&gt;="public protected internal private"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;&amp;lt;!-- operator --&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Kind&lt;/span&gt; &lt;span class="attr"&gt;Is&lt;/span&gt;&lt;span class="kwrd"&gt;="operator"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Access&lt;/span&gt; &lt;span class="attr"&gt;Order&lt;/span&gt;&lt;span class="kwrd"&gt;="public protected internal private"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;&amp;lt;!--Class indexers--&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;And&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Kind&lt;/span&gt; &lt;span class="attr"&gt;Is&lt;/span&gt;&lt;span class="kwrd"&gt;="indexer"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Static&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;And&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Access&lt;/span&gt; &lt;span class="attr"&gt;Order&lt;/span&gt;&lt;span class="kwrd"&gt;="public protected internal private"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Abstract&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Virtual&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Override&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;&amp;lt;!--Class properties--&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;And&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Kind&lt;/span&gt; &lt;span class="attr"&gt;Is&lt;/span&gt;&lt;span class="kwrd"&gt;="property"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Static&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;And&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Access&lt;/span&gt; &lt;span class="attr"&gt;Order&lt;/span&gt;&lt;span class="kwrd"&gt;="public protected internal private"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Abstract&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Virtual&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Override&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;&amp;lt;!--Class Methods--&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;And&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Kind&lt;/span&gt; &lt;span class="attr"&gt;Is&lt;/span&gt;&lt;span class="kwrd"&gt;="method"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Static&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;And&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Access&lt;/span&gt; &lt;span class="attr"&gt;Order&lt;/span&gt;&lt;span class="kwrd"&gt;="public protected internal private"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Abstract&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Virtual&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Override&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;&amp;lt;!--all other members--&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Access&lt;/span&gt; &lt;span class="attr"&gt;Order&lt;/span&gt;&lt;span class="kwrd"&gt;="public protected internal private"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Abstract&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Virtual&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Override&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;&amp;lt;!--nested types--&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Kind&lt;/span&gt; &lt;span class="attr"&gt;Is&lt;/span&gt;&lt;span class="kwrd"&gt;="type"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Match&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sort&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Entry&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Pattern&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Patterns&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-5043783598621985721?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/5043783598621985721/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2008/10/resharper-code-cleanup.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/5043783598621985721'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/5043783598621985721'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2008/10/resharper-code-cleanup.html' title='ReSharper Code Cleanup . . .'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-1872986441637210226</id><published>2008-10-02T06:00:00.001-07:00</published><updated>2008-10-02T06:00:02.248-07:00</updated><title type='text'>Qualities of a Good Unit Test . . .</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Cheese Pairing for this Post: &lt;/span&gt;&lt;span style="font-style: italic;"&gt;sm&lt;/span&gt;&lt;span style="font-style: italic;"&gt;oked gouda&lt;br /&gt;&lt;span style="font-size:78%;"&gt;[this is something great for every day consumption; try some on toast]&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;So I was looking through some of the documents I have used for presentations in the office and I thought this was an interesting one:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Atomic&lt;/span&gt;&lt;br /&gt;&lt;div&gt;A unit test should only test a small piece of functionality. &lt;/div&gt;&lt;div&gt;A litmus test is to ask if any part of the unit test could stand alone in a separate unit test. &lt;/div&gt;Another feedback loop for your unit testing quality is the amount of time you spend with the debugger. If your unit tests are coarse, a test failure is more difficult to find. If the unit test exercises a small amount of code, the test failure cause can usually be spotted very quickly.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;span style="font-weight: bold;"&gt;Order Independent &amp;amp; Isolated&lt;/span&gt;&lt;br /&gt;There should never be an order dependency, intentional or not, between unit tests. &lt;/div&gt;&lt;div&gt;Problems arise when one unit test leaves some kind of dirty data lying around. Testing against a database or some sort of static cache is a common culprit. &lt;/div&gt;Put evil, stateful things behind nice, deterministic mocks or stubs.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Intention Revealing&lt;/span&gt;&lt;br /&gt;&lt;div&gt;A unit test can, and should, be a valuable form of documentation. &lt;/div&gt;&lt;div&gt;Unit tests are part of the contract that software implements.&lt;/div&gt;&lt;div&gt;A unit test provides a sample of the expected usage of the code.&lt;br /&gt;&lt;/div&gt;Excessive data setup can obfuscate a unit test beyond any hope of comprehension.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Easy to Setup&lt;/span&gt;&lt;span&gt;&lt;br /&gt;How easily can I set up an environment to run the tests? If the answer is "not very," I might never get the tests running.&lt;/span&gt;&lt;span&gt;&lt;br /&gt;As much as possible, decouple unit tests from external dependencies like databases and web services by using mocks or stubs. When you do test against an external dependency, the dependency better be setup correctly by the automated build. &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-1872986441637210226?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/1872986441637210226/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2008/10/qualities-of-good-unit-test.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/1872986441637210226'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/1872986441637210226'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2008/10/qualities-of-good-unit-test.html' title='Qualities of a Good Unit Test . . .'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-1913242321291172336</id><published>2008-09-26T12:37:00.000-07:00</published><updated>2008-09-27T10:55:29.102-07:00</updated><title type='text'>Transactions . . .</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Cheese Pairing for this Post: &lt;/span&gt;&lt;span style="font-style: italic;"&gt;1-year-old, Cave-Aged Gruyere&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;&lt;span style="font-style: italic;"&gt;[this is a great one that you can really enjoy every once in a while under the right circumstances]&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;So, this week a user story was assigned to me that said something like, "Make sure that we don't save and of the Order data if we can't save ALL the Order data."  Immediately, I thought, "Sounds like time to add some transactional support to our (custom) repositories."  So there I am adding some tests to the repositories solution that assert that I have some infrastructure in place to track all of the database connections, etc, when one of my co-workers says, "Why don't you just use TransactionScope?"  This was new to me, so here is what I learned:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms172152.aspx"&gt;TransactionScope&lt;/a&gt; is a class built on the Microsoft Distributed Transaction Coordinator.  It basically wraps up all that hard work of tracking and committing or rolling back transactions across multiple connections into an easy to use interface, like so:&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;void&lt;/span&gt; MethodWithTransaction()&lt;br /&gt;{&lt;br /&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt;(TransactionScope scope = &lt;span class="kwrd"&gt;new&lt;/span&gt; TransactionScope())&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="rem"&gt;/* Perform transactional work here */&lt;/span&gt;&lt;br /&gt;        scope.Complete();&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;That's it.  If you get to scope.Complete(), the transaction(s) commit.  If you don't get there, the whole thing rolls back when the TransactionScope is disposed.&lt;br /&gt;&lt;br /&gt;Ok, you knew that wasn't all there is to it right?  You have to configure your SQL Servers to run the DTC components.  I didn't do this as our OPS team already had it done.  I did have to do some config on my machine though.  Here are the steps:&lt;br /&gt;&lt;br /&gt;Run dcomcnfg:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_AV_S2ctxpZQ/SN0-46E8CjI/AAAAAAAAABc/3-6REocWD-k/s1600-h/dcomcnfg.JPG"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_AV_S2ctxpZQ/SN0-46E8CjI/AAAAAAAAABc/3-6REocWD-k/s400/dcomcnfg.JPG" alt="" id="BLOGGER_PHOTO_ID_5250421887967431218" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Right-click My Computer and open up the properties. Go to the MSDTC tab:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_AV_S2ctxpZQ/SN0_P4ISHmI/AAAAAAAAABk/h0snWYotbj0/s1600-h/properties.JPG"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_AV_S2ctxpZQ/SN0_P4ISHmI/AAAAAAAAABk/h0snWYotbj0/s400/properties.JPG" alt="" id="BLOGGER_PHOTO_ID_5250422282581581410" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Click the Security Configuration button:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_AV_S2ctxpZQ/SN0_hrWcIII/AAAAAAAAABs/PdLBI9wVQOw/s1600-h/Sec_config.JPG"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_AV_S2ctxpZQ/SN0_hrWcIII/AAAAAAAAABs/PdLBI9wVQOw/s400/Sec_config.JPG" alt="" id="BLOGGER_PHOTO_ID_5250422588388941954" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Those are the setting that work for me.  I also had trouble with the firewall we used here at work, but our networking guys were able to resolve that as soon as I mentioned DTC.&lt;br /&gt;&lt;br /&gt;In the (likely) event that you need more info, try these links:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/aa561924.aspx"&gt;Troubleshooting Problems with MSDTC&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://support.microsoft.com/kb/293799"&gt;How To Use DTCTester Tool&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Good Luck!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-1913242321291172336?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/1913242321291172336/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2008/09/transactions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/1913242321291172336'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/1913242321291172336'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2008/09/transactions.html' title='Transactions . . .'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_AV_S2ctxpZQ/SN0-46E8CjI/AAAAAAAAABc/3-6REocWD-k/s72-c/dcomcnfg.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-8883484551157919273</id><published>2008-09-26T12:28:00.001-07:00</published><updated>2008-09-26T14:47:31.823-07:00</updated><title type='text'>Getting started . . .</title><content type='html'>OK, now that that is out of the way, lets talk about code.&lt;br /&gt;&lt;br /&gt;I work in C# using Visual Studio.NET 2008 w/&lt;a href="http://www.jetbrains.com/resharper/" target="_blank"&gt;ReSharper&lt;/a&gt;.  After working with ReSharper for the last year, I honestly can't imagine working without it, hence the inclusion as part of my IDE.  Why don't I throw some buzzwords at you and then try to justify them: &lt;a href="http://www.domainlanguage.com/ddd/index.html"&gt;DDD&lt;/a&gt;, TDD, Agile, XP, IoC, &lt;a href="http://ayende.com/projects/rhino-mocks.aspx"&gt;RhinoMocks&lt;/a&gt;, nUnit, WatiN, Patterns, Patterns, Patterns...  The list could go on.  Years ago, I would have defined myself (as a coder) using the names of technologies (XML, HTML, T-SQL).  Now I talk more about tools and methods than technologies.&lt;br /&gt;&lt;br /&gt;I mostly work in ASP.NET targeting the .NET 3.5 framework these days at work, though at home, in my free time, I tend to be more desktop focused.&lt;br /&gt;&lt;br /&gt;Well, this isn't a resume, now is it?  I should just talk about the things that really interest me...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-8883484551157919273?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/8883484551157919273/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2008/09/getting-started.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/8883484551157919273'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/8883484551157919273'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2008/09/getting-started.html' title='Getting started . . .'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4809508800731778132.post-5975874773081625312</id><published>2008-09-26T12:12:00.001-07:00</published><updated>2008-09-26T14:47:09.829-07:00</updated><title type='text'>Setting the mood . . .</title><content type='html'>I work in a &lt;a href="http://www.blogger.com/www.1800contacts.com"&gt;shop&lt;/a&gt; that practices paired programming on all production code.  While I quite enjoy this style and encourage it, I occasionally feel the need to check out from the team and get into a coding zone of my own.  I find that heavy metal and punk rock help set up the correct mood for me fairly well.  Here is the Pandora station I generally listen to: &lt;a href="http://www.pandora.com/?sc=sh18653197644805908" target="_blank"&gt;Code Machine&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4809508800731778132-5975874773081625312?l=codeobsession.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codeobsession.blogspot.com/feeds/5975874773081625312/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codeobsession.blogspot.com/2008/09/setting-mood.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/5975874773081625312'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4809508800731778132/posts/default/5975874773081625312'/><link rel='alternate' type='text/html' href='http://codeobsession.blogspot.com/2008/09/setting-mood.html' title='Setting the mood . . .'/><author><name>David Adsit</name><uri>http://www.blogger.com/profile/04091755691184549942</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-Uskf3P9trNU/TVcx-rS-qQI/AAAAAAAAACU/2JwNsOY1rYQ/s220/DA.jpg'/></author><thr:total>0</thr:total></entry></feed>
