<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Los Techies</title><link>http://www.lostechies.com/blogs/</link><description>LosTechies.com was originally discussed a few years ago, over a couple of adult beverages whose name sounds very similar to l(D)os t(E)quies. Anyway the thought was to create a public forum where technical ideas and thoughts can be shared in the same way we all get together around a good meal and drinks. Ideas and thoughts are cultivated in discussion, and brought to fruition through professional debate and laughter. Sounds good in theory, well read our thoughts and ideas, take part in our debates and rejoice in our laughter.</description><dc:language>en-US</dc:language><generator>CommunityServer 2007.1 (Build: 20917.1142)</generator><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/LosTechies" type="application/rss+xml" /><item><title>Ping-pong Pairing Session Screencast with Ben Scheirman</title><link>http://feeds.feedburner.com/~r/LosTechies/~3/289943702/ping-pong-pairing-session-screencast-with-ben-scheirman.aspx</link><pubDate>Wed, 14 May 2008 05:12:08 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:3235</guid><dc:creator>chadmyers</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;Well, it&amp;#39;s two-fer Tuesday here at Los Techies, I guess!&amp;nbsp; By pure coincidence, Ben Scheirman wrapped up the post-production of a screencast we did a few weeks ago.&lt;/p&gt; &lt;p&gt;&lt;a href="http://flux88.com/"&gt;Ben Scheirman&lt;/a&gt; just recently &lt;a href="http://flux88.com/ScreencastTestDrivingAnInventoryScreen.aspx"&gt;posted on his blog&lt;/a&gt; about it.&lt;/p&gt; &lt;p&gt;Ben did a LOT of work trying to get the video and audio in sync and did a &lt;strong&gt;&lt;em&gt;heroic&lt;/em&gt;&lt;/strong&gt; job. We still have a lot to learn about how to get everything to work together (audio, video, shared Internet connection), so please forgive us on the unprofessional nature of the screencast. We&amp;#39;re developers messing around with screencasts, this isn&amp;#39;t our day job! :)&lt;/p&gt; &lt;p&gt;The Screencast can be viewed here:&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.benscheirman.com/screencasts/tdd-inventory"&gt;http://www.benscheirman.com/screencasts/tdd-inventory&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Just like Ben did in his post, I&amp;#39;d like to establish a few caveats:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;I&amp;#39;m not a TDD expert! I make no claims of canon here or that this is official TDD or BDD gospel. Please take with a grain of salt!  &lt;li&gt;Our main goal was to have a pairing session using TDD and record it. We started out trying to teach some TDD fundamentals, but it just turned into a cool jam session  &lt;li&gt;We had a lot of technological problems w/r/t Skype dropping calls.  &lt;li&gt;We had some time sync issues with the audio, so the audio and the video get out of sync part way through the video, but it&amp;#39;s still worth watching part of it  &lt;li&gt;Sorry for the length, hopefully you can zip around and find stuff that&amp;#39;s interesting and then back up a little to see what you want to see.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Anyhow, there&amp;#39;s lots of good stuff in there, and I hope someone gets some useful into out of it. &lt;/p&gt; &lt;p&gt;I can&amp;#39;t speak for Ben, but I know I&amp;#39;d definitely like to keep trying this sort of thing in the future -- hoping that the technological issues would work themselves out and Ben wouldn&amp;#39;t have to kill himself just to get the audio lined up!&lt;/p&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=3235" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=WjKuoH"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=WjKuoH" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=AxYLxh"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=AxYLxh" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=37A45H"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=37A45H" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/LosTechies/~4/289943702" height="1" width="1"/&gt;</description><category domain="http://www.lostechies.com/blogs/chad_myers/archive/tags/TDD/default.aspx">TDD</category><category domain="http://www.lostechies.com/blogs/chad_myers/archive/tags/Screencast/default.aspx">Screencast</category><feedburner:origLink>http://www.lostechies.com/blogs/chad_myers/archive/2008/05/14/ping-pong-pairing-session-screencast-with-ben-scheirman.aspx</feedburner:origLink></item><item><title>ALT.NET Podcast on Continuous Improvement</title><link>http://feeds.feedburner.com/~r/LosTechies/~3/289850444/alt-net-podcast-on-continuous-improvement.aspx</link><pubDate>Wed, 14 May 2008 01:16:55 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:3233</guid><dc:creator>chadmyers</dc:creator><slash:comments>2</slash:comments><description>&lt;p&gt;&lt;a href="http://www.blowmage.com/"&gt;Mike Moore&lt;/a&gt; recently put together a &lt;a href="http://altnetpodcast.com/episodes/1-continuous-improvement"&gt;podcast about ALT.NET and Continuous Improvement&lt;/a&gt; featuring &lt;a href="http://codebetter.com/blogs/jeremy.miller/default.aspx"&gt;Jeremy Miller&lt;/a&gt;, &lt;a href="http://codebetter.com/blogs/david_laribee/"&gt;David Laribee&lt;/a&gt;, and, in order to make the other guys sound smarter, me.&lt;/p&gt; &lt;p&gt;Please check it out and let us all know what you think!&lt;/p&gt; &lt;p&gt;From what I understand, the &amp;#39;Alt.NET Podcast&amp;#39; folks are planning on doing many more episodes, so you may want to subscribe to their feed and stay on top of it in the future.&lt;/p&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=3233" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=Q0EEdH"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=Q0EEdH" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=nYrgGh"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=nYrgGh" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=vsQFBH"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=vsQFBH" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/LosTechies/~4/289850444" height="1" width="1"/&gt;</description><category domain="http://www.lostechies.com/blogs/chad_myers/archive/tags/ALT.NET/default.aspx">ALT.NET</category><feedburner:origLink>http://www.lostechies.com/blogs/chad_myers/archive/2008/05/13/alt-net-podcast-on-continuous-improvement.aspx</feedburner:origLink></item><item><title>OT: You Can Save Lives</title><link>http://feeds.feedburner.com/~r/LosTechies/~3/287533013/ot-you-can-save-lives.aspx</link><pubDate>Sat, 10 May 2008 14:59:43 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:3218</guid><dc:creator>chadmyers</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;I debated about posting this on a technical blog and abusing the relationship with my subscribers, but I believe that the benefits outweigh the negatives. Lives are stake, people are suffering, and many of YOU can help. I hope you agree that this post is worth it.&lt;/p&gt; &lt;p&gt;I know many of you have families and several of you are expecting a new addition. I would like to humbly ask you to consider donating the umbilical cord blood to your local Cord Blood Bank.&amp;nbsp; In Texas, the &lt;a href="http://www.bloodntissue.org/texascordbloodbank.asp"&gt;Texas Cord Blood Blank is in San Antonio&lt;/a&gt;. Most states have a Cord Blood Bank (usually in conjunction with a hospital or a regular blood bank). Please &lt;a href="http://www.marrow.org/HELP/Donate_Cord_Blood_Share_Life/How_to_Donate_Cord_Blood/CB_Participating_Hospitals/nmdp_cord_blood_hospitals.pl"&gt;see if there&amp;#39;s one in your state&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Many people are capturing the cord blood after birth and storing it for treatment of their own family should any of the problems arise that cord blood can treat. This is great and you should seriously consider doing this. I would also like to suggest you consider donating some or all of it to your local/regional blood bank for those who are more likely (or who already have) these life-threatening conditions. People with horrible diseases like Leukemia, lymphoma, sickle cell anemia, and cancer are being treated TODAY and some have had remarkable recoveries due to Cord Blood therapy.&lt;/p&gt; &lt;p&gt;Why am I doing this on my blog? Because so far most hospitals and midwives don&amp;#39;t know that you can save the Cord Blood and bank it and so they don&amp;#39;t think to ask women before or during labor whether they want the blood to be saved.&amp;nbsp; At this time, you must ASK for it.&amp;nbsp; If your family is expecting, I strongly encourage you to look into this and decide if the risks are low enough and benefits high enough to help give someone life-saving therapy.&lt;/p&gt; &lt;p&gt;From what I understand, several major insurance carriers are starting to &lt;a href="http://www.gentlebirth.org/archives/cordBloodInsurance.html"&gt;cover the collection procedure&lt;/a&gt; as well as the &lt;a href="http://www.marrow.org/PATIENT/Plan_for_Tx/Planning_for_Tx_Costs/Insurance_and_Transplant_Cover/"&gt;on the recipient side&lt;/a&gt;, the transplant procedure because it is a &lt;a href="http://www.lifebankusa.com/testimonialsTransplant.php"&gt;demonstrable&lt;/a&gt; and &lt;a href="http://www.itsasurvey.com/artman2/publish/medical/Cord_Blood_Study_Shows_Good_Results.shtml"&gt;scientifically proven&lt;/a&gt; &lt;a href="http://www.cordblood-bank.net/cord-blood-stem-cell-transplant.htm"&gt;medical success&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Benefits of cord blood:&lt;/strong&gt; &lt;ul&gt; &lt;li&gt;There is very little risk to the donor.  &lt;li&gt;Since cord blood immune cells are less mature, they are more easily accepted by the patient when used in transplantation. As a result, patients with a less than perfect immune match can now be treated  &lt;li&gt;There are fewer immune complications after transplantation.  &lt;li&gt;Since cord blood is banked and ready to use, it is immediately available when a patient needs it. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Some of the diseases currently treated with cord blood:&lt;/strong&gt; &lt;ul&gt; &lt;li&gt;Leukemia &amp;amp; other blood cancers  &lt;li&gt;Aplastic anemia  &lt;li&gt;Lymphoma  &lt;li&gt;Deficiencies of the immune system  &lt;li&gt;Genetic disorders such as sickle cell anemia &lt;/li&gt;&lt;/ul&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=3218" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=zCMfuH"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=zCMfuH" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=3cFAph"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=3cFAph" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=01LKcH"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=01LKcH" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/LosTechies/~4/287533013" height="1" width="1"/&gt;</description><category domain="http://www.lostechies.com/blogs/chad_myers/archive/tags/OffTopic/default.aspx">OffTopic</category><feedburner:origLink>http://www.lostechies.com/blogs/chad_myers/archive/2008/05/10/ot-you-can-save-lives.aspx</feedburner:origLink></item><item><title>LINQ query operators: lose that foreach already!</title><link>http://feeds.feedburner.com/~r/LosTechies/~3/287174854/linq-query-operators-lose-that-foreach-already.aspx</link><pubDate>Fri, 09 May 2008 23:11:31 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:3213</guid><dc:creator>bogardj</dc:creator><slash:comments>6</slash:comments><description>&lt;p&gt;Now that .NET 3.5 is out with all its LINQ query operator goodness, I feel like going on a mean streak of trashing a lot of our (now) pointless foreach loops.&amp;nbsp; Some example operations include:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Transformations&lt;/li&gt; &lt;li&gt;Aggregations&lt;/li&gt; &lt;li&gt;Concatenations&lt;/li&gt; &lt;li&gt;Filtering&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;As I mentioned in &lt;a href="http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/05/08/enhancing-mappers-with-linq.aspx"&gt;my last post&lt;/a&gt;, temporary list creation is a great pointer to find opportunities for losing the foreach statements.&amp;nbsp; I keep the foreach statement when the readability and understandability of the code drops with the LINQ change, but otherwise, a lot less temporary objects are floating around.&amp;nbsp; Personally, the jury is still out for me whether it&amp;#39;s clearer to return &amp;quot;IEnumerable&amp;lt;LineItem&amp;gt;&amp;quot; over &amp;quot;LineItem[]&amp;quot;, but the temporary array creation doesn&amp;#39;t seem to have much of a point.&lt;/p&gt; &lt;h3&gt;Transformations&lt;/h3&gt; &lt;p&gt;Transformations are easy to spot. You&amp;#39;ll create a new List&amp;lt;Something&amp;gt;, then loop through some other List&amp;lt;OtherThing&amp;gt; and create a Something from the OtherThing:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;OrderSummary&lt;/span&gt;[] FindOrdersFor(&lt;span style="color:blue;"&gt;int &lt;/span&gt;customerId)
{
    &lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Order&lt;/span&gt;&amp;gt; orders = GetOrdersForCustomer(customerId);
    &lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;OrderSummary&lt;/span&gt;&amp;gt; orderSummaries = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;OrderSummary&lt;/span&gt;&amp;gt;();

    &lt;span style="color:blue;"&gt;foreach &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;Order &lt;/span&gt;order &lt;span style="color:blue;"&gt;in &lt;/span&gt;orders)
    {
        orderSummaries.Add(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;OrderSummary
                            &lt;/span&gt;{
                                CustomerName = order.Customer.Name,
                                DateSubmitted = order.DateSubmitted,
                                OrderTotal = order.GetTotal()
                            });
    }

    &lt;span style="color:blue;"&gt;return &lt;/span&gt;orderSummaries.ToArray();
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;Note the temporary list creation, just to return an array.&amp;nbsp; With LINQ query operators, I can use the Select method to do the same transformation in less code:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;OrderSummary&lt;/span&gt;[] FindOrdersFor(&lt;span style="color:blue;"&gt;int &lt;/span&gt;customerId)
{
    &lt;span style="color:blue;"&gt;return &lt;/span&gt;GetOrdersForCustomer(customerId)
        .Select(order =&amp;gt; &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;OrderSummary
                             &lt;/span&gt;{
                                 CustomerName = order.Customer.Name,
                                 DateSubmitted = order.DateSubmitted,
                                 OrderTotal = order.GetTotal()
                             })
        .ToArray();
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;By chaining the methods together, it comes out much more readable.&lt;/p&gt;
&lt;h3&gt;Aggregations&lt;/h3&gt;
&lt;p&gt;Aggregations can be found when you&amp;#39;re looping through some list for some kind of calculation.&amp;nbsp; For example, the GetTotal method on Order loops to build up the total based on each item&amp;#39;s ItemPrice:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public decimal &lt;/span&gt;GetTotal()
{
    &lt;span style="color:blue;"&gt;decimal &lt;/span&gt;total = 0.0m;

    &lt;span style="color:blue;"&gt;foreach &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;LineItem &lt;/span&gt;lineItem &lt;span style="color:blue;"&gt;in &lt;/span&gt;GetLineItems())
    {
        total += lineItem.ItemPrice;
    }

    &lt;span style="color:blue;"&gt;return &lt;/span&gt;total;
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;Again, this can be greatly reduced using LINQ query operators and the Sum method:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public decimal &lt;/span&gt;GetTotal()
{
    &lt;span style="color:blue;"&gt;return &lt;/span&gt;GetLineItems()
        .Sum(item =&amp;gt; item.ItemPrice);
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;Not only is the code much smaller, but the intent is much easier to discern.&amp;nbsp; Sometimes a calculation can be tricky, and in those cases LINQ isn&amp;#39;t bringing anything to the table.&amp;nbsp; As always, use good judgement and keep an eye on readability.&lt;/p&gt;
&lt;h3&gt;Concatenations&lt;/h3&gt;
&lt;p&gt;Oftentimes I need to combine many lists into one flattened list.&amp;nbsp; For example, suppose I need a list of OrderLineItem summary items, perhaps to display on a grid to the end user.&amp;nbsp; However, I want to display all order line items for all orders, which is difficult to build up manually:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;LineItemSummary&lt;/span&gt;[] FindLineItemsFor(&lt;span style="color:blue;"&gt;int &lt;/span&gt;customerId)
{
    &lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Order&lt;/span&gt;&amp;gt; orders = GetOrdersForCustomer(customerId);
    &lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;LineItemSummary&lt;/span&gt;&amp;gt; lineItemSummaries = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;LineItemSummary&lt;/span&gt;&amp;gt;();

    &lt;span style="color:blue;"&gt;foreach &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;Order &lt;/span&gt;order &lt;span style="color:blue;"&gt;in &lt;/span&gt;orders)
    {
        &lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;LineItemSummary&lt;/span&gt;&amp;gt; tempSummaries = TransformLineItems(order, order.GetLineItems());

        lineItemSummaries.AddRange(tempSummaries);
    }

    &lt;span style="color:blue;"&gt;return &lt;/span&gt;lineItemSummaries.ToArray();
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;Note the two temporary lists: one to hold the concatenated list, and the other to hold each result as we loop through.&amp;nbsp; With the SelectMany method, this becomes much shorter:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;LineItemSummary&lt;/span&gt;[] FindLineItemsFor(&lt;span style="color:blue;"&gt;int &lt;/span&gt;customerId)
{
    &lt;span style="color:blue;"&gt;return &lt;/span&gt;GetOrdersForCustomer(customerId)
        .SelectMany(order =&amp;gt; TransformLineItems(order, order.GetLineItems()))
        .ToArray();
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;No temporary lists are created, and all of the LineItemSummary objects are concatenated correctly.&amp;nbsp; Nested foreach loops as well as the AddRange method are indicators that the SelectMany method could be used.&lt;/p&gt;
&lt;h3&gt;Filtering&lt;/h3&gt;
&lt;p&gt;Filtering looks similar to transformations, except there&amp;#39;s an &amp;quot;if&amp;quot; statement that controls adding to the temporary list.&amp;nbsp; Suppose we want only the expensive LineItemSummary items:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;LineItemSummary&lt;/span&gt;[] FindExpensiveLineItemsFor(&lt;span style="color:blue;"&gt;int &lt;/span&gt;customerId)
{
    &lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Order&lt;/span&gt;&amp;gt; orders = GetOrdersForCustomer(customerId);
    &lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;LineItemSummary&lt;/span&gt;&amp;gt; lineItemSummaries = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;LineItemSummary&lt;/span&gt;&amp;gt;();

    &lt;span style="color:blue;"&gt;foreach &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;Order &lt;/span&gt;order &lt;span style="color:blue;"&gt;in &lt;/span&gt;orders)
    {
        &lt;span style="color:blue;"&gt;foreach &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;LineItem &lt;/span&gt;item &lt;span style="color:blue;"&gt;in &lt;/span&gt;order.GetLineItems())
        {
            &lt;span style="color:blue;"&gt;if &lt;/span&gt;(item.ItemPrice &amp;gt; 100.0m)
                lineItemSummaries.Add(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;LineItemSummary
                                          &lt;/span&gt;{
                                              CustomerName = order.Customer.Name,
                                              DateSubmitted = order.DateSubmitted,
                                              ItemPrice = item.ItemPrice,
                                              ItemName = item.ProductName
                                          });
        }
    }

    &lt;span style="color:blue;"&gt;return &lt;/span&gt;lineItemSummaries.ToArray();
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;This example has both concatenation and filtering.&amp;nbsp; The filtering can be taken care of with the Where method, and we&amp;#39;ll use the same technique earlier with the SelectMany method:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;LineItemSummary&lt;/span&gt;[] FindExpensiveLineItemsFor(&lt;span style="color:blue;"&gt;int &lt;/span&gt;customerId)
{
    &lt;span style="color:blue;"&gt;return &lt;/span&gt;GetOrdersForCustomer(customerId)
        .SelectMany(order =&amp;gt; TransformLineItems(order, order.GetLineItems()))
        .Where(item =&amp;gt; item.ItemPrice &amp;gt; 100.0m)
        .ToArray();
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;By adding the Where method, we can filter out only the expensive line items.&amp;nbsp; The method chaining looks much better than the nested foreach loops coupled with the if statement, and got rid of the temporary list creation.&lt;/p&gt;
&lt;h3&gt;Lose the foreach&lt;/h3&gt;
&lt;p&gt;With the new LINQ query operators, any temporary list creation and foreach loop should be considered suspect.&amp;nbsp; By understanding the operations LINQ gives us, we can not only reduce the amount of code we create, but the end result matches the original intent far better.&lt;/p&gt;
&lt;p&gt;Not every foreach or temporary list should be removed, as sometimes long chains and large lambdas tend to muddy rather than clear the picture.&amp;nbsp; But for a great deal of scenarios, LINQ query operators can vastly improve the readability of transformation (Select), aggregation (Sum), concatenation (SelectMany) and filtering (Where) sections of your code.&lt;/p&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=3213" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=GxJP5H"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=GxJP5H" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=NWp9jh"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=NWp9jh" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=USsNhH"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=USsNhH" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/LosTechies/~4/287174854" height="1" width="1"/&gt;</description><category domain="http://www.lostechies.com/blogs/jimmy_bogard/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://www.lostechies.com/blogs/jimmy_bogard/archive/tags/LINQ/default.aspx">LINQ</category><feedburner:origLink>http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/05/09/linq-query-operators-lose-that-foreach-already.aspx</feedburner:origLink></item><item><title>Don't Do That</title><link>http://feeds.feedburner.com/~r/LosTechies/~3/286561816/don-t-do-that.aspx</link><pubDate>Fri, 09 May 2008 04:18:30 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:3198</guid><dc:creator>hoffe</dc:creator><slash:comments>7</slash:comments><description>&lt;p&gt;Over lunch today, I learned about one of the company&amp;#39;s recent acquisitions.&amp;nbsp; Here&amp;#39;s the short of it:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The production system has between 6k-7k different Access databases (databases, not tables)&lt;/li&gt; &lt;li&gt;Since the app creates new databases on the fly, no one is sure which are production dbs&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Don&amp;#39;t ever do that.&amp;nbsp; Please.&amp;nbsp; And no, I couldn&amp;#39;t make this one up even if I tried. ;-)&lt;/p&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=3198" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=TzGXFH"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=TzGXFH" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=TXCrFh"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=TXCrFh" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=N8mSnH"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=N8mSnH" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/LosTechies/~4/286561816" height="1" width="1"/&gt;</description><feedburner:origLink>http://www.lostechies.com/blogs/evan_hoff/archive/2008/05/08/don-t-do-that.aspx</feedburner:origLink></item><item><title>NAnt script for determining whether an assembly is registered in the GAC</title><link>http://feeds.feedburner.com/~r/LosTechies/~3/286316248/nant-script-for-determining-whether-an-assembly-is-register-in-the-gac.aspx</link><pubDate>Thu, 08 May 2008 19:53:29 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:3195</guid><dc:creator>chadmyers</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;A friend of mine, &lt;a href="http://blogs.dovetailsoftware.com/blogs/kmiller/"&gt;Kevin Miller&lt;/a&gt;, recently put out a public call for anyone who had some NAnt magic for detecting whether a given assembly is in the GAC or not. I had written something like this a year or so ago and I thought I&amp;#39;d share it with everyone in the hopes it might help you.&lt;/p&gt; &lt;p&gt;Standard disclaimer: I don&amp;#39;t guarantee that this works, I don&amp;#39;t guarantee that this won&amp;#39;t explode your computer if you run it. I make no warrantees of any kind.&lt;/p&gt; &lt;p&gt;First, you have to have the .NET SDK installed. If you have Visual Studio 2005 or later, you do. If you&amp;#39;re on a server, make sure you install the .NET Framework 2.0 SDK (free download from MS -- &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=fe6f2099-b7b4-4f47-a244-c96d69c35dec"&gt;SDK x86&lt;/a&gt;, &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=1AEF6FCE-6E06-4B66-AFE4-9AAD3C835D3D"&gt;SDK x64&lt;/a&gt;, and &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=F4DD601B-1B88-47A3-BDC1-79AFA79F6FB0"&gt;SDK IA64&lt;/a&gt;) first.&lt;/p&gt; &lt;p&gt;At the top of your build script somewhere:&lt;br /&gt;&lt;/p&gt;&lt;pre class="code"&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;property&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&amp;quot;&lt;span&gt;gacutil.exe&lt;/span&gt;&amp;quot;&lt;span&gt; &lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&amp;quot;&lt;span&gt;${framework::get-sdk-directory(&amp;#39;net-2.0&amp;#39;)}\gacutil.exe&lt;/span&gt;&amp;quot;&lt;span&gt; /&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;&lt;br /&gt;Next, add the GAC check in a task somewhere (NOTE: Replace the YOUR_ASSEMBLY... with the name of the assembly to find without the &amp;quot;.dll&amp;quot; portion on the end):&lt;/p&gt;&lt;pre class="code"&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;exec&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;program&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&amp;quot;&lt;span&gt;cmd.exe&lt;/span&gt;&amp;quot;&lt;span&gt; &lt;/span&gt;&lt;span&gt;failonerror&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&amp;quot;&lt;span&gt;false&lt;/span&gt;&amp;quot;&lt;span&gt; &lt;/span&gt;&lt;span&gt;resultproperty&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&amp;quot;&lt;span&gt;foundInGac&lt;/span&gt;&amp;quot;&lt;span&gt; &lt;/span&gt;&lt;span&gt;verbose&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&amp;quot;&lt;span&gt;true&lt;/span&gt;&amp;quot;
&lt;span&gt;    &lt;/span&gt;&lt;span&gt;commandline&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&amp;quot;&lt;span&gt;/c gacutil.exe /l YOUR_ASSEMBLY_NAME_WITHOUT_THE_DOT_DLL | %windir%\system32\find &lt;/span&gt;&lt;span&gt;&amp;amp;quot;&lt;/span&gt;&lt;span&gt;Number of items = 1&lt;/span&gt;&lt;span&gt;&amp;amp;quot;&lt;/span&gt;&amp;quot;&lt;span&gt;&amp;gt;
    
    &amp;lt;&lt;/span&gt;&lt;span&gt;environment&lt;/span&gt;&lt;span&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span&gt;variable&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&amp;quot;&lt;span&gt;PATH&lt;/span&gt;&amp;quot;&lt;span&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span&gt;path&lt;/span&gt;&lt;span&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span&gt;pathelement&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;path&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&amp;quot;&lt;span&gt;%PATH%&lt;/span&gt;&amp;quot;&lt;span&gt;/&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span&gt;pathelement&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;dir&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&amp;quot;&lt;span&gt;${framework::get-sdk-directory(&amp;#39;net-2.0&amp;#39;)}&lt;/span&gt;&amp;quot;&lt;span&gt;/&amp;gt;
            &amp;lt;/&lt;/span&gt;&lt;span&gt;path&lt;/span&gt;&lt;span&gt;&amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span&gt;variable&lt;/span&gt;&lt;span&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span&gt;environment&lt;/span&gt;&lt;span&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span&gt;exec&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;In my particular case, I added a &amp;lt;fail&amp;gt; task to fail the build if that assembly was in the GAC because it could hose the versioning of my build. Here&amp;#39;s how I did that:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;fail&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&amp;quot;&lt;span&gt;${int::parse(foundInGac) == 0}&lt;/span&gt;&amp;quot;&lt;span&gt; &lt;/span&gt;&lt;span&gt;message&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&amp;quot;&lt;span&gt;The Core assembly is registered in the GAC. Please un-GAC this assembly before attempting to build the project.&lt;/span&gt;&amp;quot;&lt;span&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I hope this helps someone.&lt;/p&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=3195" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=cc032H"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=cc032H" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=Q0wBZh"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=Q0wBZh" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=1aj8eH"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=1aj8eH" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/LosTechies/~4/286316248" height="1" width="1"/&gt;</description><feedburner:origLink>http://www.lostechies.com/blogs/chad_myers/archive/2008/05/08/nant-script-for-determining-whether-an-assembly-is-register-in-the-gac.aspx</feedburner:origLink></item><item><title>Enhancing mappers with LINQ</title><link>http://feeds.feedburner.com/~r/LosTechies/~3/286067103/enhancing-mappers-with-linq.aspx</link><pubDate>Thu, 08 May 2008 12:49:53 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:3189</guid><dc:creator>bogardj</dc:creator><slash:comments>10</slash:comments><description>&lt;p&gt;The &amp;quot;big 3&amp;quot; higher-order functions in functional programming are Filter, Map and Reduce.&amp;nbsp; When looking at the new C# 3.0 LINQ query operators, we find that &lt;a href="http://diditwith.net/2007/06/27/AHigherCallingRevisited.aspx"&gt;all three have equivalents&lt;/a&gt;:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Filter = Where&lt;/li&gt; &lt;li&gt;Map = Select&lt;/li&gt; &lt;li&gt;Reduce = Aggregate&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Whenever you find yourself needing one of these three higher-order functions, just translate them into the correct query operator.&amp;nbsp; &amp;quot;Select&amp;quot; doesn&amp;#39;t have the same dictionary meaning as &amp;quot;Map&amp;quot;, but the signature is exactly the same.&lt;/p&gt; &lt;p&gt;The trick to knowing you can use these higher order functions is to look out for situations where you:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Create a new collection&lt;/li&gt; &lt;li&gt;Iterate through some other collection&lt;/li&gt; &lt;li&gt;Add items from the other collection to the new collection&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Any time you see this general algorithm, there&amp;#39;s a much terser syntax available with LINQ.&lt;/p&gt; &lt;h3&gt;&lt;/h3&gt; &lt;h3&gt;Mapper patter example&lt;/h3&gt; &lt;p&gt;For example, consider the Mapper pattern:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public interface &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IMapper&lt;/span&gt;&amp;lt;TInput, TOutput&amp;gt;
{
    TOutput Map(TInput input);
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;A common scenario to map is when I&amp;#39;m creating DTOs or message objects from Domain objects.&amp;nbsp; Serializing domain objects generally isn&amp;#39;t a concern of the domain object, as DTOs tend to be flattened out somewhat.&amp;nbsp; I might have the following domain objects:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Customer
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Guid &lt;/span&gt;Id  { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }
    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;Name { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }
}
&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;SalesOrder
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Customer &lt;/span&gt;Customer { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }
    &lt;span style="color:blue;"&gt;public decimal &lt;/span&gt;Total { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;I&amp;#39;d like to send a Sales Order over the wire for display in some client application.&amp;nbsp; But suppose the Customer object contains dozens of properties, perhaps things like a billing address, a shipping address, and so on.&amp;nbsp; The service I&amp;#39;m creating only needs a summary of customer information, so I create a SalesOrderSummary message class:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;SalesOrderSummary
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;public string &lt;/span&gt;CustomerName { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;private set&lt;/span&gt;; }
    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Guid &lt;/span&gt;CustomerId { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;private set&lt;/span&gt;; }
    &lt;span style="color:blue;"&gt;public decimal &lt;/span&gt;Total { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;private set&lt;/span&gt;; }

    &lt;span style="color:green;"&gt;// For serialization
    &lt;/span&gt;&lt;span style="color:blue;"&gt;private &lt;/span&gt;SalesOrderSummary() { }

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;SalesOrderSummary(&lt;span style="color:blue;"&gt;string &lt;/span&gt;customerName, &lt;span style="color:#2b91af;"&gt;Guid &lt;/span&gt;customerId, &lt;span style="color:blue;"&gt;decimal &lt;/span&gt;total)
    {
        CustomerName = customerName;
        CustomerId = customerId;
        Total = total;
    }
}&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;The corresponding mapper would look like:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;SalesOrderSummaryMapper &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;IMapper&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;SalesOrder&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;SalesOrderSummary&lt;/span&gt;&amp;gt;
{
    &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;SalesOrderSummary &lt;/span&gt;Map(&lt;span style="color:#2b91af;"&gt;SalesOrder &lt;/span&gt;input)
    {
        &lt;span style="color:blue;"&gt;return new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;SalesOrderSummary&lt;/span&gt;(input.Customer.Name, input.Customer.Id, input.Total);
    }
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;Nothing too exciting so far, right?&amp;nbsp; Well, suppose now I need to return an array of SalesOrderSummary, perhaps for display in a grid.&amp;nbsp; In that case, I&amp;#39;ll need to build up a list of SalesOrderSummary objects based on a list of SalesOrder objects:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;SalesOrderSummary&lt;/span&gt;[] FindSalesOrdersByMonth(&lt;span style="color:#2b91af;"&gt;DateTime &lt;/span&gt;date)
{
    &lt;span style="color:green;"&gt;// get the sales orders from the repository first
    &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;SalesOrder&lt;/span&gt;&amp;gt; salesOrders = GetSalesOrders();

    &lt;span style="color:blue;"&gt;var &lt;/span&gt;salesOrderSummaries = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;SalesOrderSummary&lt;/span&gt;&amp;gt;();
    &lt;span style="color:blue;"&gt;var &lt;/span&gt;mapper = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;SalesOrderSummaryMapper&lt;/span&gt;();

    &lt;span style="color:blue;"&gt;foreach &lt;/span&gt;(&lt;span style="color:blue;"&gt;var &lt;/span&gt;salesOrder &lt;span style="color:blue;"&gt;in &lt;/span&gt;salesOrders)
    {
        salesOrderSummaries.Add(mapper.Map(salesOrder));
    }

    &lt;span style="color:blue;"&gt;return &lt;/span&gt;salesOrderSummaries.ToArray();
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;This isn&amp;#39;t too bad, but the creation of a second list just to build up an array seems rather pointless.&amp;nbsp; But by borrowing &lt;a href="http://www.jpboodhoo.com/blog/IMapper.aspx"&gt;some ideas from JP&lt;/a&gt;, we can make this a lot easier.&lt;/p&gt;
&lt;h3&gt;Using LINQ&lt;/h3&gt;
&lt;p&gt;We can already see the higher order function we need, it&amp;#39;s in the name of the mapper!&amp;nbsp; Instead of &amp;quot;Map&amp;quot;, we&amp;#39;ll use &amp;quot;Select&amp;quot; to do the transforming.&amp;nbsp; But since we have the interface, we can create an extension method to do the Map function:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public static class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;MapperExtensions
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;public static &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;TOutput&amp;gt; MapAll&amp;lt;TInput, TOutput&amp;gt;(&lt;span style="color:blue;"&gt;this &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IMapper&lt;/span&gt;&amp;lt;TInput, TOutput&amp;gt; mapper, 
        &lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;TInput&amp;gt; input)
    {
        &lt;span style="color:blue;"&gt;return &lt;/span&gt;input.Select(x =&amp;gt; mapper.Map(x));
    }
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;This new MapAll function is the functional programming Map function, where it takes an input list and returns a new IEnumerable with the mapped values.&amp;nbsp; Internally, the Select LINQ query operator will loop through our input, calling the lambda function we passed in (mapper.Map).&amp;nbsp; This is the exact same operation in our original example, but now our service method now becomes much smaller:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;SalesOrderSummary&lt;/span&gt;[] FindSalesOrdersByMonth(&lt;span style="color:#2b91af;"&gt;DateTime &lt;/span&gt;date)
{
    &lt;span style="color:green;"&gt;// get the sales orders from the repository first
    &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;SalesOrder&lt;/span&gt;&amp;gt; salesOrders = GetSalesOrders();
    &lt;span style="color:blue;"&gt;var &lt;/span&gt;mapper = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;SalesOrderSummaryMapper&lt;/span&gt;();

    &lt;span style="color:blue;"&gt;return &lt;/span&gt;mapper.MapAll(salesOrders).ToArray();
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;Much nicer, our service method is reduced to just a handful of lines.&amp;nbsp; The nice thing about this syntax is that it removes all of the unnecessary cruft of a temporary list creation that clouded the intent of this method.&lt;/p&gt;
&lt;p&gt;So any time you find yourself creating a temporary list just to build up some filtered, mapped or reduced values, stop yourself.&amp;nbsp; There&amp;#39;s a higher calling available with functional programming and LINQ.&lt;/p&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=3189" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=W5yv9H"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=W5yv9H" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=cyDVIh"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=cyDVIh" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=4Rlf3H"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=4Rlf3H" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/LosTechies/~4/286067103" height="1" width="1"/&gt;</description><category domain="http://www.lostechies.com/blogs/jimmy_bogard/archive/tags/Domain-Driven+Design/default.aspx">Domain-Driven Design</category><category domain="http://www.lostechies.com/blogs/jimmy_bogard/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://www.lostechies.com/blogs/jimmy_bogard/archive/tags/LINQ/default.aspx">LINQ</category><feedburner:origLink>http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/05/08/enhancing-mappers-with-linq.aspx</feedburner:origLink></item><item><title>Mike Cohn in town</title><link>http://feeds.feedburner.com/~r/LosTechies/~3/285359161/mike-cohn-in-town.aspx</link><pubDate>Wed, 07 May 2008 12:26:20 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:3184</guid><dc:creator>bogardj</dc:creator><slash:comments>3</slash:comments><description>&lt;p&gt;&lt;a href="http://blog.mountaingoatsoftware.com/"&gt;Mike Cohn&lt;/a&gt;, author of &lt;a href="http://www.amazon.com/User-Stories-Applied-Development-Addison-Wesley/dp/0321205685"&gt;User Stories Applied&lt;/a&gt; and &lt;a href="http://www.amazon.com/Agile-Estimating-Planning-Robert-Martin/dp/0131479415"&gt;Agile Estimation and Planning&lt;/a&gt;, is speaking tomorrow night as a part of &lt;a href="http://agileaustin.org/"&gt;Agile Austin&amp;#39;s&lt;/a&gt; Distinguished Speaker Series.&amp;nbsp; The topic is &lt;a href="http://mikecohnpresentation.eventbrite.com/"&gt;&amp;quot;Succeeding with Agile: A Guide to Transitioning&amp;quot;&lt;/a&gt;, with the description:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Transitioning to an agile development process is unlike most transitions an organization may make. Many transitions begin when a strong, visionary leader plants a stake in the ground and says, “Let’s take our organization there.” Other transitions start with a lone team thinking, “Who cares what management thinks, let’s do this.” The problem in transitioning to agile is that neither of these approaches alone is likely to lead to the long-term sustainable change required.&lt;/p&gt; &lt;p&gt;In this session we will look at the primary reasons why agile transitions fail and how to overcome them. We will explore what is necessary for self-organizing teams to emerge and thrive within the transitioning organization. We will also the role self-organization must play during the transition itself. This session will include a description of the eight primary ways of getting started—including going &lt;em&gt;All In, Start Small, &lt;/em&gt;and&lt;em&gt; Impending Doom—&lt;/em&gt;and the advantages of each. You will leave knowing what approach will work best for you as well as what you must and must not do to succeed with agile. &lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Transitioning to Agile is a very bumpy ride, as the rise in communication works to surface problems that were previously hidden and swept under the rug.&amp;nbsp; Mike&amp;#39;s books have had a large influence on how I approach software, so I&amp;#39;m pretty excited about Mike coming to town.&amp;nbsp; The registration fee for non-Agile Austin members is $10, or in my terms, 20 tacos from Jack in the Box.&lt;/p&gt; &lt;p&gt;For more information, check out the event page:&lt;/p&gt; &lt;p&gt;&lt;a title="http://mikecohnpresentation.eventbrite.com/" href="http://mikecohnpresentation.eventbrite.com/"&gt;http://mikecohnpresentation.eventbrite.com/&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I know it&amp;#39;s not Hannah Montana, but it should be a nice event nonetheless.&lt;/p&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=3184" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=6O5VZH"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=6O5VZH" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=Zzrchh"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=Zzrchh" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=oCnbjH"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=oCnbjH" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/LosTechies/~4/285359161" height="1" width="1"/&gt;</description><category domain="http://www.lostechies.com/blogs/jimmy_bogard/archive/tags/Agile/default.aspx">Agile</category><feedburner:origLink>http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/05/07/mike-cohn-in-town.aspx</feedburner:origLink></item><item><title>VMware Fusion 2.0 Beta 1</title><link>http://feeds.feedburner.com/~r/LosTechies/~3/284692084/vmware-fusion-2-0-beta-1.aspx</link><pubDate>Tue, 06 May 2008 13:59:10 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:3172</guid><dc:creator>Chris Patterson</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;It looks like VMware has dropped a public beta of VMware Fusion 2.0 to the public. There are too many new features in this release to mention, so I will just share the link:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://communities.vmware.com/community/beta/fusion"&gt;http://communities.vmware.com/community/beta/fusion&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Be sure to check the release notes to see if they impact your work before upgrading to this beta release.&lt;/p&gt;  &lt;p&gt;Items of interest I took away from the release notes:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Use Fn+M to simulate the non-existent insert key in Windows (hello R#) &lt;/li&gt;    &lt;li&gt;Multiple display support for virtual machines (hello second monitor) &lt;/li&gt;    &lt;li&gt;Improved compatibility with Visual Studio (not sure what this is yet) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Be sure to check it out!&lt;/p&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=3172" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=wS1kqH"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=wS1kqH" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=tgmb9h"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=tgmb9h" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=SfFy5H"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=SfFy5H" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/LosTechies/~4/284692084" height="1" width="1"/&gt;</description><category domain="http://www.lostechies.com/blogs/chris_patterson/archive/tags/.net/default.aspx">.net</category><category domain="http://www.lostechies.com/blogs/chris_patterson/archive/tags/osx/default.aspx">osx</category><category domain="http://www.lostechies.com/blogs/chris_patterson/archive/tags/mac/default.aspx">mac</category><feedburner:origLink>http://www.lostechies.com/blogs/chris_patterson/archive/2008/05/06/vmware-fusion-2-0-beta-1.aspx</feedburner:origLink></item><item><title>PabloTV: Eliminating static dependencies screencast</title><link>http://feeds.feedburner.com/~r/LosTechies/~3/284638849/pablotv-eliminating-static-dependencies-screencast.aspx</link><pubDate>Tue, 06 May 2008 12:24:13 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:3171</guid><dc:creator>bogardj</dc:creator><slash:comments>8</slash:comments><description>&lt;p&gt;Nature abhors a vacuum.&amp;nbsp; It turns out she also abhors static dependencies (I have my sources).&amp;nbsp; Static dependencies are the modern-day globals, often exposed through classes named &amp;quot;Helper&amp;quot;.&amp;nbsp; I&amp;#39;ve certainly been guilty of overusing static dependencies in the past, with classes like &amp;quot;LoggingHelper&amp;quot;, &amp;quot;SessionHelper&amp;quot;, &amp;quot;DBHelper&amp;quot; and so on.&lt;/p&gt; &lt;p&gt;The problem with static dependencies is that they are opaque to the extreme, enforcing a strong coupling that is impossible to see from users of the class.&amp;nbsp; To demonstrate techniques for eliminating static dependencies, Ray Houston and I created a short screencast:&lt;/p&gt; &lt;p&gt;&lt;a href="http://screencasts.lostechies.com/screencasts/rhouston/EliminatingStaticDependencies.htm"&gt;Eliminating static dependencies screencast&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Our screencast demonstrates using TDD along with ideas and techniques laid out in Michael Feathers&amp;#39; &lt;a href="http://www.amazon.com/Working-Effectively-Legacy-Robert-Martin/dp/0131177052"&gt;Working Effectively with Legacy Code&lt;/a&gt; and Joshua Kerievsky&amp;#39;s &lt;a href="http://www.amazon.com/Refactoring-Patterns-Addison-Wesley-Signature-Kerievsky/dp/0321213351"&gt;Refactoring to Patterns&lt;/a&gt;.&amp;nbsp; It details how to make safe, responsible changes to an existing legacy codebase, while improving the design by breaking out dependencies to a static class.&lt;/p&gt; &lt;p&gt;Hope you enjoy it!&lt;/p&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=3171" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=fVaipH"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=fVaipH" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=VoR1ch"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=VoR1ch" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=7ENp5H"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=7ENp5H" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/LosTechies/~4/284638849" height="1" width="1"/&gt;</description><category domain="http://www.lostechies.com/blogs/jimmy_bogard/archive/tags/Legacy+Code/default.aspx">Legacy Code</category><category domain="http://www.lostechies.com/blogs/jimmy_bogard/archive/tags/Refactoring/default.aspx">Refactoring</category><category domain="http://www.lostechies.com/blogs/jimmy_bogard/archive/tags/BDD/default.aspx">BDD</category><category domain="http://www.lostechies.com/blogs/jimmy_bogard/archive/tags/TDD/default.aspx">TDD</category><category domain="http://www.lostechies.com/blogs/jimmy_bogard/archive/tags/PabloTV/default.aspx">PabloTV</category><feedburner:origLink>http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/05/06/pablotv-eliminating-static-dependencies-screencast.aspx</feedburner:origLink></item><item><title>A pointless exercise</title><link>http://feeds.feedburner.com/~r/LosTechies/~3/283933457/a-pointless-exercise.aspx</link><pubDate>Mon, 05 May 2008 12:40:40 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:3161</guid><dc:creator>bogardj</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;I caught this last night from &lt;a href="http://www.hanselman.com/blog/"&gt;Scott Hanselman&lt;/a&gt; on Twitter:&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.betterwebapp.com/drupal/?q=screencasts"&gt;http://www.betterwebapp.com/drupal/?q=screencasts&lt;/a&gt;&lt;/p&gt; &lt;p&gt;It&amp;#39;s a side-by-side comparison of the time to create a simple web app for:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Ruby&lt;/li&gt; &lt;li&gt;Perl&lt;/li&gt; &lt;li&gt;ASP.NET&lt;/li&gt; &lt;li&gt;Java&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The website compares a few other frameworks to compare which languages and frameworks are the fastest to develop against.&amp;nbsp; Not that it matters, but ASP.NET came out on top for the simple application profile, while Python/Django came out on top for the three-tier application profile.&lt;/p&gt; &lt;p&gt;While viewing the screencast, all I could think was &amp;quot;Holy jeebus, &lt;strong&gt;is there a more pointless exercise than timing the creation of software&lt;/strong&gt;?&amp;quot;&amp;nbsp; Creating software is easy (some would say too easy).&amp;nbsp; If our problem was &amp;quot;how fast can we whip out software&amp;quot;, the issues of today&amp;#39;s software developers would have been solved decades ago.&lt;/p&gt; &lt;p&gt;The problem is that &lt;strong&gt;software maintenance dwarfs the cost of software creation&lt;/strong&gt;, by a factor of at least 3 to 1.&amp;nbsp; So if we&amp;#39;re trying to optimize software development, isn&amp;#39;t it the most expensive aspect, maintenance, what we should focus on?&amp;nbsp; We use ReSharper to optimize responsible code creation (i.e., micro-codegen vs. macro-codegen), but it also helps with responsible code maintenance through automated refactorings.&amp;nbsp; Many other responsible engineering practices, such as &lt;a href="http://www.extremeprogramming.org/rules.html"&gt;those espoused by XP&lt;/a&gt;, aim to reduce the maintenance costs of software development.&lt;/p&gt; &lt;p&gt;In the end, I could care less how long it takes to slap out some sample application.&amp;nbsp; In six years of professional development, no one has ever paid me to write an application on the level of what was demonstrated.&amp;nbsp; Some managers will care how fast you sling code, but the smart ones care about:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Can the software you created be easily changed?&lt;/li&gt; &lt;li&gt;Can the software you created be easily tested?&lt;/li&gt; &lt;li&gt;Can the software you created be easily deployed?&lt;/li&gt; &lt;li&gt;Can the software you created be easily diagnosed for bugs?&lt;/li&gt; &lt;li&gt;Is the software you created correct?&lt;/li&gt; &lt;li&gt;Is the software you created what we actually need?&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;I&amp;#39;d love to see those issues in a screencast, but who would want to watch a screencast that lasted for weeks or months?&lt;/p&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=3161" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=XJlYRH"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=XJlYRH" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=CA1nMh"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=CA1nMh" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=jx7G7H"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=jx7G7H" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/LosTechies/~4/283933457" height="1" width="1"/&gt;</description><category domain="http://www.lostechies.com/blogs/jimmy_bogard/archive/tags/Misc/default.aspx">Misc</category><category domain="http://www.lostechies.com/blogs/jimmy_bogard/archive/tags/Rant/default.aspx">Rant</category><feedburner:origLink>http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/05/05/a-pointless-exercise.aspx</feedburner:origLink></item><item><title>A Very Poor Object Model Is Really No Object Model At All</title><link>http://feeds.feedburner.com/~r/LosTechies/~3/283658460/a-very-poor-object-model-is-really-no-object-model-at-all.aspx</link><pubDate>Mon, 05 May 2008 02:59:02 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:3151</guid><dc:creator>hoffe</dc:creator><slash:comments>9</slash:comments><description>&lt;p&gt;First let me say that I&amp;#39;ve met &lt;a href="http://keithelder.net/blog/" target="_blank"&gt;Keith&lt;/a&gt; personally, and he&amp;#39;s a really cool guy.&amp;nbsp; Cool enough in fact, that he&amp;#39;s on my RSS subscription list. I&amp;#39;d consider him a friend.&amp;nbsp; :-)&lt;/p&gt; &lt;p&gt;This is my response to his recent post, &lt;a href="http://keithelder.net/blog/archive/2008/05/02/How-To-Not-Screw-Up-Your-Application-Object-Model.aspx" target="_blank"&gt;How To Not Screw Up Your Application Object Model&lt;/a&gt;.&amp;nbsp; I&amp;#39;ll also point to &lt;a href="http://www.rgoarchitects.com/nblog/2008/05/04/OOPsAnExampleOfMisusingTheTermOOP.aspx" target="_blank"&gt;Arnon&amp;#39;s reaction&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Exhibit A:&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.lostechies.com/blogs/evan_hoff/WindowsLiveWriter/AVeryPoorObjectModelIsReallyNoObjectMode_13513/objectmodel%5B3%5D.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="461" src="http://www.lostechies.com/blogs/evan_hoff/WindowsLiveWriter/AVeryPoorObjectModelIsReallyNoObjectMode_13513/objectmodel_thumb%5B1%5D.png" width="640" border="0" alt="" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;&lt;strong&gt;This is a very, very poor object model.&lt;/strong&gt;&amp;nbsp; It&amp;#39;s a very poor object model even if it perfectly represents the business requirements. I&amp;#39;m going to nickname this the &amp;quot;college freshman&amp;quot; object model, and we all know how useful college freshmen are in the real world (and just how much they have to learn before they become useful).&amp;nbsp; In short, never do this--again, even if it perfectly represents your business problem (which it won&amp;#39;t).&lt;/p&gt; &lt;p&gt;I&amp;#39;ll also repeat what Arnon said.&amp;nbsp; In a nutshell, &lt;strong&gt;don&amp;#39;t use a bulldozer where a simple shovel will do&lt;/strong&gt;.&amp;nbsp; Building an app for a vet is a good candidate for CRUD and Microsoft Access.&amp;nbsp; Don&amp;#39;t overcomplicate your solution.&lt;/p&gt; &lt;p&gt;Also,&lt;strong&gt; if you are developing outside the guidance and expertise of the customer, you greatly increase your chances of failure and waste.&amp;nbsp; Don&amp;#39;t do that.&amp;nbsp; It&amp;#39;s irresponsible and foolish.&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;I&amp;#39;d also like to point out that this object model is driven by the C++ object model thinking&amp;nbsp;of yesterday.&amp;nbsp; We&amp;#39;ve learned a lot since the 70&amp;#39;s and 80&amp;#39;s, and that includes how to do objects.&lt;/p&gt; &lt;p&gt;I&amp;#39;ll point out two very important facts that are rather obvious:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;We don&amp;#39;t have multiple inheritance in C# or VB.NET.&amp;nbsp; That greatly affects how we do OOP.&lt;/li&gt; &lt;li&gt;Inheritance is a very fragile.&amp;nbsp; 99% of the time it&amp;#39;s the wrong tool to use (as this diagram elegantly illustrates)&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Luckily, we&amp;#39;ve learned a lot in the past 10 years and evolved our design techniques since then.&lt;/p&gt; &lt;p&gt;Inheritance is the old stuff.&amp;nbsp; Composition is the new stuff.&amp;nbsp; We&amp;#39;ve learned about the &lt;a href="http://en.wikipedia.org/wiki/Fragile_base_class" target="_blank"&gt;fragile base class&lt;/a&gt; problem and moved on.&amp;nbsp; A solution using composition (instead of inheritance) yields way more flexibility and is much more resilient to change (when used properly).&amp;nbsp; Where inheritance represents the relationship with the most coupling between two classes, composition allows us to freely decouple two (or more) classes.&lt;/p&gt; &lt;p&gt;Is bad OOP really bad OOP or is it just not OOP at all?&lt;/p&gt; &lt;p&gt;&lt;strong&gt;If&amp;nbsp;you&amp;#39;ve implemented a deep type hierarchy in your .NET app while trying to build an &amp;quot;object model&amp;quot;, you&amp;#39;ve sorely misunderstood how to apply OOP in .NET.&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;In conclusion, I&amp;#39;d like to challenge Keith to write a new post on the following:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;The reason is because we have been beat to death with OOP principles.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;I&amp;#39;d be curious as to what principles you are referring to.&amp;nbsp;&amp;nbsp;I get the feeling that the OOP principles you are referring to are completely different from the ones I follow.&amp;nbsp; I&amp;#39;d love to carry this discussion further.&lt;/p&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=3151" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=zWlKDH"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=zWlKDH" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=31a89h"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=31a89h" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=xAqndH"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=xAqndH" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/LosTechies/~4/283658460" height="1" width="1"/&gt;</description><feedburner:origLink>http://www.lostechies.com/blogs/evan_hoff/archive/2008/05/04/a-very-poor-object-model-is-really-no-object-model-at-all.aspx</feedburner:origLink></item><item><title>Tying up loose ends</title><link>http://feeds.feedburner.com/~r/LosTechies/~3/283658461/tying-up-loose-ends.aspx</link><pubDate>Mon, 05 May 2008 02:53:45 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:3150</guid><dc:creator>chadmyers</dc:creator><slash:comments>6</slash:comments><description>&lt;h1&gt;Blogging Stuff&lt;/h1&gt; &lt;p&gt;Just in case anyone was following/caring, I had started a few multi-part series posts that kind of fizzled out and I felt I owed the 3 of you who cared an explanation:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Agile Arguments: No one seemed to pick up or care about this one. I have a two half-written parts to this, but I&amp;#39;m not going to flog myself to finish them if there&amp;#39;s no interest.&lt;/li&gt; &lt;li&gt;Pablo&amp;#39;s Topic of the Month for April: Design Patterns - no one else chimed in on this one. April was rough for a lot of people and we just didn&amp;#39;t get it done. Sorry folks :(&amp;nbsp; We&amp;#39;re human. We may try something for May, or pick it up again in June with a new topic (hopefully something that requires a little less investment so we can get back up to speed)&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;I think I might back away from heady posts altogether and get back to more code/task-oriented posts. There&amp;#39;s a ton of stuff out there and I&amp;#39;d like to start doing some real-world minutiae stuff with some test-driven design, IoC, or other stuff I preach sneakily thrown in there in the hopes that that might be a more effective strategy for getting people excited about some of these accelerators I have found.&lt;/p&gt; &lt;h1&gt;Community Stuff&lt;/h1&gt; &lt;h2&gt;CodingDojo&lt;/h2&gt; &lt;p&gt;The next incarnation of the TDD CodingDojo was planned for April, but my job situation + ALT.NET Seattle threw a wrench in that. May turned out to be for similar reasons. So the current plan is some time in June (hopefully early). We&amp;#39;ll see. Several of you have offered to help set up something and we (and I think I can speak for the Los Techies crew here) really appreciate the offer and we&amp;#39;ll probably be calling on you sometime soon.&lt;/p&gt; &lt;h2&gt;Screencasts&lt;/h2&gt; &lt;p&gt;I recorded a screencast with &lt;a href="http://www.flux88.com/"&gt;Ben Scheirman&lt;/a&gt; a few weekends ago and it worked out pretty well, I thought. Unfortunately there was some temporal distortion between our two audio streams, and last I checked he was slogging it out doing some grunt work to get it straightened out (thanks Ben!)&amp;nbsp; If anyone knows why one audio stream slowly gets out of sync with the other (i.e. about 1 second every few minutes), we&amp;#39;d appreciate some help.&lt;/p&gt; &lt;p&gt;&lt;a&gt;Ray Houston&lt;/a&gt; and &lt;a&gt;Jimmy Bogard&lt;/a&gt; just recorded a screencast and it&amp;#39;s coming together nicely in post-production. Look for one of them (hopefully) to post about this soon (great job guys!)&lt;/p&gt; &lt;p&gt;I&amp;#39;d encourage all four of you who read my blog to consider doing a screencast.&amp;nbsp; It&amp;#39;s a lot easier to do it in person, so if you&amp;#39;re in Austin maybe we could set something up together?&lt;/p&gt; &lt;h2&gt;DotNetSlackers and other sites&lt;/h2&gt; &lt;p&gt;The crew over at &lt;a&gt;DotNetSlackers.com&lt;/a&gt; are doing some pretty cool things and they&amp;#39;re asking for folks to help write articles, send in snippets, etc. I going to *try* to do some of these in the near future (I keep promising Sonu, but never following up -- sorry man).&lt;/p&gt; &lt;p&gt;I&amp;#39;d like to suggest anyone who has even simple snippets or interesting ASP.NET MVC usage examples, or maybe even NHibernate 101 stuff, contributing it to DotNetSlackers to further the art. They&amp;#39;re clamoring for high quality content and they&amp;#39;re even willing to &lt;a href="http://dotnetslackers.com/articles/SubmissionGuidelines.aspx"&gt;&lt;strong&gt;&lt;em&gt;PAY&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt; for content! Yes, that&amp;#39;s right, pay! :) It&amp;#39;s in your professional as well as personal interests to contribute to a site like this (disclaimer: I have no affiliation with this site other than being an occasional forum poster and I received no money or other compensation to say any of this -- I just like the site).&lt;/p&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=3150" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=4X50dH"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=4X50dH" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=ghhYSh"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=ghhYSh" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=KY4mwH"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=KY4mwH" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/LosTechies/~4/283658461" height="1" width="1"/&gt;</description><category domain="http://www.lostechies.com/blogs/chad_myers/archive/tags/Misc/default.aspx">Misc</category><feedburner:origLink>http://www.lostechies.com/blogs/chad_myers/archive/2008/05/04/tying-up-loose-ends.aspx</feedburner:origLink></item><item><title>A Reader Challenge</title><link>http://feeds.feedburner.com/~r/LosTechies/~3/283633439/a-reader-challenge.aspx</link><pubDate>Mon, 05 May 2008 01:46:08 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:3148</guid><dc:creator>hoffe</dc:creator><slash:comments>2</slash:comments><description>&lt;p&gt;This is a simple challenge.&amp;nbsp; I want you to figure this out for yourself.&amp;nbsp; It&amp;#39;s an important step I think every developer needs to take for him/herself.&lt;/p&gt; &lt;p&gt;Also, please don&amp;#39;t give any direct answers in the comments&amp;nbsp;or I will delete them. Non-answer comments are perfectly acceptable.&amp;nbsp; :-)&lt;/p&gt; &lt;p&gt;Without further ado, can you please give a simple definition and compare the following:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Procedural Code&lt;/li&gt; &lt;li&gt;Object-based Code&lt;/li&gt; &lt;li&gt;Object-oriented Code&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;In particular, what&amp;#39;s the difference between object-based code and object-oriented code?&amp;nbsp; I&amp;#39;ll give you a clue, it doesn&amp;#39;t particularly have anything to do with inheritance.&lt;/p&gt; &lt;p&gt;You might find these concepts in a few books.&amp;nbsp; I&amp;#39;ll drop a couple references here.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href="http://www.amazon.com/C%2B%2B-Primer-4th-Stanley-Lippman/dp/0201721481/" target="_blank"&gt;C++ Primer&lt;/a&gt; (Parts 3, 4, and 5)&lt;/li&gt; &lt;li&gt;&lt;a href="http://www.amazon.com/Object-Oriented-Design-Heuristics-Arthur-Riel/dp/020163385X" target="_blank"&gt;Object-Oriented Design Heuristics&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Finally, I&amp;#39;ll leave you with a slightly harder teaser problem.&amp;nbsp; What&amp;#39;s an &amp;quot;Object Role&amp;quot;?&lt;/p&gt; &lt;p&gt;If you are unsure, feel free to drop me an email, and I&amp;#39;ll steer you in the right direction (evanatevanhoffdotcom).&amp;nbsp; I&amp;#39;m not recommending those books for starters (although I&amp;#39;m sure they are great books).&lt;/p&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=3148" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=AxxcKH"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=AxxcKH" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=Rpxpeh"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=Rpxpeh" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=ftzMMH"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=ftzMMH" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/LosTechies/~4/283633439" height="1" width="1"/&gt;</description><feedburner:origLink>http://www.lostechies.com/blogs/evan_hoff/archive/2008/05/04/a-reader-challenge.aspx</feedburner:origLink></item><item><title>Connecting ActiveRecord to SQL Server</title><link>http://feeds.feedburner.com/~r/LosTechies/~3/282825815/connecting-activerecord-to-sql-server.aspx</link><pubDate>Sat, 03 May 2008 16:13:36 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:3146</guid><dc:creator>Ray Houston</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;&lt;em&gt;Disclaimer: I&amp;#39;m a Ruby noobie. I know nada about Rails. Please leave a comment if something is not correct or if there is a better way to do this.&lt;/em&gt;&lt;/p&gt; &lt;p&gt;At work, we&amp;#39;re using &lt;a href="http://wtr.rubyforge.org/"&gt;Watir&lt;/a&gt; to drive a &lt;a href="http://silverlight.net/"&gt;Silverlight&lt;/a&gt; application for some automated end to end testing. We needed an easy way to access the database from our RSpec test fixtures to make sure the proper setup data is put where we need it. I discovered that ActiveRecord can be used without rails and that all I needed to do was just install the gem. Typing the following seemed to do the trick for me:&lt;/p&gt; &lt;div&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;gem install activerecord&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I then found &lt;a href="http://wiki.rubyonrails.org/rails/pages/HowtoConnectToMicrosoftSQLServer"&gt;this&lt;/a&gt; which told me that I have install the SQLServer adapter separately like so:&lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;gem install activerecord-sqlserver-adapter --source=http://gems.rubyonrails.org&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It then also says that one must get the latest source distribution of Ruby-DBI from &lt;a href="http://rubyforge.org/projects/ruby-dbi/%20"&gt;here&lt;/a&gt; and copy the file:&lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;lib/dbd/ADO.rb&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;to your Ruby installation directory in the following place:&lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;X:/ruby/lib/ruby/site_ruby/1.8/DBD/ADO/ADO.rb&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After that I was able to create a simple test page to see if could actually get connected.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;ActiveRecordTest.rb&lt;/em&gt;&lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;require &amp;#39;active_record&amp;#39;

ActiveRecord::Base.pluralize_table_names = false

ActiveRecord::Base.establish_connection(
    :adapter =&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt; &amp;quot;sqlserver&amp;quot;,
    :host =&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt; &amp;quot;.\\SQLEXPRESS&amp;quot;,
    :database =&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt; &amp;quot;MyDB&amp;quot;,
    :username =&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt; &amp;quot;sa&amp;quot;,
    :password =&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt; &amp;quot;sa&amp;quot;
)

class Customer &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt; ActiveRecord::Base
end

Customer.find(:all).each do |cust| puts cust.Name end&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This test selects all the customers and outputs their names.&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:c15f669f-91af-41dc-9b01-86059c8662f1" style="padding-right:0px;display:inline;padding-left:0px;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/Ruby" rel="tag"&gt;Ruby&lt;/a&gt;,&lt;a href="http://technorati.com/tags/ActiveRecord" rel="tag"&gt;ActiveRecord&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=3146" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=dfNMJH"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=dfNMJH" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=ny8ssh"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=ny8ssh" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=GiwvbH"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=GiwvbH" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/LosTechies/~4/282825815" height="1" width="1"/&gt;</description><feedburner:origLink>http://www.lostechies.com/blogs/rhouston/archive/2008/05/03/connecting-activerecord-to-sql-server.aspx</feedburner:origLink></item><item><title>Developers or engineers?</title><link>http://feeds.feedburner.com/~r/LosTechies/~3/281165040/developers-or-engineers.aspx</link><pubDate>Thu, 01 May 2008 00:50:12 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:3118</guid><dc:creator>bogardj</dc:creator><slash:comments>21</slash:comments><description>&lt;p&gt;I&amp;#39;ve had quite a few job titles where I basically did the same function: Software Engineer, Software Developer, Technical Lead, and so on.&amp;nbsp; In some companies, a Software Developer is a completely different position than Software Engineer, and in others they&amp;#39;re used interchangeably.&lt;/p&gt; &lt;p&gt;The connotations and implications from each title are strikingly different.&amp;nbsp; The term &amp;quot;engineer&amp;quot; has a much different meaning than &amp;quot;developer&amp;quot;, taken outside the context of software. A Developer might lay out the plan of a new subdivision, where its green areas are, what style homes should be built and what theme the neighborhood should adhere to.&amp;nbsp; The Engineer lays out the water and sewage lines, elevations, roads, utilities and other functions vital for sustainable human habitability.&amp;nbsp; &lt;strong&gt;A Developer creates the vision and designs the implementation, while the Engineer ensures that quality, regulatory and ethical standards have been met&lt;/strong&gt;.&lt;/p&gt; &lt;p&gt;That&amp;#39;s not to say an Engineer isn&amp;#39;t creative.&amp;nbsp; In a family full of Engineering graduates (including myself), no Engineer would have a job if they weren&amp;#39;t creative.&amp;nbsp; Every problem is an implementation of a different pattern, but the details make each challenge completely different than the one before.&lt;/p&gt; &lt;p&gt;Having worked with many types of real Engineers (i.e., they&amp;#39;re doing the job they went to school for), I didn&amp;#39;t see what they were doing was much different than me.&amp;nbsp; They were concerned with:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Safety&lt;/li&gt; &lt;li&gt;Reliability&lt;/li&gt; &lt;li&gt;Maintainability&lt;/li&gt; &lt;li&gt;Aesthetics&lt;/li&gt; &lt;li&gt;Usability&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;As well as a host of other &amp;quot;ilities&amp;quot;.&amp;nbsp; One critical difference between me as a Developer and they as an Engineer was that &lt;strong&gt;Engineers are licensed by an &lt;a href="http://www.ncees.org/"&gt;independent group&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;In many fields and jurisdiction, including Civil Engineering in Texas, &lt;strong&gt;licensing is required by law when performing engineering services for the public&lt;/strong&gt;.&amp;nbsp; Licensing isn&amp;#39;t easy, either.&amp;nbsp; To become a licensed Professional Engineer PE, you must:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Graduate from an accredited engineering program&lt;/li&gt; &lt;li&gt;Take an initial exam to become an Engineering-in-Training (EIT)&lt;/li&gt; &lt;li&gt;Have a minimum of 4 years experience as an EIT, preferably as an apprentice to another PE&lt;/li&gt; &lt;li&gt;Take a rigorous exam, which takes 6-8 hours to complete&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Licensing isn&amp;#39;t a one-time affair, you have to renew your license, which has its own requirements including continuing education.&amp;nbsp; Even if not working in the public sector, licensing is considered a career necessity.&lt;/p&gt; &lt;h3&gt;But we have certifications, right?&lt;/h3&gt; &lt;p&gt;Anyone that has interviewed candidates for positions knows the sad state of software certifications.&amp;nbsp; &lt;strong&gt;At best, software certifications signify that your are certified to be an absolute beginner for that topic.&lt;/strong&gt;&amp;nbsp; For some reason, software certifications still hold value, though all involved, managers, HR and candidates, know that the certifications aren&amp;#39;t worth bytes it was emailed with.&lt;/p&gt; &lt;p&gt;Would licensing help our industry?&amp;nbsp; We live in a sad state of affairs when identities are not stolen because of sifting through your mail or stealing your wallet, but &lt;a href="http://thedailywtf.com/Articles/Oklahoma-Leaks-Tens-of-Thousands-of-Social-Security-Numbers,-Other-Sensitive-Data.aspx"&gt;because of careless, ignorant developers&lt;/a&gt;.&amp;nbsp; In a Twitter conversation with an &lt;a href="http://terrbear.org/"&gt;ex-colleague&lt;/a&gt;, Terry noted that software development lacked discipline, respect and accountability.&amp;nbsp; Can licensing help prevent the ridiculous failures, by both raising the bar and raising the stakes for individual failure?&lt;/p&gt; &lt;p&gt;If a bridge fails, the engineers can be held liable if they are found to cut corners, or even sheer ignorance.&amp;nbsp; Oversight in the form of inspectors is supposed to help, but in the end, the engineers are held accountable.&lt;/p&gt; &lt;p&gt;I see Developers as code monkeys, slapping code out without regard to reliability and maintainability.&amp;nbsp; Engineers have a much longer horizon too look at, they must ensure the bridge they build lasts 100 years, not six months.&amp;nbsp; &lt;strong&gt;Shouldn&amp;#39;t we hold ourselves up to the same standard?&lt;/strong&gt;&lt;/p&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=3118" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=l4qO3G"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=l4qO3G" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=OxV4ug"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=OxV4ug" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=dPpVZG"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=dPpVZG" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/LosTechies/~4/281165040" height="1" width="1"/&gt;</description><category domain="http://www.lostechies.com/blogs/jimmy_bogard/archive/tags/Misc/default.aspx">Misc</category><feedburner:origLink>http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/04/30/developers-or-engineers.aspx</feedburner:origLink></item><item><title>Open Spaces In Practice</title><link>http://feeds.feedburner.com/~r/LosTechies/~3/280540192/open-spaces-in-practice.aspx</link><pubDate>Wed, 30 Apr 2008 04:04:59 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:3114</guid><dc:creator>Chris Patterson</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;After a great weekend in Seattle for the ALT.NET Open Spaces event (aside from a slight error in judgement on Friday night &lt;a href="http://flux88.com/ALTNETDay1.aspx"&gt;as depicted in this blog post&lt;/a&gt;), the two coworkers and I discussed how we could bring the experience of Open Spaces back to the team in Tulsa. We decided that instead of just giving a few talks about some of the things we took away from Seattle, we would bring the experience itself to the team.&lt;/p&gt;

&lt;p&gt;At the end of our team meeting on Monday, we laid out some paper and pens and asked members of the team to write up topics that they wanted to discuss. It started a bit slow, but within minutes we had &lt;strong&gt;eighteen&lt;/strong&gt; topics on the wall. The variety of topics was excellent, most of which targeted a different subset of the team. It was great to see the team come up with such a nice list of things for the team to discuss.&lt;/p&gt;

&lt;p&gt;We then drew a grid of time slots on the whiteboard and asked the team to put their initials on the topics they wanted to attend. As the papers filled up, we started aligning them into the grid based on popularity and expected duration. We tried to keep all of them to an hour but some of the topics were given ninety minutes based on the content.&lt;/p&gt;

&lt;p&gt;We had to negotiate on some of the topics to fit our time slots, and combined a couple of similar discussions into the same time period so that we could maximize our coverage over the next few days. Some topics were brought up that are timely to an upcoming release of our software, so those were given a slight priority in the schedule.&lt;/p&gt;

&lt;p&gt;Overall, I was very impressed with the contributions by the team. Topics included things like &amp;quot;maximizing the use of Resharper&amp;quot;, &amp;quot;What are unit tests&amp;quot;, and &amp;quot;How can we test better?&amp;quot; With the large number of topics on the schedule, we&amp;#39;re hoping that we can set aside a couple of days a week (maybe Tuesday and Thursday over lunch) to continue with more discussions. I&amp;#39;ll be sure to post a follow up as things unfold over the next week.&lt;/p&gt;
&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=3114" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=2gnndG"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=2gnndG" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=DE1iig"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=DE1iig" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=lhmWZG"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=lhmWZG" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/LosTechies/~4/280540192" height="1" width="1"/&gt;</description><feedburner:origLink>http://www.lostechies.com/blogs/chris_patterson/archive/2008/04/29/open-spaces-in-practice.aspx</feedburner:origLink></item><item><title>xkcd2 - someone is wrong</title><link>http://feeds.feedburner.com/~r/LosTechies/~3/279532327/xkcd2-someone-is-wrong.aspx</link><pubDate>Mon, 28 Apr 2008 17:40:00 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:3106</guid><dc:creator>Jason Meridth</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;Who was I thinking of when I read this?&amp;nbsp; Oh, there are so many people. (mouse over for alt text, funny also -- you do this with all xkcd comics)&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;img src="http://imgs.xkcd.com/comics/duty_calls.png" title="What do you want me to do?  LEAVE?  Then they&amp;#39;ll keep being wrong!" align="" border="0" height="330" hspace="" width="300" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=3106" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=5xU7wG"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=5xU7wG" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=tmaTog"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=tmaTog" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=3lnLhG"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=3lnLhG" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/LosTechies/~4/279532327" height="1" width="1"/&gt;</description><category domain="http://www.lostechies.com/blogs/jason_meridth/archive/tags/funny/default.aspx">funny</category><feedburner:origLink>http://www.lostechies.com/blogs/jason_meridth/archive/2008/04/28/xkcd2-someone-is-wrong.aspx</feedburner:origLink></item><item><title>xkcd - ubuntu, python comics</title><link>http://feeds.feedburner.com/~r/LosTechies/~3/279532334/xkcd-ubuntu-python-comics.aspx</link><pubDate>Mon, 28 Apr 2008 17:34:00 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:3105</guid><dc:creator>Jason Meridth</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;If you don&amp;#39;t currently read &lt;a href="http://www.xkcd.com" target="_blank"&gt;xkcd.com&lt;/a&gt;, you should be.&amp;nbsp; It has some mushy lovey dovey junk in it sometimes, but the python references and open source references are hilarious.&lt;/p&gt;&lt;p&gt;Today&amp;#39;s comic: (mouse over for the Ubuntu reference)&lt;br /&gt;&lt;br /&gt;&lt;img src="http://imgs.xkcd.com/comics/zealous_autoconfig.png" title="I hear this is an option in the latest Ubuntu release" align="" border="0" height="211" hspace="" width="740" alt="" /&gt; &lt;/p&gt;&lt;p&gt;One of my other favs:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://imgs.xkcd.com/comics/python.png" title="I wrote 20 short programs in Python yesterday.  It was wonderful.  Perl, I&amp;#39;m leaving you." align="" border="0" height="588" hspace="" width="518" alt="" /&gt; &lt;br /&gt;&lt;/p&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=3105" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=oanGgG"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=oanGgG" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=b86LNg"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=b86LNg" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=rDZtwG"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=rDZtwG" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/LosTechies/~4/279532334" height="1" width="1"/&gt;</description><category domain="http://www.lostechies.com/blogs/jason_meridth/archive/tags/Linux/default.aspx">Linux</category><category domain="http://www.lostechies.com/blogs/jason_meridth/archive/tags/Ubuntu/default.aspx">Ubuntu</category><category domain="http://www.lostechies.com/blogs/jason_meridth/archive/tags/funny/default.aspx">funny</category><category domain="http://www.lostechies.com/blogs/jason_meridth/archive/tags/xkcd/default.aspx">xkcd</category><feedburner:origLink>http://www.lostechies.com/blogs/jason_meridth/archive/2008/04/28/xkcd-ubuntu-python-comics.aspx</feedburner:origLink></item><item><title>Nested classes with JUnit</title><link>http://feeds.feedburner.com/~r/LosTechies/~3/279463136/nested-classes-with-junit.aspx</link><pubDate>Mon, 28 Apr 2008 14:56:00 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:3101</guid><dc:creator>jlockwood</dc:creator><slash:comments>0</slash:comments><description>Recently I was playing with JUnit 4.X. I wanted to be able to define tests in nested classes as I had before with NUnit. This was to facilitate BDD-ish test definitions, where I break up unit tests by test context. My first attempt failed (of course) because JUnit was unable to see the nested classes and the failed to run. After a bit of digging, I ran across a sparsely documented feature that allowed me to do what I wanted. Namely by using: @RunWith(Enclosed.class) Below is an example, hope it&amp;#39;s...(&lt;a href="http://www.lostechies.com/blogs/joshua_lockwood/archive/2008/04/28/nested-classes-with-junit.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=3101" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=fnJrkG"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=fnJrkG" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=TqXDWg"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=TqXDWg" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=eiDFFG"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=eiDFFG" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/LosTechies/~4/279463136" height="1" width="1"/&gt;</description><category domain="http://www.lostechies.com/blogs/joshua_lockwood/archive/tags/Unit+Tests/default.aspx">Unit Tests</category><category domain="http://www.lostechies.com/blogs/joshua_lockwood/archive/tags/JUnit/default.aspx">JUnit</category><category domain="http://www.lostechies.com/blogs/joshua_lockwood/archive/tags/Java/default.aspx">Java</category><feedburner:origLink>http://www.lostechies.com/blogs/joshua_lockwood/archive/2008/04/28/nested-classes-with-junit.aspx</feedburner:origLink></item><item><title>Understanding Mock Objects: an alternate solution</title><link>http://feeds.feedburner.com/~r/LosTechies/~3/279097107/understanding-mock-objects-an-alternate-solution.aspx</link><pubDate>Mon, 28 Apr 2008 02:27:53 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:3089</guid><dc:creator>bogardj</dc:creator><slash:comments>14</slash:comments><description>&lt;p&gt;In &lt;a href="http://geekswithblogs.net/AzamSharp/Default.aspx"&gt;AzamSharp&amp;#39;s&lt;/a&gt; recent post &lt;a href="http://geekswithblogs.net/AzamSharp/archive/2008/04/27/121695.aspx"&gt;Understanding Mock Objects&lt;/a&gt;, he poses a problem of testing with volatile data.&amp;nbsp; His example extends on &lt;a href="http://aspalliance.com/1400_Beginning_to_Mock_with_Rhino_Mocks_and_MbUnit__Part_1.all"&gt;an article on AspAlliance&lt;/a&gt;, which exhibits the same problems with its solution.&amp;nbsp; Suppose I have an image service that returns images based on the time of day:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public static class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ImageOfTheDayService
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;public static string &lt;/span&gt;GetImage(&lt;span style="color:#2b91af;"&gt;DateTime &lt;/span&gt;dt)
    {
        &lt;span style="color:blue;"&gt;int &lt;/span&gt;hour = dt.Hour;

        &lt;span style="color:blue;"&gt;if &lt;/span&gt;(hour &amp;gt; 6 &amp;amp;&amp;amp; hour &amp;lt; 21) &lt;span style="color:blue;"&gt;return &lt;/span&gt;&lt;span style="color:#a31515;"&gt;&amp;quot;sun.jpg&amp;quot;&lt;/span&gt;;

        &lt;span style="color:blue;"&gt;return &lt;/span&gt;&lt;span style="color:#a31515;"&gt;&amp;quot;moon.jpg&amp;quot;&lt;/span&gt;;
    }
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;The initial test uses the current date and time to perform the test:&lt;/p&gt;&lt;pre class="code"&gt;[&lt;span style="color:#2b91af;"&gt;Test&lt;/span&gt;]
&lt;span style="color:blue;"&gt;public void &lt;/span&gt;should_return_sun_image_when_it_is_day_time()
{
    &lt;span style="color:blue;"&gt;string &lt;/span&gt;imageName = &lt;span style="color:#2b91af;"&gt;ImageOfTheDayService&lt;/span&gt;.GetImage(&lt;span style="color:#2b91af;"&gt;DateTime&lt;/span&gt;.Now);
    &lt;span style="color:#2b91af;"&gt;Assert&lt;/span&gt;.AreEqual(imageName, &lt;span style="color:#a31515;"&gt;&amp;quot;sun.jpg&amp;quot;&lt;/span&gt;);
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;Since DateTime.Now is non-deterministic, this test will pass only some of the time, and will at other times.&amp;nbsp; The problem is that this test has a dependency on the system clock.&amp;nbsp; AzamSharp&amp;#39;s solution to this problem was to create an interface to wrap DateTime:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public interface &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IDateTime
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;int &lt;/span&gt;GetHour();
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;Now the ImageOfTheDayService uses IDateTime to determine the hour:&lt;/p&gt;&lt;pre class="code"&gt;[&lt;span style="color:#2b91af;"&gt;Test&lt;/span&gt;]
&lt;span style="color:blue;"&gt;public void &lt;/span&gt;MOCKING_should_return_night_image_when_it_is_night_time()
{
    &lt;span style="color:blue;"&gt;var &lt;/span&gt;mock = &lt;span style="color:blue;"&gt;new &lt;/span&gt;Mock&amp;lt;&lt;span style="color:#2b91af;"&gt;IDateTime&lt;/span&gt;&amp;gt;();
    mock.Expect(e =&amp;gt; e.GetHour()).Returns(21); &lt;span style="color:green;"&gt;// 9:00 PM

    &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="color:#a31515;"&gt;&amp;quot;moon.jpg&amp;quot;&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;ImageOfTheDayService&lt;/span&gt;.GetImage(mock.Object));
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;I &lt;em&gt;really&lt;/em&gt; don&amp;#39;t like this solution, as &lt;strong&gt;the test had the external non-deterministic dependency&lt;/strong&gt;, not the image service.&lt;/p&gt;
&lt;h3&gt;Alternative solution&lt;/h3&gt;
&lt;p&gt;Here&amp;#39;s another solution that doesn&amp;#39;t use mocks, and keeps the original DateTime parameter:&lt;/p&gt;&lt;pre class="code"&gt;[&lt;span style="color:#2b91af;"&gt;Test&lt;/span&gt;]
&lt;span style="color:blue;"&gt;public void &lt;/span&gt;should_return_night_image_when_it_is_night_time()
{
    &lt;span style="color:#2b91af;"&gt;DateTime &lt;/span&gt;nightTime = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DateTime&lt;/span&gt;(2000, 1, 1, 0, 0, 0);

    &lt;span style="color:blue;"&gt;string &lt;/span&gt;imageName = &lt;span style="color:#2b91af;"&gt;ImageOfTheDayService&lt;/span&gt;.GetImage(nightTime);
    &lt;span style="color:#2b91af;"&gt;Assert&lt;/span&gt;.AreEqual(imageName, &lt;span style="color:#a31515;"&gt;&amp;quot;moon.jpg&amp;quot;&lt;/span&gt;);
}
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;Note that I eliminated the dependency on the system clock by simply creating a DateTime that represents &amp;quot;night time&amp;quot;.&amp;nbsp; Another test creates a &amp;quot;day time&amp;quot; DateTime, and perhaps more to fill in edge cases.&amp;nbsp; Instead of creating an interface to wrap something that didn&amp;#39;t need fixing, we used DateTime exactly how they were designed.&amp;nbsp; DateTime.Now is not the only way to create a DateTime object.&lt;/p&gt;
&lt;p&gt;Solving a non-deterministic test with mocks only works when it&amp;#39;s the component under test that has the non-deterministic dependencies.&amp;nbsp; In the example AzamSharp&amp;#39;s example, it was the test, and not the component that had the non-deterministic dependency.&amp;nbsp; Creating the DateTime using its constructor led to both a more readable test and a more cohesive interface for the image service.&lt;/p&gt;
&lt;p&gt;It&amp;#39;s easy to believe everything is a nail if all you want to use is that shiny hammer.&amp;nbsp; Keep in mind the purpose of mocks: to verify the indirect inputs and outputs of a component, not to fix every &lt;a href="http://xunitpatterns.com/Erratic%20Test.html"&gt;erratic test&lt;/a&gt; under the sun.&lt;/p&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=3089" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=yyEqXG"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=yyEqXG" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=sIF5Ig"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=sIF5Ig" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=Exq5cG"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=Exq5cG" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/LosTechies/~4/279097107" height="1" width="1"/&gt;</description><feedburner:origLink>http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/04/27/understanding-mock-objects-an-alternate-solution.aspx</feedburner:origLink></item><item><title>Ubuntu 8.04, VirtualBox, and USB support</title><link>http://feeds.feedburner.com/~r/LosTechies/~3/278984051/using-the-gutsy-gibbon-ubuntu-7-10-non-ose-version-of-virtualbox-with-your-hardy-heron-ubuntu-8-04-install.aspx</link><pubDate>Sun, 27 Apr 2008 16:42:00 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:3087</guid><dc:creator>Jason Meridth</dc:creator><slash:comments>8</slash:comments><description>&lt;p&gt;&lt;i&gt;&lt;b&gt;UPDATE&lt;/b&gt;: Make sure your user account is a member of the vboxusers account.&amp;nbsp; VirtualBox will not start and the error will tell you this, but just want to be explicit.&amp;nbsp; You will have to logout and log back in. &lt;/i&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;I recently upgraded my Ubuntu to the latest version, as mentioned in a previous post.&amp;nbsp; I&amp;#39;m very excited about it, due to greater support for hardware items that I&amp;#39;ve had to fight battles with (one of the many reasons people won&amp;#39;t make the switch to Linux).&amp;nbsp; I upgraded to Hardy Heron and then upgraded VirtualBox when prompted.&amp;nbsp; It was a fatal hardware recognition mistake.&amp;nbsp; As soon as I booted back up after a restart, I didn&amp;#39;t have sound, wireless, etc.&amp;nbsp; &lt;/p&gt;&lt;p&gt;After just not being in the mood of going down the road of trying to get the hardware re-recognized, I reloaded and di my research on the virtualbox upgrade.&amp;nbsp; It seems to be a known issue on the ubuntuforms.&amp;nbsp;&lt;/p&gt;&lt;p&gt;I looked through the forums and got educated on a few things about the ose (open source edition) versions of VirtualBox.&amp;nbsp; 1. no usb support (I will update if I&amp;#39;m proved wrong). 2. the new ose kernel modules hose toshiba satellite hardware detection (at least on my laptop).&lt;/p&gt;&lt;p&gt;To get the gutsy non-ose version of Virtual Box, add this repository to /etc/apt/sources.list:&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;font face="Courier New"&gt;deb http://www.virtualbox.org/debian gutsy non-free &lt;/font&gt;&lt;br /&gt;
&lt;br /&gt;
then in a terminal:&lt;/p&gt;&lt;p&gt; &lt;font face="Courier New"&gt; apt-get update&lt;br /&gt;apt-get install virtualbox&lt;/font&gt; &lt;br /&gt;&lt;/p&gt;&lt;p&gt;if you get a host key issue, the do the following:&lt;/p&gt;&lt;p&gt;go get the public key.. go to this website and it&amp;#39;ll have the
key there just right click anywhere in the page and go to save page as
then save it to your home directory preferably.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.virtualbox.org/debian/innotek.asc" target="_blank"&gt;http://www.virtualbox.org/debian/innotek.asc&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Now to add that key run...&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;font face="Courier New"&gt;apt-key add innotek.asc&lt;br /&gt;apt-get update&lt;br /&gt;apt-get install virtualbox&lt;/font&gt; &lt;/p&gt;&lt;p&gt;This will give you the gutsy version that I&amp;#39;ve worked with and have had no problems with.&amp;nbsp; The bonus is that you get USB support.&amp;nbsp;&lt;/p&gt;&lt;p&gt;I will get back to code posts next.&amp;nbsp; Just want to share the knowledge with other Linux users.&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=3087" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=YckXBG"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=YckXBG" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=NhhUng"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=NhhUng" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=zJc5QG"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=zJc5QG" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/LosTechies/~4/278984051" height="1" width="1"/&gt;</description><category domain="http://www.lostechies.com/blogs/jason_meridth/archive/tags/Tools/default.aspx">Tools</category><category domain="http://www.lostechies.com/blogs/jason_meridth/archive/tags/Linux/default.aspx">Linux</category><category domain="http://www.lostechies.com/blogs/jason_meridth/archive/tags/Ubuntu/default.aspx">Ubuntu</category><category domain="http://www.lostechies.com/blogs/jason_meridth/archive/tags/Virtual+Machine/default.aspx">Virtual Machine</category><feedburner:origLink>http://www.lostechies.com/blogs/jason_meridth/archive/2008/04/27/using-the-gutsy-gibbon-ubuntu-7-10-non-ose-version-of-virtualbox-with-your-hardy-heron-ubuntu-8-04-install.aspx</feedburner:origLink></item><item><title>MSDN - can't download with firefox</title><link>http://feeds.feedburner.com/~r/LosTechies/~3/278633471/msdn-can-t-download-with-firefox.aspx</link><pubDate>Sun, 27 Apr 2008 04:26:00 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:3081</guid><dc:creator>Jason Meridth</dc:creator><slash:comments>5</slash:comments><description>&lt;p&gt;&lt;i&gt;&lt;b&gt;UPDATE&lt;/b&gt;: I&amp;#39;m on Linux.&amp;nbsp; Getting this to work on Windows is simple enough, just like James mentions in the comments. Thanks.&amp;nbsp;&lt;/i&gt;&lt;/p&gt;&lt;p&gt;I&amp;#39;m writing this, because it&amp;#39;s about the 5th time I&amp;#39;ve had to use my Windows box or VM to get iso files from MSDN. &lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;lt;rant&amp;gt; &lt;br /&gt;&lt;/p&gt;&lt;p&gt;I understand, in a business manner, why Microsoft won&amp;#39;t allow downloads from Firefox at MSDN.&amp;nbsp; I work for a company that was kind enough to give me a MSDN license.&amp;nbsp; I&amp;#39;ve used it a great deal to get software like Vistual Studio 2008 and SQL Server 2008 recently.&amp;nbsp; I also use it for the iso files I use in my VMs.&amp;nbsp; I recently had to download Vista again and from Firefox the specific items I want (the checkboxes in MSDN&amp;#39;s new Silverlight UI) are grayed out.&amp;nbsp; COME ON!!!!!&lt;/p&gt;&lt;p&gt;I use Firefox more than I use Internet Explorer.&amp;nbsp; And before, you non-Linux users tell me about the IE tab plugin for Firefox, let me remind you that you still have to have iexplore.exe on your PC.&amp;nbsp; Linux doesn&amp;#39;t have it (and shouldn&amp;#39;t).&lt;/p&gt;&lt;p&gt;I like where Microsoft development teams are going recently (Guthrie, Haack, Conery, etc), but the MSDN team needs to wake up and open the ability to download items via Firefox.&lt;/p&gt;&lt;p&gt;If someone out there knows a way to do this with Firefox, I will update this post and eat some humble pie.&lt;/p&gt;&lt;p&gt;&amp;lt;/rant&amp;gt; &lt;br /&gt;&lt;/p&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=3081" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=Mh17TG"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=Mh17TG" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=MV2r7g"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=MV2r7g" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=2aFymG"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=2aFymG" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/LosTechies/~4/278633471" height="1" width="1"/&gt;</description><category domain="http://www.lostechies.com/blogs/jason_meridth/archive/tags/Tools/default.aspx">Tools</category><category domain="http://www.lostechies.com/blogs/jason_meridth/archive/tags/Ubuntu/default.aspx">Ubuntu</category><category domain="http://www.lostechies.com/blogs/jason_meridth/archive/tags/microsoft/default.aspx">microsoft</category><category domain="http://www.lostechies.com/blogs/jason_meridth/archive/tags/msdn/default.aspx">msdn</category><feedburner:origLink>http://www.lostechies.com/blogs/jason_meridth/archive/2008/04/26/msdn-can-t-download-with-firefox.aspx</feedburner:origLink></item><item><title>Ubutnu 8.04 (Hardy Heron) after upgrade - I have complete sound!!</title><link>http://feeds.feedburner.com/~r/LosTechies/~3/278405913/ubutnu-8-04-hardy-heron-after-upgrade-i-have-complete-sound.aspx</link><pubDate>Sat, 26 Apr 2008 17:46:00 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:3070</guid><dc:creator>Jason Meridth</dc:creator><slash:comments>2</slash:comments><description>&lt;p&gt;&lt;i&gt;&lt;b&gt;UPDATE&lt;/b&gt;: Do not upgrade your virtual box install.&amp;nbsp; Stay with the Gutsy version if you already have it.&amp;nbsp; If you are just installing Hardy Heron from scratch, I will have a post in a little bit and link to it here about how to ensure you get the correct version. &lt;/i&gt;&lt;/p&gt;&lt;p&gt;In a previous &lt;a href="http://www.lostechies.com/blogs/jason_meridth/archive/2007/05/12/getting-sound-working-on-my-toshiba-laptop-with-ubuntu-7-04-feisty-fawn.aspx" target="_blank"&gt;post&lt;/a&gt;, I shared the pain of getting sound working on my Toshiba Satellite laptop with prior versions of Ubuntu.&amp;nbsp; It has been off and on for a while and I&amp;#39;ve even resorting to recompiling my kernel to get it to work (no luck).&amp;nbsp; After upgrading to Hardy Heron today and restarting, I heard the wonderful drum sounds you here when Ubuntu loands.&amp;nbsp; YIPEE!!&amp;nbsp; I just logged in and finally got to watch some of the CodeBetter screencasts on the Seattle conference on my laptop without having to use my Windows VM.&amp;nbsp; For some reason, when I plugged headphones in and used my Windows VM, I got sound.&lt;/p&gt;&lt;p&gt;I also got the latest beta of Firfox 3.0.&amp;nbsp; Wow.&amp;nbsp; My del.icio.us plugin was not compatible, but I did find the &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/5457" target="_blank"&gt;Shareaholic&lt;/a&gt; plugin that lets you post to Twitter, Facebook, Reddit, Digg, Del.icio.us, etc.&amp;nbsp; Nice.&amp;nbsp; A few special effects also.&lt;/p&gt;&lt;p&gt;I noticed that the OS also has indexing in place now, so you can search for programs like you do with Vista.&lt;/p&gt;&lt;p&gt;There are other new features that I&amp;#39;m excited about, but will use them in greater detail before I blog about them.&lt;/p&gt;&lt;p&gt;Don&amp;#39;t get me wrong folks.&amp;nbsp; Microsoft pays my bills with the day job, but I like Linux for personal reasons (oh and it&amp;#39;s free).&amp;nbsp; Just want to share in case anyone is thinking about switching or is currently using and hasn&amp;#39;t upgraded. I finally got my Vista VM up and I&amp;#39;m working in IronPython again.&amp;nbsp; I plan to post on that soon.&lt;/p&gt;&lt;p&gt;I&amp;#39;m just very happy my sound is working flawlessly. &lt;br /&gt;&lt;/p&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=3070" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=CrwjAaG"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=CrwjAaG" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=tzSMrqg"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=tzSMrqg" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=kEu44FG"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=kEu44FG" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/LosTechies/~4/278405913" height="1" width="1"/&gt;</description><category domain="http://www.lostechies.com/blogs/jason_meridth/archive/tags/Linux/default.aspx">Linux</category><category domain="http://www.lostechies.com/blogs/jason_meridth/archive/tags/Ubuntu/default.aspx">Ubuntu</category><feedburner:origLink>http://www.lostechies.com/blogs/jason_meridth/archive/2008/04/26/ubutnu-8-04-hardy-heron-after-upgrade-i-have-complete-sound.aspx</feedburner:origLink></item><item><title>Raising the bar</title><link>http://feeds.feedburner.com/~r/LosTechies/~3/278070488/raising-the-bar.aspx</link><pubDate>Sat, 26 Apr 2008 04:34:44 GMT</pubDate><guid isPermaLink="false">ded273ab-9e87-4979-8222-e4e2e46f1b46:3064</guid><dc:creator>bogardj</dc:creator><slash:comments>2</slash:comments><description>&lt;p&gt;&lt;a href="http://www.lostechies.com/blogs/chad_myers/archive/2008/04/23/two-random-thoughts.aspx"&gt;Continuous improvement&lt;/a&gt; is absolutely essential for any serious software developer.&amp;nbsp; Personally, my drive for constant improvement is not so much the next shiny developer toy (though this happens occasionally), but the idea that there is always some way to deliver value to the customer better and cheaper than what I&amp;#39;m doing now.&lt;/p&gt; &lt;p&gt;Driving personal improvement can be a great example to teammates, but for an entire team (or even teams you don&amp;#39;t work with) to improve, you&amp;#39;ll have to expand your horizons.&amp;nbsp; You&amp;#39;ll need to &lt;a href="http://www.codinghorror.com/blog/archives/000854.html"&gt;maximize the value of your keystrokes&lt;/a&gt;, so to speak.&lt;/p&gt; &lt;p&gt;So you sent an email to your teammates about a possible design improvement.&amp;nbsp; Why not blog about it?&amp;nbsp; So you read a new design or patterns book.&amp;nbsp; Why not give your team a presentation and summary?&amp;nbsp; So you refactored some gnarly code.&amp;nbsp; Why not tell the whole team on your improvements?&lt;/p&gt; &lt;p&gt;Keeping self-improvement to your self might not improve your situation as much as you might like.&amp;nbsp; Unless you&amp;#39;re flying solo, other team members will eventually write code that you will despise.&lt;/p&gt; &lt;h3&gt;&lt;/h3&gt; &lt;h3&gt;Driving local improvement&lt;/h3&gt; &lt;p&gt;Instead of deriding poor design, look towards collective improvement and raise your team&amp;#39;s collective bar.&amp;nbsp; Some different bar-raising techniques include:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Creating a team blog&lt;/li&gt; &lt;li&gt;Starting a book club&lt;/li&gt; &lt;li&gt;Hold brown-bag sessions on patterns, practices, refactorings, and others&lt;/li&gt; &lt;li&gt;Pairing and mentoring sessions with junior developers&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;If you&amp;#39;re only improving yourself, &lt;em&gt;your&lt;/em&gt; code will improve, but it won&amp;#39;t impact the team&amp;#39;s codebase as much as &lt;em&gt;everyone&amp;#39;s&lt;/em&gt; code improving.&amp;nbsp; And it&amp;#39;s not just code either.&amp;nbsp; Communication and process improvements will provide at least, if not more value than coding improvements.&amp;nbsp; Body language can tell you if you&amp;#39;re on the right track when running ideas past your domain experts.&amp;nbsp; If you can&amp;#39;t recognize these signals, you&amp;#39;re creating quite a bit of waste.&amp;nbsp; Driving awareness and action of improvement areas are part of what&amp;#39;s required of you to earn your pay.&lt;/p&gt; &lt;h3&gt;Driving community improvement&lt;/h3&gt; &lt;p&gt;Something I&amp;#39;ve made a personal commitment to do is to try and drive some community improvement.&amp;nbsp; I&amp;#39;m already at a &lt;a href="http://headspringsystems.com/"&gt;great place&lt;/a&gt; that expects XP practices, and we can always expand and improve, but every shop I run into has serious dysfunctions.&amp;nbsp; I&amp;#39;d like to try to raise the bar through:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;This blog and the literally tens of people that read it&lt;/li&gt; &lt;li&gt;Screencasts on &lt;strike&gt;shiny new objects&lt;/strike&gt; values, principles and practices I think are important&lt;/li&gt; &lt;li&gt;&lt;a href="http://groups.google.com/group/austin-ddd-book-club/"&gt;Local book clubs&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Skype/VNC sessions with interested folks (probably for a &lt;a href="http://www.stellaartois.com/"&gt;small fee&lt;/a&gt;)&lt;/li&gt; &lt;li&gt;&lt;a href="http://austincodecamp.com/"&gt;Code camp sessions&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;I have my selfish reasons for these things, as everyone else&amp;#39;s code is terrible.&amp;nbsp; Except mine, of course.&amp;nbsp; You can hear angels singing when I apply ReSharper shortcuts.&lt;/p&gt; &lt;p&gt;There are about an order of magnitude more bad developers than good ones, and another order of magnitude from good to great.&amp;nbsp; The onus is on the upper-level practitioners to mentor others and raise the collective bar of our community.&lt;/p&gt;&lt;img src="http://www.lostechies.com/aggbug.aspx?PostID=3064" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=crxv84G"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=crxv84G" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=JTvLu4g"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=JTvLu4g" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/LosTechies?a=20eFoGG"&gt;&lt;img src="http://feeds.feedburner.com/~f/LosTechies?i=20eFoGG" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/LosTechies/~4/278070488" height="1" width="1"/&gt;</description><category domain="http://www.lostechies.com/blogs/jimmy_bogard/archive/tags/Misc/default.aspx">Misc</category><feedburner:origLink>http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/04/25/raising-the-bar.aspx</feedburner:origLink></item></channel></rss>
