<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:podcast="https://podcastindex.org/namespace/1.0">
  <channel>
    <atom:link href="https://feeds.simplecast.com/W8bGHhCA" rel="self" title="MP3 Audio" type="application/atom+xml"/>
    <atom:link href="https://simplecast.superfeedr.com/" rel="hub" xmlns="http://www.w3.org/2005/Atom"/>
    <generator>https://simplecast.com</generator>
    <title>Weekly Dev Tips</title>
    <description>Weekly Dev Tips offers a variety of technical and career tips for software developers. Each tip is quick and to the point, describing a problem and one or more ways to solve that problem. I don&apos;t expect every tip to be useful to every developer, but I hope you&apos;ll find enough of them valuable to make listening worth your time.

Hosted by experienced software architect, trainer, and entrepreneur Steve Smith, also known online as @ardalis. If you find these useful, you may also want to get a free software development tip delivered to your inbox every Wednesday from ardalis.com/tips.</description>
    <language>en</language>
    <pubDate>Mon, 22 Mar 2021 23:58:27 +0000</pubDate>
    <lastBuildDate>Thu, 8 Jun 2023 17:43:50 +0000</lastBuildDate>
    <image>
      <link>http://weeklydevtips.com</link>
      <title>Weekly Dev Tips</title>
      <url>https://image.simplecastcdn.com/images/b7b4f0aa-b789-468a-9dec-08578bbb3673/e90d7180-3c10-46fe-b4f1-b8e5794dd672/3000x3000/1502307817artwork.jpg?aid=rss_feed</url>
    </image>
    <link>http://weeklydevtips.com</link>
    <itunes:type>episodic</itunes:type>
    <itunes:summary>Weekly Dev Tips offers a variety of technical and career tips for software developers. Each tip is quick and to the point, describing a problem and one or more ways to solve that problem. I don&apos;t expect every tip to be useful to every developer, but I hope you&apos;ll find enough of them valuable to make listening worth your time.

Hosted by experienced software architect, trainer, and entrepreneur Steve Smith, also known online as @ardalis. If you find these useful, you may also want to get a free software development tip delivered to your inbox every Wednesday from ardalis.com/tips.</itunes:summary>
    <itunes:author>Steve Smith (@ardalis)</itunes:author>
    <itunes:explicit>no</itunes:explicit>
    <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0aa-b789-468a-9dec-08578bbb3673/e90d7180-3c10-46fe-b4f1-b8e5794dd672/3000x3000/1502307817artwork.jpg?aid=rss_feed"/>
    <itunes:new-feed-url>https://feeds.simplecast.com/W8bGHhCA</itunes:new-feed-url>
    <itunes:keywords>technology, web, software, programming, tips, advice, craftsmanship</itunes:keywords>
    <itunes:owner>
      <itunes:name>Steve Smith (@ardalis)</itunes:name>
      <itunes:email>steve@ardalis.com</itunes:email>
    </itunes:owner>
    <itunes:category text="Technology"/>
    <itunes:category text="Business">
      <itunes:category text="Careers"/>
    </itunes:category>
    <item>
      <guid isPermaLink="false">4db3039c-c137-4b9a-8c78-745216344c29</guid>
      <title>Blogging with guest Andrew Lock</title>
      <description><![CDATA[<h2>Show Resources and Links</h2><ul><li><a href="https://andrewlock.net/">Andrew Lock's blog</a></li><li><a href="https://www.manning.com/books/asp-net-core-in-action-second-edition">ASP.NET Core in Action</a> by Manning</li><li><a href="https://twitter.com/andrewlocknet">Follow Andrew on Twitter</a></li><li><a href="https://www.hanselman.com/blog/YourWordsAreWasted.aspx">Your Words are Wasted</a> by Scott Hanselman</li><li><a href="https://devbetter.com">devBetter</a></li><li><a href="https://ardalis.com/blog">Ardalis Blog</a></li></ul><p>That's it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 22 Mar 2021 23:58:27 +0000</pubDate>
      <author>steve@ardalis.com (Andrew Lock, Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h2>Show Resources and Links</h2><ul><li><a href="https://andrewlock.net/">Andrew Lock's blog</a></li><li><a href="https://www.manning.com/books/asp-net-core-in-action-second-edition">ASP.NET Core in Action</a> by Manning</li><li><a href="https://twitter.com/andrewlocknet">Follow Andrew on Twitter</a></li><li><a href="https://www.hanselman.com/blog/YourWordsAreWasted.aspx">Your Words are Wasted</a> by Scott Hanselman</li><li><a href="https://devbetter.com">devBetter</a></li><li><a href="https://ardalis.com/blog">Ardalis Blog</a></li></ul><p>That's it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="8234518" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0aa-b789-468a-9dec-08578bbb3673/episodes/40073047-ebef-43b3-8f9b-09ec7497c309/audio/380b293b-b6db-4614-8afa-fc7f63da396f/default_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Blogging with guest Andrew Lock</itunes:title>
      <itunes:author>Andrew Lock, Steve Smith (@ardalis)</itunes:author>
      <itunes:duration>00:08:34</itunes:duration>
      <itunes:summary>This is episode 75 on blogging with guest Andrew Lock.</itunes:summary>
      <itunes:subtitle>This is episode 75 on blogging with guest Andrew Lock.</itunes:subtitle>
      <itunes:keywords>developer, blogging</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>75</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">bec76b56-0e69-4cf5-ac4d-91d07934082a</guid>
      <title>.Net Foundation with guest Claire Novotny</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I'm your host Steve Smith, aka Ardalis.</p><p>This is episode 74 with guest Claire Novotny.</p><h1>On the Dot Net Foundation</h1><p>This week's tip is brought to you by devBetter.com.</p><h2>Sponsor - devBetter Group Career Coaching for Developers</h2><p>What is devBetter? It's a private group coaching community geared toward accelerating developer careers. We meet weekly for live Q&A sessions and have an active Discord-based discussion the rest of the week. Topics range from coding skills to interviewing and personal branding. Check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page.</p><p>This week my guest is Claire Novotny, Executive Director of the .NET Foundation. We're going to spend a few minutes talking about the foundation.</p><h2>Show Resources and Links</h2><ul><li><a href="https://dotnetfoundation.org/">.NET Foundation</a></li><li><a href="https://devbetter.com">devBetter</a></li><li><a href="https://ardalis.com/blog">Ardalis Blog</a></li></ul><p>That's it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a>. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 8 Jun 2020 16:13:05 +0000</pubDate>
      <author>steve@ardalis.com (Claire Novotny, Steve Smith | @ardalis | Weekly Dev Tips)</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I'm your host Steve Smith, aka Ardalis.</p><p>This is episode 74 with guest Claire Novotny.</p><h1>On the Dot Net Foundation</h1><p>This week's tip is brought to you by devBetter.com.</p><h2>Sponsor - devBetter Group Career Coaching for Developers</h2><p>What is devBetter? It's a private group coaching community geared toward accelerating developer careers. We meet weekly for live Q&A sessions and have an active Discord-based discussion the rest of the week. Topics range from coding skills to interviewing and personal branding. Check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page.</p><p>This week my guest is Claire Novotny, Executive Director of the .NET Foundation. We're going to spend a few minutes talking about the foundation.</p><h2>Show Resources and Links</h2><ul><li><a href="https://dotnetfoundation.org/">.NET Foundation</a></li><li><a href="https://devbetter.com">devBetter</a></li><li><a href="https://ardalis.com/blog">Ardalis Blog</a></li></ul><p>That's it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a>. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="15973064" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/0838b400-33b0-4047-a026-240ce827d336/074-dotnet-foundation-with-guest-claire-novotny_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>.Net Foundation with guest Claire Novotny</itunes:title>
      <itunes:author>Claire Novotny, Steve Smith | @ardalis | Weekly Dev Tips</itunes:author>
      <itunes:duration>00:16:38</itunes:duration>
      <itunes:summary>This is episode 74 with guest Claire Novotny on the .Net Foundation.</itunes:summary>
      <itunes:subtitle>This is episode 74 with guest Claire Novotny on the .Net Foundation.</itunes:subtitle>
      <itunes:keywords>.net core, .net, .net foundation</itunes:keywords>
      <itunes:explicit>yes</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>74</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">1d7189d7-5182-4004-bf40-506a55fa14ac</guid>
      <title>Code Comments with Guest Claudio Lassala</title>
      <description><![CDATA[<h1>On Code Comments</h1><p>This week's tip is brought to you by devBetter.com.</p><h2>Sponsor - devBetter Group Career Coaching for Developers</h2><p>What is devBetter? It's a private group coaching community geared toward accelerating developer careers. We meet weekly for live Q&A sessions and have an active Discord-based discussion the rest of the week. Topics range from coding skills to interviewing and personal branding. Check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page.</p><h1>On Code Comments</h1><p>Claudio and I discuss code comments and how Claudio's thoughts on them have evolved over the last 15 years or so.</p><h2>Show Resources and Links</h2><ul><li><a href="https://lassala.net/">Claudio's blog</a></li><li><a href="https://twitter.com/ClaudioLassala">Claudio on twitter</a></li><li><a href="https://lassala.net/2020/05/07/about-commenting-code/">Notes and Links from this Episode</a></li><li><a href="https://devbetter.com">devBetter</a></li><li><a href="https://ardalis.com/blog">Ardalis Blog</a></li></ul><p>That's it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a>. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 11 May 2020 06:30:03 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith | @ardalis |Software Developer, Claudio Lassala)</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h1>On Code Comments</h1><p>This week's tip is brought to you by devBetter.com.</p><h2>Sponsor - devBetter Group Career Coaching for Developers</h2><p>What is devBetter? It's a private group coaching community geared toward accelerating developer careers. We meet weekly for live Q&A sessions and have an active Discord-based discussion the rest of the week. Topics range from coding skills to interviewing and personal branding. Check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page.</p><h1>On Code Comments</h1><p>Claudio and I discuss code comments and how Claudio's thoughts on them have evolved over the last 15 years or so.</p><h2>Show Resources and Links</h2><ul><li><a href="https://lassala.net/">Claudio's blog</a></li><li><a href="https://twitter.com/ClaudioLassala">Claudio on twitter</a></li><li><a href="https://lassala.net/2020/05/07/about-commenting-code/">Notes and Links from this Episode</a></li><li><a href="https://devbetter.com">devBetter</a></li><li><a href="https://ardalis.com/blog">Ardalis Blog</a></li></ul><p>That's it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a>. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="23227355" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/38c1f3f2-9b98-4ac0-89a8-8be4a03c0ef9/73-code-comments-with-guest-claudio-lassala_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Code Comments with Guest Claudio Lassala</itunes:title>
      <itunes:author>Steve Smith | @ardalis |Software Developer, Claudio Lassala</itunes:author>
      <itunes:duration>00:23:59</itunes:duration>
      <itunes:summary>Hi and welcome back to Weekly Dev Tips. This is episode 73 with guest Claudio Lassala.
</itunes:summary>
      <itunes:subtitle>Hi and welcome back to Weekly Dev Tips. This is episode 73 with guest Claudio Lassala.
</itunes:subtitle>
      <itunes:keywords>code comments, code</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>73</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">3ca0f8ce-3642-4739-a717-8d183c04c6c3</guid>
      <title>Using the New GitHub CLI with guest John Papa</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I'm your host Steve Smith, aka Ardalis.</p><p>This is episode 72 with guest John Papa.</p><h1>GitHub's New Command Line Interface</h1><p>This week's tip is brought to you by devBetter.com.</p><h2>Sponsor - devBetter Group Career Coaching for Developers</h2><p>What is devBetter? It's a private group coaching community geared toward accelerating developer careers. We meet weekly for live Q&A sessions and have an active Discord-based discussion the rest of the week. Topics range from coding skills to interviewing and personal branding. Check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page.</p><h1>GitHub's New Command Line Interface</h1><p>John and I discuss GitHub's new CLI.</p><h2>Show Resources and Links</h2><ul><li><a href="https://cli.github.com/manual/index">GitHub CLI Docs</a></li><li><a href="https://johnpapa.net/try-githubs-new-cli-gh/">Try gh, GitHub's new CLI</a></li><li><a href="https://docs.microsoft.com/en-us/learn/modules/shift-nodejs-express-apis-serverless/">Moving Express to Azure Functions (Azure Learn Module)</a></li><li><a href="https://devbetter.com">devBetter</a></li><li><a href="https://ardalis.com/blog">Ardalis Blog</a></li></ul><p>That's it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a>. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 20 Apr 2020 06:30:23 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I'm your host Steve Smith, aka Ardalis.</p><p>This is episode 72 with guest John Papa.</p><h1>GitHub's New Command Line Interface</h1><p>This week's tip is brought to you by devBetter.com.</p><h2>Sponsor - devBetter Group Career Coaching for Developers</h2><p>What is devBetter? It's a private group coaching community geared toward accelerating developer careers. We meet weekly for live Q&A sessions and have an active Discord-based discussion the rest of the week. Topics range from coding skills to interviewing and personal branding. Check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page.</p><h1>GitHub's New Command Line Interface</h1><p>John and I discuss GitHub's new CLI.</p><h2>Show Resources and Links</h2><ul><li><a href="https://cli.github.com/manual/index">GitHub CLI Docs</a></li><li><a href="https://johnpapa.net/try-githubs-new-cli-gh/">Try gh, GitHub's new CLI</a></li><li><a href="https://docs.microsoft.com/en-us/learn/modules/shift-nodejs-express-apis-serverless/">Moving Express to Azure Functions (Azure Learn Module)</a></li><li><a href="https://devbetter.com">devBetter</a></li><li><a href="https://ardalis.com/blog">Ardalis Blog</a></li></ul><p>That's it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a>. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="16362406" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/a39aa922-e727-4f89-bafd-f1379cb698f4/072-using-the-new-github-cli-with-guest-john-papa_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Using the New GitHub CLI with guest John Papa</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:duration>00:16:50</itunes:duration>
      <itunes:summary>This is episode 72 with guest John Papa on GitHub&apos;s New Command Line Interface.</itunes:summary>
      <itunes:subtitle>This is episode 72 with guest John Papa on GitHub&apos;s New Command Line Interface.</itunes:subtitle>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>72</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">ce10f631-3975-431c-918e-9e1959046f49</guid>
      <title>Adapter Design Pattern</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I'm your host Steve Smith, aka Ardalis.</p>
<p>This is episode 71. This is the first tip I'm recording since going into quarantine lockdown due to the Coronavirus - the last few months were all recorded well ahead of their publication. I hope you're all staying safe and that you're finding these tips helpful. And perhaps you're listening to this from some time in the future, in which case hopefully everything turned out great!</p>
<h1>Adapter Design Pattern</h1>
<p>This week's tip is brought to you by devBetter.com.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>What is devBetter? It's a private group coaching community geared toward accelerating developer careers. We meet weekly for live Q&amp;A sessions and have an active Discord-based discussion the rest of the week. Topics range from coding skills to interviewing and personal branding. Check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page.</p>
<h1>Adapter Design Pattern</h1>
<p>This week we're going to talk briefly about the adapter design pattern. This is one of the most common and useful design patterns, so it's a good idea for most developers to be familiar with it. It's described in the Gang of Four's Design Patterns book, linked in the show notes. You can also learn more about it in the great book Head First Design Patterns or my Pluralsight course, also both linked in the show notes.</p>
<p>This pattern is designed to solve the problem of incompatible interfaces. Typically this is an issue when you can't or don't want to change a client's expectations to match a service provider's interface. Or vice versa. For instance, let's say you have a large application and throughout it you've made calls to log diagnostic output using a particular named method with certain arguments. Now, you discover that you need to use a different logging solution, but unfortunately its method has a different name and its arguments are in a different order. Do you need to touch everywhere in your application to make the change?</p>
<p>Not necessarily. Instead, you can introduce an adapter. The adapter has the same interface as your existing approach, but translates from that interface to the new one behind the scenes. Your code keeps using the method signature it's used to, but you're able to point it at a different end result. Because they usually wrap the incompatible class, adapters are also often referred to as wrappers. With a w - not like rap artists.</p>
<p>It's against the rules to talk about the adapter design pattern without comparing it to electrical plug adapters, so here goes. If you've ever traveled and needed to use an adapter to convert your US plug appliance to fit another country's outlet, or vice versa, you've used an adapter. They're also common with electronics, for instance to convert a newer iPhone lightning port to a 3.5mm audio port on devices that lack a headphone jack. Adapters let you evolve the behavior of both the client and the service provider while still allowing incompatible combinations to work together. In this way, they decouple clients from service providers.</p>
<p>Although adapters  are structurally very similar to decorators and proxies, their intent differs. You can learn more about all of these patterns and see code examples on Pluralsight, or in the books I mentioned earlier.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://www.pluralsight.com/courses/c-sharp-design-patterns-adapter">Adapter Design Pattern in C#</a> on Pluralsight</li>
<li><a href="https://www.pluralsight.com/courses/domain-driven-design-fundamentals">Domain-Driven Design Fundamentals</a> on Pluralsight</li>
<li><a href="https://amzn.to/2xwlbEI">Design Patterns</a> on Amazon</li>
<li><a href="https://amzn.to/2XC4EJX">Head First Design Patterns</a> on Amazon</li>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://ardalis.com/blog">Ardalis Blog</a></li>
</ul>
<p>That's it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Wed, 15 Apr 2020 17:21:40 +0000</pubDate>
      <author>steve@ardalis.com (steve smith)</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I'm your host Steve Smith, aka Ardalis.</p>
<p>This is episode 71. This is the first tip I'm recording since going into quarantine lockdown due to the Coronavirus - the last few months were all recorded well ahead of their publication. I hope you're all staying safe and that you're finding these tips helpful. And perhaps you're listening to this from some time in the future, in which case hopefully everything turned out great!</p>
<h1>Adapter Design Pattern</h1>
<p>This week's tip is brought to you by devBetter.com.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>What is devBetter? It's a private group coaching community geared toward accelerating developer careers. We meet weekly for live Q&amp;A sessions and have an active Discord-based discussion the rest of the week. Topics range from coding skills to interviewing and personal branding. Check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page.</p>
<h1>Adapter Design Pattern</h1>
<p>This week we're going to talk briefly about the adapter design pattern. This is one of the most common and useful design patterns, so it's a good idea for most developers to be familiar with it. It's described in the Gang of Four's Design Patterns book, linked in the show notes. You can also learn more about it in the great book Head First Design Patterns or my Pluralsight course, also both linked in the show notes.</p>
<p>This pattern is designed to solve the problem of incompatible interfaces. Typically this is an issue when you can't or don't want to change a client's expectations to match a service provider's interface. Or vice versa. For instance, let's say you have a large application and throughout it you've made calls to log diagnostic output using a particular named method with certain arguments. Now, you discover that you need to use a different logging solution, but unfortunately its method has a different name and its arguments are in a different order. Do you need to touch everywhere in your application to make the change?</p>
<p>Not necessarily. Instead, you can introduce an adapter. The adapter has the same interface as your existing approach, but translates from that interface to the new one behind the scenes. Your code keeps using the method signature it's used to, but you're able to point it at a different end result. Because they usually wrap the incompatible class, adapters are also often referred to as wrappers. With a w - not like rap artists.</p>
<p>It's against the rules to talk about the adapter design pattern without comparing it to electrical plug adapters, so here goes. If you've ever traveled and needed to use an adapter to convert your US plug appliance to fit another country's outlet, or vice versa, you've used an adapter. They're also common with electronics, for instance to convert a newer iPhone lightning port to a 3.5mm audio port on devices that lack a headphone jack. Adapters let you evolve the behavior of both the client and the service provider while still allowing incompatible combinations to work together. In this way, they decouple clients from service providers.</p>
<p>Although adapters  are structurally very similar to decorators and proxies, their intent differs. You can learn more about all of these patterns and see code examples on Pluralsight, or in the books I mentioned earlier.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://www.pluralsight.com/courses/c-sharp-design-patterns-adapter">Adapter Design Pattern in C#</a> on Pluralsight</li>
<li><a href="https://www.pluralsight.com/courses/domain-driven-design-fundamentals">Domain-Driven Design Fundamentals</a> on Pluralsight</li>
<li><a href="https://amzn.to/2xwlbEI">Design Patterns</a> on Amazon</li>
<li><a href="https://amzn.to/2XC4EJX">Head First Design Patterns</a> on Amazon</li>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://ardalis.com/blog">Ardalis Blog</a></li>
</ul>
<p>That's it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="2242619" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/b5b4a6c7-c4c9-4667-b326-6ccfe1768e43/071-adapter-design-pattern_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Adapter Design Pattern</itunes:title>
      <itunes:author>steve smith</itunes:author>
      <itunes:duration>00:03:52</itunes:duration>
      <itunes:summary>A brief overview of the adapter design pattern.</itunes:summary>
      <itunes:subtitle>A brief overview of the adapter design pattern.</itunes:subtitle>
      <itunes:keywords>software development, ardalis, design pattern, design patterns, clean code, programming, oop, adapter, wrapper</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>71</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">4a600a20-aa05-4770-8530-24a9ebf847dd</guid>
      <title>Defense in Depth with guest Matt Eland</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p><p>This is episode 70 on Defense in Depth with guest Matt Eland.</p><h1>Defense in Depth with guest Matt Eland</h1><p>This week's tip is brought to you by devBetter.com.</p><h2>Sponsor - devBetter Group Career Coaching for Developers</h2><p>What is devBetter? It's a private group coaching community geared toward accelerating developer careers. We meet weekly for live Q&A sessions and have an active Discord-based discussion the rest of the week. Topics range from coding skills to interviewing and personal branding. Check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page.</p><h1>Defense in Depth with guest Matt Eland</h1><p>This week's tip is brought to you by guest Matt Eland. Matt is a teacher, writer, and .NET foundation member who focuses on software quality and improving code. Welcome, Matt!</p><h2>Show Resources and Links</h2><ul><li><a href="https://twitter.com/integerman">Matt on Twitter</a></li><li><a href="https://devbetter.com">devBetter</a></li><li><a href="https://ardalis.com/blog">Ardalis Blog</a></li><li><a href="">Pluralsight Courses</a></li></ul><p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 6 Apr 2020 06:30:15 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith | @ardalis | Software Developer, Matt Eland)</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p><p>This is episode 70 on Defense in Depth with guest Matt Eland.</p><h1>Defense in Depth with guest Matt Eland</h1><p>This week's tip is brought to you by devBetter.com.</p><h2>Sponsor - devBetter Group Career Coaching for Developers</h2><p>What is devBetter? It's a private group coaching community geared toward accelerating developer careers. We meet weekly for live Q&A sessions and have an active Discord-based discussion the rest of the week. Topics range from coding skills to interviewing and personal branding. Check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page.</p><h1>Defense in Depth with guest Matt Eland</h1><p>This week's tip is brought to you by guest Matt Eland. Matt is a teacher, writer, and .NET foundation member who focuses on software quality and improving code. Welcome, Matt!</p><h2>Show Resources and Links</h2><ul><li><a href="https://twitter.com/integerman">Matt on Twitter</a></li><li><a href="https://devbetter.com">devBetter</a></li><li><a href="https://ardalis.com/blog">Ardalis Blog</a></li><li><a href="">Pluralsight Courses</a></li></ul><p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="10988063" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/db331857-04b3-45cb-a29b-635bd879c7c9/070-defense-in-depth-with-guest-matt-eland_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Defense in Depth with guest Matt Eland</itunes:title>
      <itunes:author>Steve Smith | @ardalis | Software Developer, Matt Eland</itunes:author>
      <itunes:duration>00:11:17</itunes:duration>
      <itunes:summary>This is episode 70 on Defense in Depth with guest Matt Eland.</itunes:summary>
      <itunes:subtitle>This is episode 70 on Defense in Depth with guest Matt Eland.</itunes:subtitle>
      <itunes:keywords>matt eland, security</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>70</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">68e59722-53f3-4bc9-bffd-b4746bd29916</guid>
      <title>Setting Up New Projects with guest Heather Downing</title>
      <description><![CDATA[
]]></description>
      <pubDate>Mon, 30 Mar 2020 06:30:06 +0000</pubDate>
      <author>steve@ardalis.com (Heather Downing, Steve Smith | @ardalis | Software Developer)</author>
      <link>http://weeklydevtips.com</link>
      <enclosure length="8392015" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/50631404-c393-46fe-8a52-11c21f141b27/069-setting-up-new-projects-with-guest-heather-downing_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Setting Up New Projects with guest Heather Downing</itunes:title>
      <itunes:author>Heather Downing, Steve Smith | @ardalis | Software Developer</itunes:author>
      <itunes:duration>00:08:39</itunes:duration>
      <itunes:summary></itunes:summary>
      <itunes:subtitle></itunes:subtitle>
      <itunes:keywords>getting started, new project, git, project management</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>69</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">10e2f3a3-dda4-4efc-9a7f-28477efd2765</guid>
      <title>Respawn with guest Jimmy Bogard</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I'm your host Steve Smith, aka Ardalis.</p><p> </p><p>This is episode 68 with guest Jimmy Bogard.</p><p> </p><p>This week's tip is brought to you by devBetter.com.</p><p> </p><p>## Sponsor - devBetter Group Career Coaching for Developers</p><p> </p><p>What is devBetter? It's a private group coaching community geared toward accelerating developer careers. We meet weekly for live Q&A sessions and have an active Discord-based discussion the rest of the week. Topics range from coding skills to interviewing and personal branding. Check out [devBetter.com](https://devbetter.com/) and read the testimonials at the bottom of the page.</p><p> </p><p># Respawn with guest Jimmy Bogard</p><p> </p><p>This week's guest is Jimmy Bogard, author of popular OSS projects AutoMapper and MediatR. And less popular project Respawn.</p><p> </p><p>## Show Resources and Links</p><p> </p><p>- [Jimmy on Twitter](https://twitter.com/jbogard)</p><p>- [devBetter](https://devbetter.com)</p><p>- [Ardalis Blog](https://ardalis.com/blog)</p><p>- [Pluralsight Courses](https://www.pluralsight.com/authors/steve-smith)</p><p> </p><p>That's it for this week. If you want to hear more from me, go to [ardalis.com/tips](https://ardalis.com/tips) to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on [twitch.tv/ardalis](https://twitch.tv/ardalis) most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p><p> </p>
]]></description>
      <pubDate>Mon, 23 Mar 2020 06:30:13 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith | @ardalis | Software Developer, Jimmy Bogard)</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I'm your host Steve Smith, aka Ardalis.</p><p> </p><p>This is episode 68 with guest Jimmy Bogard.</p><p> </p><p>This week's tip is brought to you by devBetter.com.</p><p> </p><p>## Sponsor - devBetter Group Career Coaching for Developers</p><p> </p><p>What is devBetter? It's a private group coaching community geared toward accelerating developer careers. We meet weekly for live Q&A sessions and have an active Discord-based discussion the rest of the week. Topics range from coding skills to interviewing and personal branding. Check out [devBetter.com](https://devbetter.com/) and read the testimonials at the bottom of the page.</p><p> </p><p># Respawn with guest Jimmy Bogard</p><p> </p><p>This week's guest is Jimmy Bogard, author of popular OSS projects AutoMapper and MediatR. And less popular project Respawn.</p><p> </p><p>## Show Resources and Links</p><p> </p><p>- [Jimmy on Twitter](https://twitter.com/jbogard)</p><p>- [devBetter](https://devbetter.com)</p><p>- [Ardalis Blog](https://ardalis.com/blog)</p><p>- [Pluralsight Courses](https://www.pluralsight.com/authors/steve-smith)</p><p> </p><p>That's it for this week. If you want to hear more from me, go to [ardalis.com/tips](https://ardalis.com/tips) to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on [twitch.tv/ardalis](https://twitch.tv/ardalis) most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p><p> </p>
]]></content:encoded>
      <enclosure length="4508660" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/f6ae63ca-fc95-404f-aa94-a4a9596923d4/jimmy-bogard-respawn_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Respawn with guest Jimmy Bogard</itunes:title>
      <itunes:author>Steve Smith | @ardalis | Software Developer, Jimmy Bogard</itunes:author>
      <itunes:duration>00:04:32</itunes:duration>
      <itunes:summary>This is episode 68 with guest Jimmy Bogard.</itunes:summary>
      <itunes:subtitle>This is episode 68 with guest Jimmy Bogard.</itunes:subtitle>
      <itunes:keywords>respawn, ndc</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>68</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">1e69ee98-c750-4bc8-bcad-71859a998ba1</guid>
      <title>Abstractions with guest Chris Klug</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I'm your host Steve Smith, aka Ardalis.</p><p>This is episode 67 with guest Chris Klug.</p><p>This week's tip is brought to you by devBetter.com.</p><h2>Sponsor - devBetter Group Career Coaching for Developers</h2><p>What is devBetter? It's a private group coaching community geared toward accelerating developer careers. We meet weekly for live Q&A sessions and have an active Discord-based discussion the rest of the week. Topics range from coding skills to interviewing and personal branding. Check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page.</p><h1>Abstractions with guest Chris Klug</h1><p>This week's guest is Chris Klug. Chris is a Swedish .NET developer and Microsoft MVP whom we met up with at NDC London to record this episode on using, and not overusing, abstractions.</p><h2>Show Resources and Links</h2><ul><li><a href="https://twitter.com/ZeroKoll">Chris on Twitter</a></li><li><a href="https://devbetter.com">devBetter</a></li><li><a href="https://ardalis.com/blog">Ardalis Blog</a></li><li><a href="https://www.pluralsight.com/authors/steve-smith">Pluralsight Courses</a></li></ul><p>That's it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 16 Mar 2020 06:30:09 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I'm your host Steve Smith, aka Ardalis.</p><p>This is episode 67 with guest Chris Klug.</p><p>This week's tip is brought to you by devBetter.com.</p><h2>Sponsor - devBetter Group Career Coaching for Developers</h2><p>What is devBetter? It's a private group coaching community geared toward accelerating developer careers. We meet weekly for live Q&A sessions and have an active Discord-based discussion the rest of the week. Topics range from coding skills to interviewing and personal branding. Check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page.</p><h1>Abstractions with guest Chris Klug</h1><p>This week's guest is Chris Klug. Chris is a Swedish .NET developer and Microsoft MVP whom we met up with at NDC London to record this episode on using, and not overusing, abstractions.</p><h2>Show Resources and Links</h2><ul><li><a href="https://twitter.com/ZeroKoll">Chris on Twitter</a></li><li><a href="https://devbetter.com">devBetter</a></li><li><a href="https://ardalis.com/blog">Ardalis Blog</a></li><li><a href="https://www.pluralsight.com/authors/steve-smith">Pluralsight Courses</a></li></ul><p>That's it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="13380962" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/da928500-e806-491b-9289-4f90b98c5204/067-abstractions-with-guest-chris-klug_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Abstractions with guest Chris Klug</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:duration>00:13:56</itunes:duration>
      <itunes:summary>This is episode 67 with guest Chris Klug.</itunes:summary>
      <itunes:subtitle>This is episode 67 with guest Chris Klug.</itunes:subtitle>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>67</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">aa6bf116-8ae2-4efc-8110-d0d31436b646</guid>
      <title>Blazor with guest Carl Franklin</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p><p>This is episode 66 with a Blazor tip from Carl Franklin of .NET Rocks fame.</p><p>This week's tip is brought to you by devBetter.com.</p><h2>Sponsor - devBetter Group Career Coaching for Developers</h2><p>What is devBetter? It's a private group coaching community geared toward accelerating developer careers. We meet weekly for live Q&A sessions and have an active Discord-based discussion the rest of the week. Topics range from coding skills to interviewing and personal branding. Check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page.</p><h1>Building a Blazor Object Picker with guest Carl Franklin</h1><p>This week's guest is Carl Franklin, host of <a href="https://dotnetrocks.com">.NET Rocks</a> and Blazor trainer. Carl and I discuss Blazor in general and look at how to create a generic object picker control for Blazor.</p><h2>Show Resources and Links</h2><ul><li><a href="https://twitter.com/carlfranklin">Carl on Twitter</a></li><li><a>Blazor Object Picker</a></li><li><a href="https://devbetter.com">devBetter</a></li><li><a href="https://ardalis.com/blog">Ardalis Blog</a></li><li><a href="https://www.pluralsight.com/authors/steve-smith">Pluralsight Courses</a></li></ul><p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 9 Mar 2020 06:30:04 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis) | Weekly Dev Tips | Software Developer, Carl Franklin)</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p><p>This is episode 66 with a Blazor tip from Carl Franklin of .NET Rocks fame.</p><p>This week's tip is brought to you by devBetter.com.</p><h2>Sponsor - devBetter Group Career Coaching for Developers</h2><p>What is devBetter? It's a private group coaching community geared toward accelerating developer careers. We meet weekly for live Q&A sessions and have an active Discord-based discussion the rest of the week. Topics range from coding skills to interviewing and personal branding. Check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page.</p><h1>Building a Blazor Object Picker with guest Carl Franklin</h1><p>This week's guest is Carl Franklin, host of <a href="https://dotnetrocks.com">.NET Rocks</a> and Blazor trainer. Carl and I discuss Blazor in general and look at how to create a generic object picker control for Blazor.</p><h2>Show Resources and Links</h2><ul><li><a href="https://twitter.com/carlfranklin">Carl on Twitter</a></li><li><a>Blazor Object Picker</a></li><li><a href="https://devbetter.com">devBetter</a></li><li><a href="https://ardalis.com/blog">Ardalis Blog</a></li><li><a href="https://www.pluralsight.com/authors/steve-smith">Pluralsight Courses</a></li></ul><p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="11034679" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/433a66c7-42fc-4e7d-9641-7e75da07df5e/066-carl-franklin-on-blazor_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Blazor with guest Carl Franklin</itunes:title>
      <itunes:author>Steve Smith (@ardalis) | Weekly Dev Tips | Software Developer, Carl Franklin</itunes:author>
      <itunes:duration>00:11:20</itunes:duration>
      <itunes:summary>This is episode 66 with a Blazor tip from Carl Franklin of .NET Rocks fame.</itunes:summary>
      <itunes:subtitle>This is episode 66 with a Blazor tip from Carl Franklin of .NET Rocks fame.</itunes:subtitle>
      <itunes:keywords>developer, ndc, .net framework, carl franklin, blazor, tips</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>66</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">ee1c44bc-0d3b-4442-b35f-7909868a6f4c</guid>
      <title>A/B Testing with Azure with guest Lars Klint</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p><p>This is episode 65 on simple and inexpensive A/B testing with Azure, with guest Lars Klint.</p><p>This week's tip is brought to you by devBetter.com.</p><h2>Sponsor - devBetter Group Career Coaching for Developers</h2><p>What is devBetter? It's a private group coaching community geared toward accelerating developer careers. We meet weekly for live Q&A sessions and have an active Discord-based discussion the rest of the week. Topics range from coding skills to interviewing and personal branding. Check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page.</p><h1>A/B Testing with Azure with guest Lars Klint</h1><p>This week's guest is Lars Klint, a well-known cloud expert, speaker, and trainer who works for training company A Cloud Guru.</p><h2>Show Resources and Links</h2><ul><li><a href="https://twitter.com/larsklint">Lars on Twitter</a></li><li><a href="https://acloud.guru">A Cloud Guru</a></li><li><a href="https://devbetter.com">devBetter</a></li><li><a href="https://ardalis.com/blog">Ardalis Blog</a></li><li><a href="https://www.pluralsight.com/authors/steve-smith">Pluralsight Courses</a></li></ul><p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 2 Mar 2020 07:00:03 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis) | Weekly Dev Tips | Software Developer, Lars Klint)</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p><p>This is episode 65 on simple and inexpensive A/B testing with Azure, with guest Lars Klint.</p><p>This week's tip is brought to you by devBetter.com.</p><h2>Sponsor - devBetter Group Career Coaching for Developers</h2><p>What is devBetter? It's a private group coaching community geared toward accelerating developer careers. We meet weekly for live Q&A sessions and have an active Discord-based discussion the rest of the week. Topics range from coding skills to interviewing and personal branding. Check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page.</p><h1>A/B Testing with Azure with guest Lars Klint</h1><p>This week's guest is Lars Klint, a well-known cloud expert, speaker, and trainer who works for training company A Cloud Guru.</p><h2>Show Resources and Links</h2><ul><li><a href="https://twitter.com/larsklint">Lars on Twitter</a></li><li><a href="https://acloud.guru">A Cloud Guru</a></li><li><a href="https://devbetter.com">devBetter</a></li><li><a href="https://ardalis.com/blog">Ardalis Blog</a></li><li><a href="https://www.pluralsight.com/authors/steve-smith">Pluralsight Courses</a></li></ul><p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="7608706" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/48c5aba7-ad54-4c44-a5a1-c12c71064f17/065-ab-testing-with-azure-with-guest-lars-klint_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>A/B Testing with Azure with guest Lars Klint</itunes:title>
      <itunes:author>Steve Smith (@ardalis) | Weekly Dev Tips | Software Developer, Lars Klint</itunes:author>
      <itunes:duration>00:07:46</itunes:duration>
      <itunes:summary>This is episode 65 on simple and inexpensive A/B testing with Azure, with guest Lars Klint.
</itunes:summary>
      <itunes:subtitle>This is episode 65 on simple and inexpensive A/B testing with Azure, with guest Lars Klint.
</itunes:subtitle>
      <itunes:keywords>app services, a/b tests, azure, services, testing</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>65</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">12eb9dcf-b69e-49ea-a970-7be90756a8d2</guid>
      <title>Richard Campbell on Teams</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p><p>This is episode 64 on team membership with guest Richard Campbell.</p><p>This week's tip is brought to you by devBetter.com.</p><h2>Sponsor - devBetter Group Career Coaching for Developers</h2><p>What is devBetter? It's a private group coaching community geared toward accelerating developer careers. We meet weekly for live Q&A sessions and have an active Discord-based discussion the rest of the week. Topics range from coding skills to interviewing and personal branding. Check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page.</p><h1>Team Membership with Guest Richard Campbell</h1><p>This week's guest is Richard Campbell, known to many .NET developers as co-host of .NET Rocks. He has a tip for us this week on how to participate well within at team.</p><p>Three concepts:</p><ul><li>Leadership</li><li>Authority</li><li>Influence</li></ul><h2>Show Resources and Links</h2><ul><li><a href="https://twitter.com/richcampbell">Richard on Twitter</a></li><li><a href="https://dotnetrocks.com/">.NET Rocks</a></li><li><a href="https://devbetter.com">devBetter</a></li><li><a href="https://ardalis.com/blog">Ardalis Blog</a></li><li><a href="https://www.pluralsight.com/authors/steve-smith">Pluralsight Courses</a></li></ul><p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 24 Feb 2020 07:30:23 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis) | Weekly Dev Tips | Software Developer, Richard Campbell)</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p><p>This is episode 64 on team membership with guest Richard Campbell.</p><p>This week's tip is brought to you by devBetter.com.</p><h2>Sponsor - devBetter Group Career Coaching for Developers</h2><p>What is devBetter? It's a private group coaching community geared toward accelerating developer careers. We meet weekly for live Q&A sessions and have an active Discord-based discussion the rest of the week. Topics range from coding skills to interviewing and personal branding. Check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page.</p><h1>Team Membership with Guest Richard Campbell</h1><p>This week's guest is Richard Campbell, known to many .NET developers as co-host of .NET Rocks. He has a tip for us this week on how to participate well within at team.</p><p>Three concepts:</p><ul><li>Leadership</li><li>Authority</li><li>Influence</li></ul><h2>Show Resources and Links</h2><ul><li><a href="https://twitter.com/richcampbell">Richard on Twitter</a></li><li><a href="https://dotnetrocks.com/">.NET Rocks</a></li><li><a href="https://devbetter.com">devBetter</a></li><li><a href="https://ardalis.com/blog">Ardalis Blog</a></li><li><a href="https://www.pluralsight.com/authors/steve-smith">Pluralsight Courses</a></li></ul><p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="9928539" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/e8ce688e-028b-41aa-82cc-4d8af6f092ea/064-richard-campbell-on-teams_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Richard Campbell on Teams</itunes:title>
      <itunes:author>Steve Smith (@ardalis) | Weekly Dev Tips | Software Developer, Richard Campbell</itunes:author>
      <itunes:duration>00:10:15</itunes:duration>
      <itunes:summary>This week&apos;s guest is Richard Campbell, known to many .NET developers as co-host of .NET Rocks. He has a tip for us this week on how to participate well within at team.
</itunes:summary>
      <itunes:subtitle>This week&apos;s guest is Richard Campbell, known to many .NET developers as co-host of .NET Rocks. He has a tip for us this week on how to participate well within at team.
</itunes:subtitle>
      <itunes:keywords>leadership, .net, participation, communication, influence, .net rocks, team, authority</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>64</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">a1ad67d6-7d71-42d6-97a4-139487db486d</guid>
      <title>Password Managers with guest Troy Hunt</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p><p>This is episode 63 on password managers with guest Troy Hunt.</p><p>This week's tip is brought to you by devBetter.com.</p><h2>Sponsor - devBetter Group Career Coaching for Developers</h2><p>What is devBetter? It's a private group coaching community geared toward accelerating developer careers. We meet weekly for live Q&A sessions and have an active Discord-based discussion the rest of the week. Topics range from coding skills to interviewing and personal branding. Check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page.</p><h1>Password Managers with guest Troy Hunt</h1><p>This week's guest is security expert, trainer, and international speaker Troy Hunt. He has some tips to share about how deal with passwords and other secrects.</p><p>// no transcript</p><h2>Show Resources and Links</h2><ul><li><a href="https://1password.com">1Password</a></li><li><a href="https://keepass.info">Keypass</a></li><li><a href="https://devbetter.com">devBetter</a></li><li><a href="https://ardalis.com/blog">Ardalis Blog</a></li><li><a href="https://www.pluralsight.com/authors/steve-smith">Pluralsight Courses</a></li></ul><p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 17 Feb 2020 07:30:07 +0000</pubDate>
      <author>steve@ardalis.com (Troy Hunt, Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p><p>This is episode 63 on password managers with guest Troy Hunt.</p><p>This week's tip is brought to you by devBetter.com.</p><h2>Sponsor - devBetter Group Career Coaching for Developers</h2><p>What is devBetter? It's a private group coaching community geared toward accelerating developer careers. We meet weekly for live Q&A sessions and have an active Discord-based discussion the rest of the week. Topics range from coding skills to interviewing and personal branding. Check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page.</p><h1>Password Managers with guest Troy Hunt</h1><p>This week's guest is security expert, trainer, and international speaker Troy Hunt. He has some tips to share about how deal with passwords and other secrects.</p><p>// no transcript</p><h2>Show Resources and Links</h2><ul><li><a href="https://1password.com">1Password</a></li><li><a href="https://keepass.info">Keypass</a></li><li><a href="https://devbetter.com">devBetter</a></li><li><a href="https://ardalis.com/blog">Ardalis Blog</a></li><li><a href="https://www.pluralsight.com/authors/steve-smith">Pluralsight Courses</a></li></ul><p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="6547257" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/ba28ce55-640e-4626-b744-91eff2323008/063-troyhunt-passwordmanagers_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Password Managers with guest Troy Hunt</itunes:title>
      <itunes:author>Troy Hunt, Steve Smith (@ardalis)</itunes:author>
      <itunes:duration>00:06:48</itunes:duration>
      <itunes:summary>This is episode 63 on password managers with guest Troy Hunt.
</itunes:summary>
      <itunes:subtitle>This is episode 63 on password managers with guest Troy Hunt.
</itunes:subtitle>
      <itunes:keywords>1password, keepass, password managers, security</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>63</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">7358d178-94f3-488d-b918-629ac0ae5eea</guid>
      <title>Requirements and Change with Guest Juval Löwy</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p><p>This is episode 62 on the nature of mapping requirements to our software design and architecture and how we deal with change.</p><p>This week's tip is brought to you by devBetter.com.</p><h2>Sponsor - devBetter Group Career Coaching for Developers</h2><p>What is devBetter? It's a private group coaching community geared toward accelerating developer careers. We meet weekly for live Q&A sessions and have an active Discord-based discussion the rest of the week. Topics range from coding skills to interviewing and personal branding. Check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page.</p><h1>Requirements and Change with guest Juval Löwy</h1><p>This week's guest is Juval Löwy of IDesign. He has a tip for us this week on how we approach writing software. I'll let him introduce himself and share his tips.</p><p>// no transcript</p><p>Thanks, Juval! I've included a link to Juval's book, Righting Software - that's RIGHTing, in the show notes. Juval was kind enough to send me a copy and what I've read so far makes a lot of sense.</p><h2>Show Resources and Links</h2><ul><li><a href="http://idesign.net/">IDesign</a></li><li><a href="https://amzn.to/2Oz2fut">Righting Software</a> - on Amazon</li><li><a href="https://devbetter.com">devBetter</a></li><li><a href="https://ardalis.com/blog">Ardalis Blog</a></li><li><a href="https://www.pluralsight.com/authors/steve-smith">Pluralsight Courses</a></li></ul><p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 10 Feb 2020 07:00:23 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis), Juval Löwy)</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p><p>This is episode 62 on the nature of mapping requirements to our software design and architecture and how we deal with change.</p><p>This week's tip is brought to you by devBetter.com.</p><h2>Sponsor - devBetter Group Career Coaching for Developers</h2><p>What is devBetter? It's a private group coaching community geared toward accelerating developer careers. We meet weekly for live Q&A sessions and have an active Discord-based discussion the rest of the week. Topics range from coding skills to interviewing and personal branding. Check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page.</p><h1>Requirements and Change with guest Juval Löwy</h1><p>This week's guest is Juval Löwy of IDesign. He has a tip for us this week on how we approach writing software. I'll let him introduce himself and share his tips.</p><p>// no transcript</p><p>Thanks, Juval! I've included a link to Juval's book, Righting Software - that's RIGHTing, in the show notes. Juval was kind enough to send me a copy and what I've read so far makes a lot of sense.</p><h2>Show Resources and Links</h2><ul><li><a href="http://idesign.net/">IDesign</a></li><li><a href="https://amzn.to/2Oz2fut">Righting Software</a> - on Amazon</li><li><a href="https://devbetter.com">devBetter</a></li><li><a href="https://ardalis.com/blog">Ardalis Blog</a></li><li><a href="https://www.pluralsight.com/authors/steve-smith">Pluralsight Courses</a></li></ul><p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="9640274" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/6dbcdb90-2dd9-4ec9-abbf-d4406c4a3595/weekly-dev-tips-062-requirements-and-change-juval-lowy-auphonic_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Requirements and Change with Guest Juval Löwy</itunes:title>
      <itunes:author>Steve Smith (@ardalis), Juval Löwy</itunes:author>
      <itunes:duration>00:10:03</itunes:duration>
      <itunes:summary>This week&apos;s guest is Juval Löwy of IDesign. He has a tip for us this week on how we approach writing software. I&apos;ll let him introduce himself and share his tips.</itunes:summary>
      <itunes:subtitle>This week&apos;s guest is Juval Löwy of IDesign. He has a tip for us this week on how we approach writing software. I&apos;ll let him introduce himself and share his tips.</itunes:subtitle>
      <itunes:keywords>developer, software design, tips</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>62</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">8b84e79d-db3e-438b-a5dc-b499700a7416</guid>
      <title>Mise en Place with guest Ryan Lanciaux</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p><p><br /> </p><p>This is episode 61.</p><p><br /> </p><p><strong># Mise en Place</strong></p><p><br /> </p><p>This week's tip is brought to you by devBetter.com.</p><p><br /> </p><p><strong>## Sponsor - devBetter Group Career Coaching for Developers</strong></p><p><br /> </p><p>What is devBetter? It's a private group coaching community geared toward accelerating developer careers. We meet weekly for live Q&A sessions and have an active Discord-based discussion the rest of the week. Topics range from coding skills to interviewing and personal branding. Check out [devBetter.com](https://devbetter.com/) and read the testimonials at the bottom of the page.</p><p><br /> </p><p><strong># Mise en Place</strong></p><p><br /> </p><p>This week I'm happy to introduce Ryan Lanciaux who has a guest tip to share on mise en place. Ryan runs Spaceship Studio LLC, a consultancy specializing in fast and dynamic web and native mobile applications. Take it away, Ryan!</p><p><br /> </p><p>(no transcript)</p><p><br /> </p><p>Thanks, Ryan! Ryan also recently wrote a blog post on the magic of mise en place if you'd like to learn more. There's a link to it in this episode's show notes on weeklydevtips.com.</p><p><br /> </p><p><strong>## Show Resources and Links</strong></p><p><br /> </p><p>-[Follow Ryan on Twitter](https://twitter.com/ryanlanciaux)</p><p>-[The Magic of Mise-en-Place](http://ryanlanciaux.com/blog/2019/09/20/the-magic-of-a-mise-en-place-mindset-for-frontend-development/)</p><p>-[devBetter](https://devbetter.com)</p><p>-[Ardalis Blog](https://ardalis.com/blog)</p><p>-[Pluralsight Courses](<a href="https://www.pluralsight.com/authors/steve-smith">https://www.pluralsight.com/authors/steve-smith</a>)</p><p><br /> </p><p>That’s it for this week. If you want to hear more from me, go to [ardalis.com/tips](https://ardalis.com/tips) to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on [twitch.tv/ardalis](https://twitch.tv/ardalis) most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p><p><br /> </p>
]]></description>
      <pubDate>Tue, 4 Feb 2020 21:06:20 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p><p><br /> </p><p>This is episode 61.</p><p><br /> </p><p><strong># Mise en Place</strong></p><p><br /> </p><p>This week's tip is brought to you by devBetter.com.</p><p><br /> </p><p><strong>## Sponsor - devBetter Group Career Coaching for Developers</strong></p><p><br /> </p><p>What is devBetter? It's a private group coaching community geared toward accelerating developer careers. We meet weekly for live Q&A sessions and have an active Discord-based discussion the rest of the week. Topics range from coding skills to interviewing and personal branding. Check out [devBetter.com](https://devbetter.com/) and read the testimonials at the bottom of the page.</p><p><br /> </p><p><strong># Mise en Place</strong></p><p><br /> </p><p>This week I'm happy to introduce Ryan Lanciaux who has a guest tip to share on mise en place. Ryan runs Spaceship Studio LLC, a consultancy specializing in fast and dynamic web and native mobile applications. Take it away, Ryan!</p><p><br /> </p><p>(no transcript)</p><p><br /> </p><p>Thanks, Ryan! Ryan also recently wrote a blog post on the magic of mise en place if you'd like to learn more. There's a link to it in this episode's show notes on weeklydevtips.com.</p><p><br /> </p><p><strong>## Show Resources and Links</strong></p><p><br /> </p><p>-[Follow Ryan on Twitter](https://twitter.com/ryanlanciaux)</p><p>-[The Magic of Mise-en-Place](http://ryanlanciaux.com/blog/2019/09/20/the-magic-of-a-mise-en-place-mindset-for-frontend-development/)</p><p>-[devBetter](https://devbetter.com)</p><p>-[Ardalis Blog](https://ardalis.com/blog)</p><p>-[Pluralsight Courses](<a href="https://www.pluralsight.com/authors/steve-smith">https://www.pluralsight.com/authors/steve-smith</a>)</p><p><br /> </p><p>That’s it for this week. If you want to hear more from me, go to [ardalis.com/tips](https://ardalis.com/tips) to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on [twitch.tv/ardalis](https://twitch.tv/ardalis) most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p><p><br /> </p>
]]></content:encoded>
      <enclosure length="7624452" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/96bd9701-aa01-42f5-90df-8527797b79b2/061-mise-en-place-with-ryan-lanciaux_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Mise en Place with guest Ryan Lanciaux</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:duration>00:09:40</itunes:duration>
      <itunes:summary>Mise en Place with guest Ryan Lanciaux</itunes:summary>
      <itunes:subtitle>Mise en Place with guest Ryan Lanciaux</itunes:subtitle>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>61</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">a5ed02f6-1c9e-4c7f-abe1-ebc45526c5e1</guid>
      <title>How Developers Fail</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p><p>This is episode 60.</p><h1>How Developers Fail</h1><p>This week's tip is brought to you by devBetter.com.</p><h2>Sponsor - devBetter Group Career Coaching for Developers</h2><p>What is devBetter? It's a private group coaching community geared toward accelerating developer careers. We meet weekly for live Q&A sessions and have an active Discord-based discussion the rest of the week. Topics range from coding skills to interviewing and personal branding. Check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page.</p><h2>How Developers Fail</h2><p>I'm fond of saying "Developers fail in two ways: either we build the thing wrong or we build the wrong thing." I like the word play, which helps make the quote more memorable. It's very similar to the adage that "if you don't like where you work, you can change your organization, or you can change organizations." But it also strikes me that that most developers focus more on one problem than the other. In my experience, both personally and with others I've worked with, more junior programmers are most concerned with how to build the thing. There's a technical challenge there, and figuring it out is something many of us enjoy, like solving a puzzle. But as you gain experience, you find that often the thing you or your team built isn't actually the thing the customer wanted. And this kind of failure is both more difficult to detect and often more expensive to address after the fact.</p><h2>Building the Thing Wrong</h2><p>Let's focus for a moment on the first kind of failure, building the thing wrong. It's intentionally vague. The thing is whatever the software is you're building. And wrong in this case means any kind of technical defect that results in the system not meeting its users' needs. Maybe there's a critical bug that results in the system crashing. Maybe the architecture doesn't scale. Maybe there are massive performance or resource problems or memory leaks that make the system unusable. It could even be a security flaw that allows a malicious user to take down the system, or compromise its private data. These are all the kinds of things we tend to think of when we think about flaws or defects or bugs in software applications.</p><p>Sometimes, quite often in fact, these failures are quite minor. They may be caught by a build server or during manual testing before end users ever see them. Other times, the failures may be quite expensive, with no easy fix. Some bugs are inevitable, which is why we design software processes to expect, detect, and correct them. Our engineering practices are very often designed to find system defects as quickly as possible, since we know correcting a defect moments after its introduction is orders of magnitude less expensive than after it's been shipped to production. Make no mistake, preventing the shipping of defects is a very worthwhile activity for software teams.</p><p>Another more subtle way in which we might build things wrong is architecturally or from the standpoint of quality. Certain decisions made early on about the system architecture might turn out to be "wrong" later on when they prevent us from responding to customer demands. Technical debt in the form of shortcuts taken can have a similar impact later in the life of a system. Though more insidious than the release of user-observable defects, these too are examples of building things wrong.</p><h2>Building the Wrong Thing</h2><p>So what about the second class of failure, building the wrong thing? Why would we do that? It turns out communication is hard. Customers and users don't always communicate what they want clearly. We don't always listen well. Or we forget. Or we build what we think they want - or what we would want - instead of what they say they want. Sometimes that even works, but most of the time it's an example of forgetting that you are not the user.</p><p>Oftentimes the user wants to solve a problem, but when they see part of what your software-based solution looks like, it triggers new ideas about how to better solve the problem. It's not that they didn't know what they wanted, but rather that the iterative process of designing a solution has revealed a better approach they was apparent at the outset. The worst thing we can do as software developers is to force the production of a mediocre solution because we are not open to a great one that our efforts made apparent later in the development process. To that end, it's important to communicate frequently, to validate our assumptions, and to allow the customers and stakeholders to respond to our work as it progresses. Be willing to change direction and be open to new ideas in order to maximize the value of the solution you deliver.</p><p>Being able to build a thing right is generally a question of technical competence. Once you reach a certain skill threshold, you have confidence in your ability to do it. Building the right thing requires additional skills and may depend on that technical competence. Beyond building software right, you must now be able to communicate quickly and effectively and pivot the direction of your solution as needed based on the latest information.</p><p>Only then can you be confident that you're building the right thing right.</p><h2>Show Resources and Links</h2><ul><li><a href="https://devbetter.com">devBetter</a></li><li><a href="https://ardalis.com/blog">Ardalis Blog</a></li><li><a href="https://www.pluralsight.com/authors/steve-smith">Pluralsight Courses</a></li></ul><p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 27 Jan 2020 07:00:09 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@Ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p><p>This is episode 60.</p><h1>How Developers Fail</h1><p>This week's tip is brought to you by devBetter.com.</p><h2>Sponsor - devBetter Group Career Coaching for Developers</h2><p>What is devBetter? It's a private group coaching community geared toward accelerating developer careers. We meet weekly for live Q&A sessions and have an active Discord-based discussion the rest of the week. Topics range from coding skills to interviewing and personal branding. Check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page.</p><h2>How Developers Fail</h2><p>I'm fond of saying "Developers fail in two ways: either we build the thing wrong or we build the wrong thing." I like the word play, which helps make the quote more memorable. It's very similar to the adage that "if you don't like where you work, you can change your organization, or you can change organizations." But it also strikes me that that most developers focus more on one problem than the other. In my experience, both personally and with others I've worked with, more junior programmers are most concerned with how to build the thing. There's a technical challenge there, and figuring it out is something many of us enjoy, like solving a puzzle. But as you gain experience, you find that often the thing you or your team built isn't actually the thing the customer wanted. And this kind of failure is both more difficult to detect and often more expensive to address after the fact.</p><h2>Building the Thing Wrong</h2><p>Let's focus for a moment on the first kind of failure, building the thing wrong. It's intentionally vague. The thing is whatever the software is you're building. And wrong in this case means any kind of technical defect that results in the system not meeting its users' needs. Maybe there's a critical bug that results in the system crashing. Maybe the architecture doesn't scale. Maybe there are massive performance or resource problems or memory leaks that make the system unusable. It could even be a security flaw that allows a malicious user to take down the system, or compromise its private data. These are all the kinds of things we tend to think of when we think about flaws or defects or bugs in software applications.</p><p>Sometimes, quite often in fact, these failures are quite minor. They may be caught by a build server or during manual testing before end users ever see them. Other times, the failures may be quite expensive, with no easy fix. Some bugs are inevitable, which is why we design software processes to expect, detect, and correct them. Our engineering practices are very often designed to find system defects as quickly as possible, since we know correcting a defect moments after its introduction is orders of magnitude less expensive than after it's been shipped to production. Make no mistake, preventing the shipping of defects is a very worthwhile activity for software teams.</p><p>Another more subtle way in which we might build things wrong is architecturally or from the standpoint of quality. Certain decisions made early on about the system architecture might turn out to be "wrong" later on when they prevent us from responding to customer demands. Technical debt in the form of shortcuts taken can have a similar impact later in the life of a system. Though more insidious than the release of user-observable defects, these too are examples of building things wrong.</p><h2>Building the Wrong Thing</h2><p>So what about the second class of failure, building the wrong thing? Why would we do that? It turns out communication is hard. Customers and users don't always communicate what they want clearly. We don't always listen well. Or we forget. Or we build what we think they want - or what we would want - instead of what they say they want. Sometimes that even works, but most of the time it's an example of forgetting that you are not the user.</p><p>Oftentimes the user wants to solve a problem, but when they see part of what your software-based solution looks like, it triggers new ideas about how to better solve the problem. It's not that they didn't know what they wanted, but rather that the iterative process of designing a solution has revealed a better approach they was apparent at the outset. The worst thing we can do as software developers is to force the production of a mediocre solution because we are not open to a great one that our efforts made apparent later in the development process. To that end, it's important to communicate frequently, to validate our assumptions, and to allow the customers and stakeholders to respond to our work as it progresses. Be willing to change direction and be open to new ideas in order to maximize the value of the solution you deliver.</p><p>Being able to build a thing right is generally a question of technical competence. Once you reach a certain skill threshold, you have confidence in your ability to do it. Building the right thing requires additional skills and may depend on that technical competence. Beyond building software right, you must now be able to communicate quickly and effectively and pivot the direction of your solution as needed based on the latest information.</p><p>Only then can you be confident that you're building the right thing right.</p><h2>Show Resources and Links</h2><ul><li><a href="https://devbetter.com">devBetter</a></li><li><a href="https://ardalis.com/blog">Ardalis Blog</a></li><li><a href="https://www.pluralsight.com/authors/steve-smith">Pluralsight Courses</a></li></ul><p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="5186324" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/c8d6c55a-860c-458d-ab90-09c41e93eb10/060-how-developers-fail_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>How Developers Fail</itunes:title>
      <itunes:author>Steve Smith (@Ardalis)</itunes:author>
      <itunes:duration>00:05:24</itunes:duration>
      <itunes:summary>Episode 60: How Developers Fail
In my experience, both personally and with others I&apos;ve worked with, more junior programmers are most concerned with how to build the thing. But as you gain experience, you find that often the thing you or your team built isn&apos;t actually the thing the customer wanted. And this kind of failure is both more difficult to detect and often more expensive to address after the fact.</itunes:summary>
      <itunes:subtitle>Episode 60: How Developers Fail
In my experience, both personally and with others I&apos;ve worked with, more junior programmers are most concerned with how to build the thing. But as you gain experience, you find that often the thing you or your team built isn&apos;t actually the thing the customer wanted. And this kind of failure is both more difficult to detect and often more expensive to address after the fact.</itunes:subtitle>
      <itunes:keywords>junior developer, failure, scipe, problem solving, project management</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>60</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">0aee82b0-9b2b-4cf4-b030-b73a4eaf5798</guid>
      <title>Versioning with guest Jon Skeet</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p><p><br /> </p><p>This is episode 59, on versioning and semver, with guest Jon Skeet.</p><p><br /> </p><p><strong># Versioning</strong></p><p><br /> </p><p>This week's tip is brought to you by devBetter.com.</p><p><br /> </p><p><strong>## Sponsor - devBetter Group Career Coaching for Developers</strong></p><p><br /> </p><p>devBetter is a career coaching group I started last year. It gives you direct access to me as well as a group of peers with a diverse range of experience, with a shared goal of improving. We talk about code, careers, and more each week in our private online community and weekly live coaching sessions. Read the testimonials on [devBetter.com](https://devbetter.com/) and see what you think.</p><p><br /> </p><p>This week I'm excited to introduce Jon Skeet, who works for Google and is renowned for his Stack Overflow reputation. Jon's going to share some of his knowledge about versioning software, which can certainly be tricky business. I'll let him take it from here.</p><p><br /> </p><p><strong># Versioning with Jon Skeet</strong></p><p><br /> </p><p>(no transcript available - some selected quotes)</p><p><br /> </p><p>"Versioning is all about what you do guarantee for future versions and how they relate to previous versions."</p><p><br /> </p><p><strong># Back to Steve</strong></p><p><br /> </p><p>Thanks, Jon! I definitely learned something from that, and I'm sure many of my listeners did as well. I've added a link to your book web site and twitter profile to the show notes.</p><p><br /> </p><p><strong>## Show Resources and Links</strong></p><p><br /> </p><p>-[Jon Skeet on Twitter](https://twitter.com/jonskeet)</p><p>-[Jon's book, C# in Depth](https://csharpindepth.com/)</p><p>-[devBetter](https://devbetter.com)</p><p><br /> </p><p>That’s it for this week. If you want to hear more from me, go to [ardalis.com/tips](https://ardalis.com/tips) to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on [twitch.tv/ardalis](https://twitch.tv/ardalis) most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p><p><br /> </p>
]]></description>
      <pubDate>Mon, 28 Oct 2019 14:54:48 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p><p><br /> </p><p>This is episode 59, on versioning and semver, with guest Jon Skeet.</p><p><br /> </p><p><strong># Versioning</strong></p><p><br /> </p><p>This week's tip is brought to you by devBetter.com.</p><p><br /> </p><p><strong>## Sponsor - devBetter Group Career Coaching for Developers</strong></p><p><br /> </p><p>devBetter is a career coaching group I started last year. It gives you direct access to me as well as a group of peers with a diverse range of experience, with a shared goal of improving. We talk about code, careers, and more each week in our private online community and weekly live coaching sessions. Read the testimonials on [devBetter.com](https://devbetter.com/) and see what you think.</p><p><br /> </p><p>This week I'm excited to introduce Jon Skeet, who works for Google and is renowned for his Stack Overflow reputation. Jon's going to share some of his knowledge about versioning software, which can certainly be tricky business. I'll let him take it from here.</p><p><br /> </p><p><strong># Versioning with Jon Skeet</strong></p><p><br /> </p><p>(no transcript available - some selected quotes)</p><p><br /> </p><p>"Versioning is all about what you do guarantee for future versions and how they relate to previous versions."</p><p><br /> </p><p><strong># Back to Steve</strong></p><p><br /> </p><p>Thanks, Jon! I definitely learned something from that, and I'm sure many of my listeners did as well. I've added a link to your book web site and twitter profile to the show notes.</p><p><br /> </p><p><strong>## Show Resources and Links</strong></p><p><br /> </p><p>-[Jon Skeet on Twitter](https://twitter.com/jonskeet)</p><p>-[Jon's book, C# in Depth](https://csharpindepth.com/)</p><p>-[devBetter](https://devbetter.com)</p><p><br /> </p><p>That’s it for this week. If you want to hear more from me, go to [ardalis.com/tips](https://ardalis.com/tips) to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on [twitch.tv/ardalis](https://twitch.tv/ardalis) most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p><p><br /> </p>
]]></content:encoded>
      <enclosure length="6378906" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/cc91bac7-298f-4b6e-8238-28527b84986d/059-versioning-with-jon-skeet_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Versioning with guest Jon Skeet</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:duration>00:10:18</itunes:duration>
      <itunes:summary>This week I&apos;m excited to introduce Jon Skeet, who works for Google and is renowned for his Stack Overflow reputation. Jon&apos;s going to share some of his knowledge about versioning software, which can certainly be tricky business. I&apos;ll let him take it from here.</itunes:summary>
      <itunes:subtitle>This week I&apos;m excited to introduce Jon Skeet, who works for Google and is renowned for his Stack Overflow reputation. Jon&apos;s going to share some of his knowledge about versioning software, which can certainly be tricky business. I&apos;ll let him take it from here.</itunes:subtitle>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>59</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">4f788e4d-a0f3-4af5-8b0a-7e4570ae705b</guid>
      <title>Boundaries with guest James Hickey</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 58, on the concept of boundaries, with guest James Hickey.</p>
<h1>Boundaries</h1>
<p>This week's tip is brought to you by devBetter.com.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>Need to level up your career? Looking for a mentor or a the support of some motivated, tech-savvy peers? devBetter is a group coaching program I started last year. We meet for weekly group Q&amp;A sessions and have an ongoing private Slack channel the rest of the week. I offer advice, networking opportunities, coding exercises, marketing and branding tips, and occasional assignments to help members improve. Read some of the testimonials on <a href="https://devbetter.com/">devBetter.com</a> and see if it sounds like it you might be a good fit.</p>
<p>This week we have our first returning guest, James Hickey. James was on the show earlier for episode 48 on how to accelerate your career. This week, he's back to talk about boundaries withing software systems. James is a software developer working remotely in eastern Canada. He's recently written a book about keeping your code clean called &quot;Refactoring TypeScript&quot; (https://leanpub.com/refactoringtypescript). He's also the author of an open-source .NET Core library called Coravel, which provides advanced capabilities to web applications. Welcome back, James!</p>
<h1>Boundaries</h1>
<p>Hi! I'm James Hickey.</p>
<p>I'm a software developer working remotely in eastern Canada.</p>
<p>When I started my career as a software developer I was thrust into a large codebase for a SAAS that helped automotive manufacturers perform analytics on their financial data.</p>
<p>The way the codebase was organized is probably familiar to most developers - especially those with a background in enterprise-y companies. The solution was organized into 3 main projects: business, DAL (data-access), and &quot;core&quot; (which was just a bunch of classes having no business logic full of public getters and setters).</p>
<p>At the end of the day, all the real business logic was mostly found within stored procedures in the database. So, all those layers didn't serve any real purpose. Business-oriented classes would just call a function from the DAL layer, and that method would call a stored procedure.</p>
<p>As a fresh-out-of-school developer who's trying to learn &quot;how the pros do it&quot;, I didn't question this way of organizing code.</p>
<p>Eventually, though, I came to realize that this way of organizing code was terrible. It was hard to find code for specific features. You end up having to switch contexts between multiple projects when working on the same feature.</p>
<h1>A Better Way</h1>
<p>I've also been in projects having very different ways of organizing code, yet suffered from the same kinds of issues.</p>
<p>Throughout this time, I had a hunch that there was a common issue that was causing these difficulties. It didn't matter how well classes or sub-systems were designed, because, in the grand scheme of things, it was still hard to deal with the codebase as a whole.</p>
<p>As I read books and blogs and listened to well-known industry experts share their knowledge about software design, I came across better techniques and patterns for organizing code and designing software well.</p>
<p>Then, I discovered domain-driven design.</p>
<h2>DDD</h2>
<p>DDD is a pretty huge subject, but at the heart of the entire philosophy is the idea that the most important thing about managing complexity in software is around putting up boundaries.</p>
<p>In these other systems I've mentioned, the boundaries were enforced the wrong way. Instead of slicing our solutions by technical concerns (like by data-access, objects, interfaces, etc.), DDD teaches us to slice our solutions by business functionality (like shipping, search, billing, etc.)</p>
<p>Since then, I've had the opportunity to learn about other approaches to software design and have formed some opinions around what works well and what generally doesn't work out so well.</p>
<p>Out of all of these ideas, the most important one I've learned and have seen the effects of within real software projects is this idea of creating boundaries.</p>
<h2>Different Boundary Types</h2>
<p>You might be familiar with the concept called Bounded Contexts. In a nutshell, these are isolated sub-systems or bubbles that you design and build individually. Instead of creating one codebase and shoving all your code into it, you create a codebase or application per specific business feature or area of functionality.</p>
<p>Multiple boundaries can communicate with each other, but not by traditional means. In projects like the ones I mentioned at the beginning, if shipping needed information from the payments feature, it would just reach into the database and query the payments table!</p>
<p>These more strict boundaries mean you can't just reach into another feature's data or code.</p>
<p>This has many benefits. Mainly, it allows the inside of each boundary to attack its core business problem head-on and not worry about secondary concerns like persistence and what other business problems require. And it decouples all your different bubbles or contexts.</p>
<p>Inside each bounded context are these other boundaries called aggregates. These are objects that represent transactional boundaries.</p>
<p>The details are not important, but what is important is that each aggregate does not directly call another aggregate's methods and grab its data. Usually, aggregates will emit events to communicate with each other.</p>
<p>I use domain-driven design as the first example because the idea of boundaries is so fundamental to it.</p>
<p>But there are other ways to enforce boundaries.</p>
<p>Some prefer to create an isolated component, module, package or assembly (depending on what language you are in) and expose all the functionality of that isolated component as a facade. In this case, you might have one class that has all the publicly accessible behaviours or functions. None of the internal classes are exposed.</p>
<p>When looking at architectures like Clean Architecture, all business functionality might be exposed as use cases. Each use case, like &quot;register new user&quot;, would be modelled as a single class. This class would not expose any domain objects or objects from modules farther down the chain. It would expose it's own specific models or DTOs. This is a way to enforce a boundary so that the outside world doesn't know about the internal details of specific modules or components.</p>
<p>Similarly, if you are building a web API then you might want to enforce boundaries by using view models or DTOs which are used for sending data to your clients. This way, internal details like specific domain classes aren't exposed and you can modify or version each endpoint without affecting the other modules or projects that depend on it.</p>
<p>Using specific classes dedicated for use in HTTP POST data binding also helps keep boundaries around each specific end-point. You also get the added security benefit of not &quot;over posting.&quot;</p>
<h2>Duplication?</h2>
<p>Whenever you share code you are introducing some form of coupling. This, in turn, is the opposite of putting up boundaries.</p>
<p>Let's say, for example, I have a User class. This class is used within the user profile logic and the authentication logic for an application.</p>
<p>If I need to add new behaviours to the authentication flow, does it make sense that the same functionality is now available for use in the user profile scenario? Since both features are sharing the same class, this is possible.</p>
<p>This approach of trying to share as much code as possible throughout our apps is what causes spaghetti code and bugs galore. This is probably the biggest issue I come across in codebases. We think that sharing everything is good. But it's not. It creates a tangled mess of dependencies that, over time, cause businesses who want to be agile to sluggishly attempt to keep up with customer and market needs.</p>
<p>Instead, if we isolate each of these features and NOT share that User class, then changes from one feature won't affect the other.</p>
<p>Sure, you might end up creating two different user classes that have what look like duplicated fields, but that's OK. You aren't duplicating logic because these classes represent different things. The logic for the user profile screen is going to be different than authentication logic by definition.</p>
<p>There is a place for shared behaviour, like sharing how you might display a user's name in your application's UI. But fundamentally, we should seek to create boundaries around the different parts of our codebases.</p>
<h2>Conclusion</h2>
<p>Next time you find yourself having to start a new project or product, think about how you can isolate that product or feature from the rest of your codebase.</p>
<p>Maybe you want to build it as a completely separate assembly or project? In this case, you could use an event-driven means of communication. Or, maybe expose a public API as a facade.</p>
<p>If that doesn't make sense or isn't possible, you can at least create a new folder structure that makes it very clear what business functionality exists in that place.</p>
<p>I've written more about this last point over at <a href="https://builtwithdot.net/blog/changing-how-your-code-is-organized-could-speed-development-from-weeks-to-days">builtwithdot.net</a> if you are curious.</p>
<p>Thanks for listening in!</p>
<p>Thanks, James. I've added a link to your blog to the show notes. Listeners interested in learning more about Domain-Driven Design and Clean Architecture will find additional resources in the show notes as well.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://builtwithdot.net/blog/changing-how-your-code-is-organized-could-speed-development-from-weeks-to-days">Changing How Your Code is Organized Could Speed Development</a></li>
<li><a href="https://github.com/ardalis/CleanArchitecture">Clean Architecture on GitHub</a></li>
<li><a href="https://www.pluralsight.com/courses/domain-driven-design-fundamentals">DDD Fundamentals</a></li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 30 Sep 2019 06:00:13 +0000</pubDate>
      <author>steve@ardalis.com (James Hickey)</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 58, on the concept of boundaries, with guest James Hickey.</p>
<h1>Boundaries</h1>
<p>This week's tip is brought to you by devBetter.com.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>Need to level up your career? Looking for a mentor or a the support of some motivated, tech-savvy peers? devBetter is a group coaching program I started last year. We meet for weekly group Q&amp;A sessions and have an ongoing private Slack channel the rest of the week. I offer advice, networking opportunities, coding exercises, marketing and branding tips, and occasional assignments to help members improve. Read some of the testimonials on <a href="https://devbetter.com/">devBetter.com</a> and see if it sounds like it you might be a good fit.</p>
<p>This week we have our first returning guest, James Hickey. James was on the show earlier for episode 48 on how to accelerate your career. This week, he's back to talk about boundaries withing software systems. James is a software developer working remotely in eastern Canada. He's recently written a book about keeping your code clean called &quot;Refactoring TypeScript&quot; (https://leanpub.com/refactoringtypescript). He's also the author of an open-source .NET Core library called Coravel, which provides advanced capabilities to web applications. Welcome back, James!</p>
<h1>Boundaries</h1>
<p>Hi! I'm James Hickey.</p>
<p>I'm a software developer working remotely in eastern Canada.</p>
<p>When I started my career as a software developer I was thrust into a large codebase for a SAAS that helped automotive manufacturers perform analytics on their financial data.</p>
<p>The way the codebase was organized is probably familiar to most developers - especially those with a background in enterprise-y companies. The solution was organized into 3 main projects: business, DAL (data-access), and &quot;core&quot; (which was just a bunch of classes having no business logic full of public getters and setters).</p>
<p>At the end of the day, all the real business logic was mostly found within stored procedures in the database. So, all those layers didn't serve any real purpose. Business-oriented classes would just call a function from the DAL layer, and that method would call a stored procedure.</p>
<p>As a fresh-out-of-school developer who's trying to learn &quot;how the pros do it&quot;, I didn't question this way of organizing code.</p>
<p>Eventually, though, I came to realize that this way of organizing code was terrible. It was hard to find code for specific features. You end up having to switch contexts between multiple projects when working on the same feature.</p>
<h1>A Better Way</h1>
<p>I've also been in projects having very different ways of organizing code, yet suffered from the same kinds of issues.</p>
<p>Throughout this time, I had a hunch that there was a common issue that was causing these difficulties. It didn't matter how well classes or sub-systems were designed, because, in the grand scheme of things, it was still hard to deal with the codebase as a whole.</p>
<p>As I read books and blogs and listened to well-known industry experts share their knowledge about software design, I came across better techniques and patterns for organizing code and designing software well.</p>
<p>Then, I discovered domain-driven design.</p>
<h2>DDD</h2>
<p>DDD is a pretty huge subject, but at the heart of the entire philosophy is the idea that the most important thing about managing complexity in software is around putting up boundaries.</p>
<p>In these other systems I've mentioned, the boundaries were enforced the wrong way. Instead of slicing our solutions by technical concerns (like by data-access, objects, interfaces, etc.), DDD teaches us to slice our solutions by business functionality (like shipping, search, billing, etc.)</p>
<p>Since then, I've had the opportunity to learn about other approaches to software design and have formed some opinions around what works well and what generally doesn't work out so well.</p>
<p>Out of all of these ideas, the most important one I've learned and have seen the effects of within real software projects is this idea of creating boundaries.</p>
<h2>Different Boundary Types</h2>
<p>You might be familiar with the concept called Bounded Contexts. In a nutshell, these are isolated sub-systems or bubbles that you design and build individually. Instead of creating one codebase and shoving all your code into it, you create a codebase or application per specific business feature or area of functionality.</p>
<p>Multiple boundaries can communicate with each other, but not by traditional means. In projects like the ones I mentioned at the beginning, if shipping needed information from the payments feature, it would just reach into the database and query the payments table!</p>
<p>These more strict boundaries mean you can't just reach into another feature's data or code.</p>
<p>This has many benefits. Mainly, it allows the inside of each boundary to attack its core business problem head-on and not worry about secondary concerns like persistence and what other business problems require. And it decouples all your different bubbles or contexts.</p>
<p>Inside each bounded context are these other boundaries called aggregates. These are objects that represent transactional boundaries.</p>
<p>The details are not important, but what is important is that each aggregate does not directly call another aggregate's methods and grab its data. Usually, aggregates will emit events to communicate with each other.</p>
<p>I use domain-driven design as the first example because the idea of boundaries is so fundamental to it.</p>
<p>But there are other ways to enforce boundaries.</p>
<p>Some prefer to create an isolated component, module, package or assembly (depending on what language you are in) and expose all the functionality of that isolated component as a facade. In this case, you might have one class that has all the publicly accessible behaviours or functions. None of the internal classes are exposed.</p>
<p>When looking at architectures like Clean Architecture, all business functionality might be exposed as use cases. Each use case, like &quot;register new user&quot;, would be modelled as a single class. This class would not expose any domain objects or objects from modules farther down the chain. It would expose it's own specific models or DTOs. This is a way to enforce a boundary so that the outside world doesn't know about the internal details of specific modules or components.</p>
<p>Similarly, if you are building a web API then you might want to enforce boundaries by using view models or DTOs which are used for sending data to your clients. This way, internal details like specific domain classes aren't exposed and you can modify or version each endpoint without affecting the other modules or projects that depend on it.</p>
<p>Using specific classes dedicated for use in HTTP POST data binding also helps keep boundaries around each specific end-point. You also get the added security benefit of not &quot;over posting.&quot;</p>
<h2>Duplication?</h2>
<p>Whenever you share code you are introducing some form of coupling. This, in turn, is the opposite of putting up boundaries.</p>
<p>Let's say, for example, I have a User class. This class is used within the user profile logic and the authentication logic for an application.</p>
<p>If I need to add new behaviours to the authentication flow, does it make sense that the same functionality is now available for use in the user profile scenario? Since both features are sharing the same class, this is possible.</p>
<p>This approach of trying to share as much code as possible throughout our apps is what causes spaghetti code and bugs galore. This is probably the biggest issue I come across in codebases. We think that sharing everything is good. But it's not. It creates a tangled mess of dependencies that, over time, cause businesses who want to be agile to sluggishly attempt to keep up with customer and market needs.</p>
<p>Instead, if we isolate each of these features and NOT share that User class, then changes from one feature won't affect the other.</p>
<p>Sure, you might end up creating two different user classes that have what look like duplicated fields, but that's OK. You aren't duplicating logic because these classes represent different things. The logic for the user profile screen is going to be different than authentication logic by definition.</p>
<p>There is a place for shared behaviour, like sharing how you might display a user's name in your application's UI. But fundamentally, we should seek to create boundaries around the different parts of our codebases.</p>
<h2>Conclusion</h2>
<p>Next time you find yourself having to start a new project or product, think about how you can isolate that product or feature from the rest of your codebase.</p>
<p>Maybe you want to build it as a completely separate assembly or project? In this case, you could use an event-driven means of communication. Or, maybe expose a public API as a facade.</p>
<p>If that doesn't make sense or isn't possible, you can at least create a new folder structure that makes it very clear what business functionality exists in that place.</p>
<p>I've written more about this last point over at <a href="https://builtwithdot.net/blog/changing-how-your-code-is-organized-could-speed-development-from-weeks-to-days">builtwithdot.net</a> if you are curious.</p>
<p>Thanks for listening in!</p>
<p>Thanks, James. I've added a link to your blog to the show notes. Listeners interested in learning more about Domain-Driven Design and Clean Architecture will find additional resources in the show notes as well.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://builtwithdot.net/blog/changing-how-your-code-is-organized-could-speed-development-from-weeks-to-days">Changing How Your Code is Organized Could Speed Development</a></li>
<li><a href="https://github.com/ardalis/CleanArchitecture">Clean Architecture on GitHub</a></li>
<li><a href="https://www.pluralsight.com/courses/domain-driven-design-fundamentals">DDD Fundamentals</a></li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="5054952" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/b2bf1d72-10dc-46f4-af2a-a9a8f8263a4c/058-boundaries-with-guest-james-hickey_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Boundaries with guest James Hickey</itunes:title>
      <itunes:author>James Hickey</itunes:author>
      <itunes:duration>00:10:22</itunes:duration>
      <itunes:summary>This week we have our first returning guest, James Hickey. James was on the show earlier for episode 48 on how to accelerate your career. This week, he&apos;s back to talk about boundaries withing software systems. James is a software developer working remotely in eastern Canada. He&apos;s recently written a book about keeping your code clean called &quot;Refactoring TypeScript&quot; (https://leanpub.com/refactoringtypescript). He&apos;s also the author of an open-source .NET Core library called Coravel, which provides advanced capabilities to web applications. Welcome back, James!</itunes:summary>
      <itunes:subtitle>This week we have our first returning guest, James Hickey. James was on the show earlier for episode 48 on how to accelerate your career. This week, he&apos;s back to talk about boundaries withing software systems. James is a software developer working remotely in eastern Canada. He&apos;s recently written a book about keeping your code clean called &quot;Refactoring TypeScript&quot; (https://leanpub.com/refactoringtypescript). He&apos;s also the author of an open-source .NET Core library called Coravel, which provides advanced capabilities to web applications. Welcome back, James!</itunes:subtitle>
      <itunes:keywords>software development, clean architecture, ddd, agile, clean code, programming, domain driven design</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>58</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">12ec5ea6-7d84-45cf-a7a6-8fcf6c12e0ee</guid>
      <title>Dependency Inversion Principle</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p><p>This is episode 57, on the Dependency Inversion principle.</p><h1>Dependency Inversion Principle</h1><p>This week's tip is brought to you by devBetter.com.</p><h2>Sponsor - devBetter Group Career Coaching for Developers</h2><p>Need to level up your career? Looking for a mentor or a the support of some motivated, tech-savvy peers? devBetter is a group coaching program I started last year. We meet for weekly group Q&A sessions and have an ongoing private Slack channel the rest of the week. I offer advice, networking opportunities, coding exercises, marketing and branding tips, and occasional assignments to help members improve. Interested? Check it out at <a href="https://devbetter.com/">devBetter.com</a>.</p><h2>Show Notes / Transcript</h2><p>Ok, now we've reached the last and in my opinion the most important of the <a href="https://www.pluralsight.com/courses/csharp-solid-principles">SOLID principles</a>, D for Dependency Inversion. The Dependency Inversion Principle, or DIP for short, has a longer definition that most of the other principles and is often conflated with the related coding technique, dependency inversion, or DI. The principle states that <strong>High-level modules should not depend on low-level modules. Both should depend on abstractions (interfaces or abstract types).</strong> and further, <strong>Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions.</strong></p><p>Let's look quickly at each of these two parts. The first part talks about high level and low level modules. The "level" of a module has to do with how near or far it is from some kind of I/O device. That could be the user interface or it could be a local file or a database server. Low level modules deal directly with these kinds of I/O devices or destinations. High level modules do not know about or deal with specific kinds of I/O. These are things like business logic classes and behavior that model how a system works. In many systems that don't use abstractions, high level modules depend on low level modules, or the high level logic is mixed in with low level concerns in the same modules. Both of these approaches violate the Dependency Inversion Principle. Instead, these modules should communicate with one another using abstractions like C# or Java interfaces. Both kinds of modules would depend on a common interface, typically with the low level module implementing the interface and the high level module calling it.</p><p>The second part suggests that abstractions - interfaces typically - should not depend on details. So an example of this would be if you had an interface for fetching information about a customer. One approach would be to write the interface so that it returned a <code>SqlDataReader</code> as its return type, where the data reader had the customer info. This exposes the details of how the data is stored, since you would only use a <code>SqlDataReader</code> to fetch the data from a SQL database. One benefit of following the Dependency Inversion principle is modularity. You could change that interface to return a simple <code>List<Customer></code> type and that <code>List<Customer></code> could come from any number of storage locations, from databases, to files to in-memory stores or web APIs. So, that covers how abstractions should not depend on details - what about the last bit that says details should depend on abstractions? That's talking about your low-level modules that actually communicate with I/O. These should depend on your interfaces by implementing them.</p><p>If you're build a system composed of multiple projects it can be extremely difficult to follow the Dependency Inversion principle if you don't structure your project dependencies appropriately. This means ensuring that your abstractions - your interfaces - live in a project alongside your business model entities and that your implementation details live in another project that references this one. I have a GitHub repository and solution template called <a href="https://github.com/ardalis/CleanArchitecture">Clean Architecture</a> that you can use as a starting point for new ASP.NET Core applications that need to follow SOLID principles and use clean architecture. You'll find a link to it in the show notes or just google ardalis clean architecture.</p><p>A key benefit of Clean Architecture that is enabled by following the Dependency Inversion Principle is that your business model has no dependencies on external infrastructure concerns. These dependencies are a huge part of why legacy codebases are often difficult or impossible to write unit tests for. By keeping these dependencies separate and in their own project that other projects do not depend upon, it makes it much easier to unit test the most important part of your application: its business domain model. I talk more about this in my <a href="https://www.pluralsight.com/courses/domain-driven-design-fundamentals">DDD Fundamentals</a> course with Julie Lerman on Pluralsight if you want to see this in action. You can also check out the <a href="https://github.com/dotnet-architecture/eShopOnWeb">eShopOnWeb reference application</a> that I built for Microsoft and its companion book, Architecting Modern Web Applications with ASP.NET Core and Microsoft Azure.</p><h2>Show Resources and Links</h2><ul><li><a href="https://devbetter.com">devBetter</a></li><li><a href="https://github.com/ardalis/CleanArchitecture">Clean Architecture on GitHub</a></li><li><a href="https://www.pluralsight.com/courses/csharp-solid-principles">SOLID Principles for C# Developers</a></li><li><a href="https://www.pluralsight.com/courses/principles-oo-design">SOLID Principles of Object Oriented Design</a> -and the DRY Principle</li><li><a href="https://www.pluralsight.com/courses/domain-driven-design-fundamentals">DDD Fundamentals</a></li><li><a href="https://github.com/dotnet-architecture/eShopOnWeb">eShopOnWeb Reference Application</a></li></ul><p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 16 Sep 2019 06:00:09 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith)</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p><p>This is episode 57, on the Dependency Inversion principle.</p><h1>Dependency Inversion Principle</h1><p>This week's tip is brought to you by devBetter.com.</p><h2>Sponsor - devBetter Group Career Coaching for Developers</h2><p>Need to level up your career? Looking for a mentor or a the support of some motivated, tech-savvy peers? devBetter is a group coaching program I started last year. We meet for weekly group Q&A sessions and have an ongoing private Slack channel the rest of the week. I offer advice, networking opportunities, coding exercises, marketing and branding tips, and occasional assignments to help members improve. Interested? Check it out at <a href="https://devbetter.com/">devBetter.com</a>.</p><h2>Show Notes / Transcript</h2><p>Ok, now we've reached the last and in my opinion the most important of the <a href="https://www.pluralsight.com/courses/csharp-solid-principles">SOLID principles</a>, D for Dependency Inversion. The Dependency Inversion Principle, or DIP for short, has a longer definition that most of the other principles and is often conflated with the related coding technique, dependency inversion, or DI. The principle states that <strong>High-level modules should not depend on low-level modules. Both should depend on abstractions (interfaces or abstract types).</strong> and further, <strong>Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions.</strong></p><p>Let's look quickly at each of these two parts. The first part talks about high level and low level modules. The "level" of a module has to do with how near or far it is from some kind of I/O device. That could be the user interface or it could be a local file or a database server. Low level modules deal directly with these kinds of I/O devices or destinations. High level modules do not know about or deal with specific kinds of I/O. These are things like business logic classes and behavior that model how a system works. In many systems that don't use abstractions, high level modules depend on low level modules, or the high level logic is mixed in with low level concerns in the same modules. Both of these approaches violate the Dependency Inversion Principle. Instead, these modules should communicate with one another using abstractions like C# or Java interfaces. Both kinds of modules would depend on a common interface, typically with the low level module implementing the interface and the high level module calling it.</p><p>The second part suggests that abstractions - interfaces typically - should not depend on details. So an example of this would be if you had an interface for fetching information about a customer. One approach would be to write the interface so that it returned a <code>SqlDataReader</code> as its return type, where the data reader had the customer info. This exposes the details of how the data is stored, since you would only use a <code>SqlDataReader</code> to fetch the data from a SQL database. One benefit of following the Dependency Inversion principle is modularity. You could change that interface to return a simple <code>List<Customer></code> type and that <code>List<Customer></code> could come from any number of storage locations, from databases, to files to in-memory stores or web APIs. So, that covers how abstractions should not depend on details - what about the last bit that says details should depend on abstractions? That's talking about your low-level modules that actually communicate with I/O. These should depend on your interfaces by implementing them.</p><p>If you're build a system composed of multiple projects it can be extremely difficult to follow the Dependency Inversion principle if you don't structure your project dependencies appropriately. This means ensuring that your abstractions - your interfaces - live in a project alongside your business model entities and that your implementation details live in another project that references this one. I have a GitHub repository and solution template called <a href="https://github.com/ardalis/CleanArchitecture">Clean Architecture</a> that you can use as a starting point for new ASP.NET Core applications that need to follow SOLID principles and use clean architecture. You'll find a link to it in the show notes or just google ardalis clean architecture.</p><p>A key benefit of Clean Architecture that is enabled by following the Dependency Inversion Principle is that your business model has no dependencies on external infrastructure concerns. These dependencies are a huge part of why legacy codebases are often difficult or impossible to write unit tests for. By keeping these dependencies separate and in their own project that other projects do not depend upon, it makes it much easier to unit test the most important part of your application: its business domain model. I talk more about this in my <a href="https://www.pluralsight.com/courses/domain-driven-design-fundamentals">DDD Fundamentals</a> course with Julie Lerman on Pluralsight if you want to see this in action. You can also check out the <a href="https://github.com/dotnet-architecture/eShopOnWeb">eShopOnWeb reference application</a> that I built for Microsoft and its companion book, Architecting Modern Web Applications with ASP.NET Core and Microsoft Azure.</p><h2>Show Resources and Links</h2><ul><li><a href="https://devbetter.com">devBetter</a></li><li><a href="https://github.com/ardalis/CleanArchitecture">Clean Architecture on GitHub</a></li><li><a href="https://www.pluralsight.com/courses/csharp-solid-principles">SOLID Principles for C# Developers</a></li><li><a href="https://www.pluralsight.com/courses/principles-oo-design">SOLID Principles of Object Oriented Design</a> -and the DRY Principle</li><li><a href="https://www.pluralsight.com/courses/domain-driven-design-fundamentals">DDD Fundamentals</a></li><li><a href="https://github.com/dotnet-architecture/eShopOnWeb">eShopOnWeb Reference Application</a></li></ul><p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="3559110" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/3028abdc-b06f-4b13-a061-ef1438bc6894/057_dependency_inversion_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Dependency Inversion Principle</itunes:title>
      <itunes:author>Steve Smith</itunes:author>
      <itunes:duration>00:06:08</itunes:duration>
      <itunes:summary>The Dependency Inversion principle is one of the SOLID principles of OOP and is very useful for reducing tight coupling between modules in C# and Java applications.</itunes:summary>
      <itunes:subtitle>The Dependency Inversion principle is one of the SOLID principles of OOP and is very useful for reducing tight coupling between modules in C# and Java applications.</itunes:subtitle>
      <itunes:keywords>visual studio, software development, .net core, clean architecture, .net, dev, github, dependency inversion principle, best practices, clean code, java, programming, oop, principles, code, solid</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>57</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">37ff4c6f-e04a-4bd0-bb72-d5ef552969b0</guid>
      <title>One Step Build Test Run</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 56, on the importance of having a simple way to build, test, and run your application locally.</p>
<h1>One Step Build Test Run</h1>
<p>This week's tip is brought to you by devBetter.com.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>Need to level up your career? Looking for a mentor or a the support of some motivated, tech-savvy peers? devBetter is a group coaching program I started last year. We meet weekly for group Q&amp;A sessions and have an ongoing private Slack channel the rest of the week. I offer advice, networking opportunities, coding exercises, marketing and branding tips, and occasional assignments to help members improve. Interested? Check it out at <a href="https://devbetter.com/">devBetter.com</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>I've worked on a lot of projects for a lot of different companies and teams. One thing that dramatically increases the friction of becoming productive on a project is the number of manual and often undocumented steps required to take a new developer on a new machine and get them up and running the application from its source code locally. A lot of the time the developers on the team don't even recognize this as an issue because they've all been there long enough that they've absorbed the knowledge that's been passed down through shared oral history since the ancient times. But new developers, and especially new developers on distributed teams, weren't there last week when someone said &quot;Oh yeah, I changed this thing so now you have to install this tool before you run the app on your machine&quot;. They don't just magically know the arcane command line scripts that must be run from 4 different nested subfolders of the application's source code in order to get the system up and running. As soon as you have one new remote team member, it exposes all the implicit knowledge-sharing and manual steps that have taken root in the team's processes and, hopefully, forces the team to make these steps explicit and then to automate them as much as possible.</p>
<p>Simple projects don't require much, if any, documentation or automation. If you have an application that is so simple that any new developer can pull it down from source, use the default compilation step for the platform, like <code>dotnet run</code> for .NET Core or F5 for a Visual Studio-based solution, then you may not need any more documentation or automation than that.</p>
<p>But when it's not that simple, you'll make everybody's life easier if you document and automate the steps. Documentation should be first, since it just makes the steps explicit, and sometimes automation can be difficult to achieve, especially if you need it to work across different operating systems. This is getting easier, though. Once you have the steps documented, you should strive to automate them to the point where common tasks are a single step. Ideally you want a One Step Build Test Run script that does all of these things: builds the app, runs tests against it, runs the app.</p>
<p>But before we get that far, let's talk about how to document the process a bit more. Today, GitHub has become the standard for open source software projects. And GitHub has essentially codified the standard that projects should have README.md files in their root that describe what the project is. Even if you're not hosting your application's code on GitHub, it's a good guess that your dev team has looked at projects on GitHub and is familiar with this convention. Thus, purely from a discoverability standpoint, the best place to put important steps for building and running your app is in its README file in the root of the repo. If you have a lot of repositories that all use the same steps and you don't want that duplication, then put a link to the shared docs into each README.</p>
<p>What about wikis? Wikis are less discoverable. They're not right there in your face when you hit the home page of a repo, and they're not right there with your code when you're looking at the source in your favorite editor like a README file is. You can put more detailed documentation and steps into a wiki if you like, but to make it discoverable you should put links to it in the README file. If you use some CMS system or project management system the answer's the same - use the README as the place to include the links to the relevant information so new team members don't have to try and find it themselves. HTML supports hyperlinks for a reason.</p>
<p>Probably the worst thing you can do in documenting your local build/test/run process is to start by putting it in the README file and then later decide to put the process in a wiki or another location, but not update the README. This will cause team members to use the README and not discover the new location, wasting lots of their time. Bad information is worse than no information. Put a link to the new process documentation location in the README.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://ardalis.com/build-automation-for-your-application-using-msbuild">Really old blog post on one-click builds</a></li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 9 Sep 2019 06:00:02 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith)</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 56, on the importance of having a simple way to build, test, and run your application locally.</p>
<h1>One Step Build Test Run</h1>
<p>This week's tip is brought to you by devBetter.com.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>Need to level up your career? Looking for a mentor or a the support of some motivated, tech-savvy peers? devBetter is a group coaching program I started last year. We meet weekly for group Q&amp;A sessions and have an ongoing private Slack channel the rest of the week. I offer advice, networking opportunities, coding exercises, marketing and branding tips, and occasional assignments to help members improve. Interested? Check it out at <a href="https://devbetter.com/">devBetter.com</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>I've worked on a lot of projects for a lot of different companies and teams. One thing that dramatically increases the friction of becoming productive on a project is the number of manual and often undocumented steps required to take a new developer on a new machine and get them up and running the application from its source code locally. A lot of the time the developers on the team don't even recognize this as an issue because they've all been there long enough that they've absorbed the knowledge that's been passed down through shared oral history since the ancient times. But new developers, and especially new developers on distributed teams, weren't there last week when someone said &quot;Oh yeah, I changed this thing so now you have to install this tool before you run the app on your machine&quot;. They don't just magically know the arcane command line scripts that must be run from 4 different nested subfolders of the application's source code in order to get the system up and running. As soon as you have one new remote team member, it exposes all the implicit knowledge-sharing and manual steps that have taken root in the team's processes and, hopefully, forces the team to make these steps explicit and then to automate them as much as possible.</p>
<p>Simple projects don't require much, if any, documentation or automation. If you have an application that is so simple that any new developer can pull it down from source, use the default compilation step for the platform, like <code>dotnet run</code> for .NET Core or F5 for a Visual Studio-based solution, then you may not need any more documentation or automation than that.</p>
<p>But when it's not that simple, you'll make everybody's life easier if you document and automate the steps. Documentation should be first, since it just makes the steps explicit, and sometimes automation can be difficult to achieve, especially if you need it to work across different operating systems. This is getting easier, though. Once you have the steps documented, you should strive to automate them to the point where common tasks are a single step. Ideally you want a One Step Build Test Run script that does all of these things: builds the app, runs tests against it, runs the app.</p>
<p>But before we get that far, let's talk about how to document the process a bit more. Today, GitHub has become the standard for open source software projects. And GitHub has essentially codified the standard that projects should have README.md files in their root that describe what the project is. Even if you're not hosting your application's code on GitHub, it's a good guess that your dev team has looked at projects on GitHub and is familiar with this convention. Thus, purely from a discoverability standpoint, the best place to put important steps for building and running your app is in its README file in the root of the repo. If you have a lot of repositories that all use the same steps and you don't want that duplication, then put a link to the shared docs into each README.</p>
<p>What about wikis? Wikis are less discoverable. They're not right there in your face when you hit the home page of a repo, and they're not right there with your code when you're looking at the source in your favorite editor like a README file is. You can put more detailed documentation and steps into a wiki if you like, but to make it discoverable you should put links to it in the README file. If you use some CMS system or project management system the answer's the same - use the README as the place to include the links to the relevant information so new team members don't have to try and find it themselves. HTML supports hyperlinks for a reason.</p>
<p>Probably the worst thing you can do in documenting your local build/test/run process is to start by putting it in the README file and then later decide to put the process in a wiki or another location, but not update the README. This will cause team members to use the README and not discover the new location, wasting lots of their time. Bad information is worse than no information. Put a link to the new process documentation location in the README.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://ardalis.com/build-automation-for-your-application-using-msbuild">Really old blog post on one-click builds</a></li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="3596507" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/ec7dbd7d-e6a7-4d52-bc34-a59e610af3ba/056_one_step_build_test_run_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>One Step Build Test Run</itunes:title>
      <itunes:author>Steve Smith</itunes:author>
      <itunes:duration>00:06:15</itunes:duration>
      <itunes:summary>This is episode 56, on the importance of having a simple way to build, test, and run your application locally.</itunes:summary>
      <itunes:subtitle>This is episode 56, on the importance of having a simple way to build, test, and run your application locally.</itunes:subtitle>
      <itunes:keywords>ci, software development, github, build process, best practices, clean code, programming, devops, continuous integration, code</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>56</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">659a8d39-f741-4abf-ac6a-999c975d8d4e</guid>
      <title>Interface Segregation</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 55, on the Interface Segregation principle.</p>
<h1>Interface Segregation Principle</h1>
<p>This week's tip is brought to you by devBetter.com.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>You can find help and advice all over today, from twitter to Stack Overflow to various Slack communities. These are great, but if you need more, if you need someone you can count on when you reach out for advice on code or your career, check out devBetter.com. Read the testimonials. Join risk free and see if it's for you. Not only will you learn from me, but if you stay for a while you'll grow and begin to be a mentor for others, gaining valuable confidence and experience. I've watched it happen.</p>
<h2>Show Notes / Transcript</h2>
<p>Returning back to the next <a href="https://www.pluralsight.com/courses/csharp-solid-principles">SOLID principle</a>, this week we're on the I as in Interface. Yes, it's the Interface Segregation Principle! Or ISP for short. Let's start by defining what this principle says. ISP states that no client should be forced to depend on methods it does not use. That's it. You can think of ISP as basically suggesting that you should prefer small, cohesive interfaces to large interfaces. In episode 49, which hopefully you already heard because you're listening to these in sequential order, we talked about the Single Responsibility Principle. These two principles are related! If you have classes that have only one responsibility, they're likely to expose a small, cohesive interface.</p>
<p>That might be worth diving into a bit more. I'm guessing that when some developers, especially C# or Java developers, hear about ISP, they immediately map the word 'interface' to the interface type and keyword in these languages. That's not wrong, it's just not fully right, either. The public methods and properties a class exposes are its interface, even if it doesn't implement any interface defined separately. And ISP applies to implicit class interfaces just as much as it does to explicit interface definitions declared with the interface type. If you keep this in mind, it may make it easier to see how SRP and ISP relate, since SRP doesn't make any mention of interface types, only classes.</p>
<p>The previous principle we discussed, Liskov Substitution, also relates to ISP. If you have a small, cohesive interface on a class, then when you decide to inherit from it you only have a few methods to worry about. If you have a massive number of methods, and your subtype is only concerned with a subset of them, it's much more likely that you won't fully implement all of the class's methods, potentially leaving some methods to throw NotImplementedException. Thus, it's easier to follow LSP if you first follow ISP.</p>
<p>What's the point of having a smaller interface instead of a larger one, though? What's the down side to having fewer, larger classes with many methods on them? Certainly there's an argument to be made, and many have, that it makes it easier to find methods when you don't have so many different classes to search through to find them. The goal of ISP is to reduce dependency between types and especially between components in a system. The more types that depend on a particular type, the more difficult that type is to change. The more inertia it has in the system. If you have a class in your application that's used by 100 other classes, how likely are you to make major changes to its design, compared to one that you just wrote that has literally no other classes using it yet? Of course it's easier and WAY less risky to change classes that have few references to them.</p>
<p>Let's say you want to change something fundamental about how that class that's used by 100 other classes works. One way you could do that would be to create a new instance of that class's interface or abstract base class, but then you'd have to implement all of its methods. Odds are, there are a bunch of them. That's not going to be easy - so instead you might just add some more conditional logic to some of the methods. Maybe add a few more method parameters to some methods. Maybe add a couple of new method overloads. And guess what? The problem just got bigger. The class just got bigger. The inertia just grew.</p>
<p>By having a small interface and being focused on a small set of functionality, ISP-following classes are easier to change an easier to replace. By being small, they're easier to subtype or implement, making it easier to build systems that are modular. You find a class that has two methods and you want to change how it works in some situations? Just write a new class, implement the two methods, and swap it in where appropriate. <strong>Prefer writing new code to change legacy systems rather than modifying existing code.</strong> By following ISP, it's easier to replace classes with different variants that implement the same interface, which results in more loosely coupled and modular designs. These designs are easier to maintain and easier to test. You can learn more about ISP and the rest of the SOLID principles from my courses on Pluralsight, linked from this episode's show notes on <a href="/episodes/55">weeklydevtips.com/episodes/55</a>.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://www.pluralsight.com/courses/csharp-solid-principles">SOLID Principles for C# Developers</a></li>
<li><a href="https://www.pluralsight.com/courses/principles-oo-design">SOLID Principles of Object Oriented Design</a> -and the DRY Principle</li>
<li><a href="https://www.pluralsight.com/courses/refactoring-csharp-developers">Refactoring for C# Developers</a></li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 2 Sep 2019 06:00:05 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith)</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 55, on the Interface Segregation principle.</p>
<h1>Interface Segregation Principle</h1>
<p>This week's tip is brought to you by devBetter.com.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>You can find help and advice all over today, from twitter to Stack Overflow to various Slack communities. These are great, but if you need more, if you need someone you can count on when you reach out for advice on code or your career, check out devBetter.com. Read the testimonials. Join risk free and see if it's for you. Not only will you learn from me, but if you stay for a while you'll grow and begin to be a mentor for others, gaining valuable confidence and experience. I've watched it happen.</p>
<h2>Show Notes / Transcript</h2>
<p>Returning back to the next <a href="https://www.pluralsight.com/courses/csharp-solid-principles">SOLID principle</a>, this week we're on the I as in Interface. Yes, it's the Interface Segregation Principle! Or ISP for short. Let's start by defining what this principle says. ISP states that no client should be forced to depend on methods it does not use. That's it. You can think of ISP as basically suggesting that you should prefer small, cohesive interfaces to large interfaces. In episode 49, which hopefully you already heard because you're listening to these in sequential order, we talked about the Single Responsibility Principle. These two principles are related! If you have classes that have only one responsibility, they're likely to expose a small, cohesive interface.</p>
<p>That might be worth diving into a bit more. I'm guessing that when some developers, especially C# or Java developers, hear about ISP, they immediately map the word 'interface' to the interface type and keyword in these languages. That's not wrong, it's just not fully right, either. The public methods and properties a class exposes are its interface, even if it doesn't implement any interface defined separately. And ISP applies to implicit class interfaces just as much as it does to explicit interface definitions declared with the interface type. If you keep this in mind, it may make it easier to see how SRP and ISP relate, since SRP doesn't make any mention of interface types, only classes.</p>
<p>The previous principle we discussed, Liskov Substitution, also relates to ISP. If you have a small, cohesive interface on a class, then when you decide to inherit from it you only have a few methods to worry about. If you have a massive number of methods, and your subtype is only concerned with a subset of them, it's much more likely that you won't fully implement all of the class's methods, potentially leaving some methods to throw NotImplementedException. Thus, it's easier to follow LSP if you first follow ISP.</p>
<p>What's the point of having a smaller interface instead of a larger one, though? What's the down side to having fewer, larger classes with many methods on them? Certainly there's an argument to be made, and many have, that it makes it easier to find methods when you don't have so many different classes to search through to find them. The goal of ISP is to reduce dependency between types and especially between components in a system. The more types that depend on a particular type, the more difficult that type is to change. The more inertia it has in the system. If you have a class in your application that's used by 100 other classes, how likely are you to make major changes to its design, compared to one that you just wrote that has literally no other classes using it yet? Of course it's easier and WAY less risky to change classes that have few references to them.</p>
<p>Let's say you want to change something fundamental about how that class that's used by 100 other classes works. One way you could do that would be to create a new instance of that class's interface or abstract base class, but then you'd have to implement all of its methods. Odds are, there are a bunch of them. That's not going to be easy - so instead you might just add some more conditional logic to some of the methods. Maybe add a few more method parameters to some methods. Maybe add a couple of new method overloads. And guess what? The problem just got bigger. The class just got bigger. The inertia just grew.</p>
<p>By having a small interface and being focused on a small set of functionality, ISP-following classes are easier to change an easier to replace. By being small, they're easier to subtype or implement, making it easier to build systems that are modular. You find a class that has two methods and you want to change how it works in some situations? Just write a new class, implement the two methods, and swap it in where appropriate. <strong>Prefer writing new code to change legacy systems rather than modifying existing code.</strong> By following ISP, it's easier to replace classes with different variants that implement the same interface, which results in more loosely coupled and modular designs. These designs are easier to maintain and easier to test. You can learn more about ISP and the rest of the SOLID principles from my courses on Pluralsight, linked from this episode's show notes on <a href="/episodes/55">weeklydevtips.com/episodes/55</a>.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://www.pluralsight.com/courses/csharp-solid-principles">SOLID Principles for C# Developers</a></li>
<li><a href="https://www.pluralsight.com/courses/principles-oo-design">SOLID Principles of Object Oriented Design</a> -and the DRY Principle</li>
<li><a href="https://www.pluralsight.com/courses/refactoring-csharp-developers">Refactoring for C# Developers</a></li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="3380482" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/a483e44a-e472-4c5b-ae62-afb0d7fad1a8/055_interface_segregation_principle_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Interface Segregation</itunes:title>
      <itunes:author>Steve Smith</itunes:author>
      <itunes:duration>00:05:57</itunes:duration>
      <itunes:summary>This is episode 55, on the Interface Segregation principle, or ISP. ISP is the I in the SOLID Principles of object-oriented design.</itunes:summary>
      <itunes:subtitle>This is episode 55, on the Interface Segregation principle, or ISP. ISP is the I in the SOLID Principles of object-oriented design.</itunes:subtitle>
      <itunes:keywords>software development, dev, interface segregation principle, c#, clean code, java, programming, oop, tips, interface, solid</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>55</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">a8f68114-a7ad-4f87-8ca5-09b382e9990e</guid>
      <title>Customize Key Mappings in Visual Studio with Kendra Havens</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 54, on customizing key bindings in Visual Studio with guest Kendra Havens.</p>
<h1>Customize Key Mappings with Kendra Havens</h1>
<p>This week's tip is brought to you by devBetter.com.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>Need to level up your career? Looking for a mentor or a the support of some motivated, tech-savvy peers? devBetter is a group coaching program I started last year. We meet for weekly group Q&amp;A sessions and have an ongoing private Slack channel the rest of the week. I offer advice, networking opportunities, coding exercises, marketing and branding tips, and occasional assignments to help members improve. Interested? Check it out at <a href="https://devbetter.com/">devBetter.com</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>This week's guest tip is from Kendra Havens. Kendra is a program manager at Microsoft on the .NET and Visual Studio team, where she focuses on the Visual Studio testing experience and productivity tools. She does videos on .NET, VS Code, and Docker and is a frequent conference presenter as well. In fact, we last met up at a recent DevIntersection conference where we were both presenting, and I invited her to share a favorite tip on the podcast. The nature of describing a visual tool in a podcast is challenging, so I have a link to a video in the show notes if you want to follow up afterward.</p>
<p>Welcome, Kendra!</p>
<hr />
<p>Thanks, Kendra! I'll post <a href="https://channel9.msdn.com/Shows/Visual-Studio-Toolbox/Visual-Studio-Productivity-Tips#time=09m30s">a link to a video showing how to do this</a> in the show notes for anyone that wants to see it.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://twitter.com/gotheap">Kendra on Twitter</a></li>
<li><a href="https://channel9.msdn.com/Shows/Visual-Studio-Toolbox/Visual-Studio-Productivity-Tips#time=09m30s">Visual Studio Productivity Tips - Keyboard Command Mapping</a></li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 26 Aug 2019 06:00:19 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith, Kendra Havens)</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 54, on customizing key bindings in Visual Studio with guest Kendra Havens.</p>
<h1>Customize Key Mappings with Kendra Havens</h1>
<p>This week's tip is brought to you by devBetter.com.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>Need to level up your career? Looking for a mentor or a the support of some motivated, tech-savvy peers? devBetter is a group coaching program I started last year. We meet for weekly group Q&amp;A sessions and have an ongoing private Slack channel the rest of the week. I offer advice, networking opportunities, coding exercises, marketing and branding tips, and occasional assignments to help members improve. Interested? Check it out at <a href="https://devbetter.com/">devBetter.com</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>This week's guest tip is from Kendra Havens. Kendra is a program manager at Microsoft on the .NET and Visual Studio team, where she focuses on the Visual Studio testing experience and productivity tools. She does videos on .NET, VS Code, and Docker and is a frequent conference presenter as well. In fact, we last met up at a recent DevIntersection conference where we were both presenting, and I invited her to share a favorite tip on the podcast. The nature of describing a visual tool in a podcast is challenging, so I have a link to a video in the show notes if you want to follow up afterward.</p>
<p>Welcome, Kendra!</p>
<hr />
<p>Thanks, Kendra! I'll post <a href="https://channel9.msdn.com/Shows/Visual-Studio-Toolbox/Visual-Studio-Productivity-Tips#time=09m30s">a link to a video showing how to do this</a> in the show notes for anyone that wants to see it.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://twitter.com/gotheap">Kendra on Twitter</a></li>
<li><a href="https://channel9.msdn.com/Shows/Visual-Studio-Toolbox/Visual-Studio-Productivity-Tips#time=09m30s">Visual Studio Productivity Tips - Keyboard Command Mapping</a></li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="4008229" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/baf692d1-0fe2-4dc5-a84c-09e1a6df6cf5/054_customize_key_mappings_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Customize Key Mappings in Visual Studio with Kendra Havens</itunes:title>
      <itunes:author>Steve Smith, Kendra Havens</itunes:author>
      <itunes:duration>00:06:51</itunes:duration>
      <itunes:summary>Kendra Havens of Microsoft shares her favorite tip for mapping a common activity to a custom keyboard shortcut in Visual Studio.</itunes:summary>
      <itunes:subtitle>Kendra Havens of Microsoft shares her favorite tip for mapping a common activity to a custom keyboard shortcut in Visual Studio.</itunes:subtitle>
      <itunes:keywords>visual studio, tools, software development, tip, dev, microsoft, ide, programming</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>54</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">4b278c97-c06c-4d03-a14a-57b65a3c6118</guid>
      <title>Liskov Substitution</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 53, on the Liskov Substitution principle.</p>
<h1>Liskov Substitution Principle</h1>
<p>This week's tip is brought to you by devBetter.com.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>Need to level up your career? Looking for a mentor or a the support of some motivated, tech-savvy peers? devBetter is a group coaching program I started last year. We meet for weekly group Q&amp;A sessions and have an ongoing private Slack channel the rest of the week. I offer advice, networking opportunities, coding exercises, marketing and branding tips, and occasional assignments to help members improve. Interested? Check it out at <a href="https://devbetter.com/">devBetter.com</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>We're in the middle of the SOLID principles this week, with the only one who is named after an individual. The Liskov Substitution Principle is named for professor Barbara Liskov, who teaches computer science at MIT. She gave a conference keynote some years ago in which she defined substitutability in object-oriented systems, essentially stating that one type could be considered substitutable for another if there were no situations in which the original type worked but the new one did not. The typical definition used today is that subtypes should always be substitutable for their base types. If this isn't the case, it likely means you have the wrong inheritance relationship, or your interface isn't cohesive enough, or there is some other code smell you should consider addressing through refactoring.</p>
<p>So, although it isn't mentioned in the name, LSP is all about inheritance hierarchies. That's the first thing to remember. Many developers, myself included, learned about inheritance with the aid of the IS-A relationship. That is, you can consider using inheritance to model a problem if there are two related concepts and one IS-A more specific version of the other. You might have a Car class, with an SUV subclass. Or an Animal class with a Mammal subclass. These work because an SUV is a car and a mammal is an animal.</p>
<p>Sometimes, though, you might have an IS-A relationship, but it's not sufficient and it leads you down the wrong OO design path. The classic geometry examples involve squares and rectangles and circles and ellipses. A square is a rectangle; a circle is an ellipse. But take care if you try and use inheritance to model them, since depending on how you do so you could introduce breaking changes into your application. Imagine if you have applications using your Rectangle type that assume they can independently set the height and width of the rectangle. Then someone introduces the Square type that inherits from Rectangle and implements height and width properties so that setting either one will set the other, too. This ensure the resulting type is always a square. But it also means that a method that takes in a rectangle and modifies its height and width to different values will break, because the first value set will be silently overwritten by the second.</p>
<p>Another classic example involves birds. What if your base bird type includes methods like Fly and properties like Altitude? Then, someone introduces subtypes for Ostrich and Penguin. Trying to substitute these in to methods that expect certain behaviors from Fly and Altitude is likely to cause problems. The problem here is that the initial assumption that all birds can fly was inherently flawed.</p>
<p>In business software, we don't usually worry about birds or squares, but we often model things like policies, accounts, orders, etc. and often there are different varieties of these concepts. You'll know when you're violating LSP when you see code that shouldn't care about the specific variety of something, but has to run a type check to do its work properly. A method takes in an Account, and then checks to see if Account Is PremiumAccount, for instance. This signals an LSP violation, and can usually be corrected with a refactoring that shifts behavior up or down the inheritance tree. Pretty much the only place where you might have a conditional on the specific type of an instance of a class is in a factory method that's responsible for creating that specific type. Otherwise, the Replace Conditional with Polymorphism refactoring is your friend. Use it to eliminate excessive conditional logic from your code by making proper use of inheritance in your object model.</p>
<p>Obviously examples of these principles are tougher to describe in a podcast than in video, so to see them in action check out my courses on Pluralsight on the <a href="https://www.pluralsight.com/courses/csharp-solid-principles">SOLID principles</a>. I just produced a revised course for 2019, but <a href="https://www.pluralsight.com/courses/principles-oo-design">my original SOLID principles of object-oriented design course</a> is out there as well and uses different examples, so you might get benefit from seeing both of them. You'll find links to both in this episode's show notes.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://www.pluralsight.com/courses/csharp-solid-principles">SOLID Principles for C# Developers</a></li>
<li><a href="https://www.pluralsight.com/courses/principles-oo-design">SOLID Principles of Object Oriented Design</a> -and the DRY Principle</li>
<li><a href="https://www.pluralsight.com/courses/refactoring-fundamentals">Refactoring Fundamentals</a></li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 29 Jul 2019 06:00:18 +0000</pubDate>
      <author>steve@ardalis.com (Steve &quot;ardalis&quot; Smith)</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 53, on the Liskov Substitution principle.</p>
<h1>Liskov Substitution Principle</h1>
<p>This week's tip is brought to you by devBetter.com.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>Need to level up your career? Looking for a mentor or a the support of some motivated, tech-savvy peers? devBetter is a group coaching program I started last year. We meet for weekly group Q&amp;A sessions and have an ongoing private Slack channel the rest of the week. I offer advice, networking opportunities, coding exercises, marketing and branding tips, and occasional assignments to help members improve. Interested? Check it out at <a href="https://devbetter.com/">devBetter.com</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>We're in the middle of the SOLID principles this week, with the only one who is named after an individual. The Liskov Substitution Principle is named for professor Barbara Liskov, who teaches computer science at MIT. She gave a conference keynote some years ago in which she defined substitutability in object-oriented systems, essentially stating that one type could be considered substitutable for another if there were no situations in which the original type worked but the new one did not. The typical definition used today is that subtypes should always be substitutable for their base types. If this isn't the case, it likely means you have the wrong inheritance relationship, or your interface isn't cohesive enough, or there is some other code smell you should consider addressing through refactoring.</p>
<p>So, although it isn't mentioned in the name, LSP is all about inheritance hierarchies. That's the first thing to remember. Many developers, myself included, learned about inheritance with the aid of the IS-A relationship. That is, you can consider using inheritance to model a problem if there are two related concepts and one IS-A more specific version of the other. You might have a Car class, with an SUV subclass. Or an Animal class with a Mammal subclass. These work because an SUV is a car and a mammal is an animal.</p>
<p>Sometimes, though, you might have an IS-A relationship, but it's not sufficient and it leads you down the wrong OO design path. The classic geometry examples involve squares and rectangles and circles and ellipses. A square is a rectangle; a circle is an ellipse. But take care if you try and use inheritance to model them, since depending on how you do so you could introduce breaking changes into your application. Imagine if you have applications using your Rectangle type that assume they can independently set the height and width of the rectangle. Then someone introduces the Square type that inherits from Rectangle and implements height and width properties so that setting either one will set the other, too. This ensure the resulting type is always a square. But it also means that a method that takes in a rectangle and modifies its height and width to different values will break, because the first value set will be silently overwritten by the second.</p>
<p>Another classic example involves birds. What if your base bird type includes methods like Fly and properties like Altitude? Then, someone introduces subtypes for Ostrich and Penguin. Trying to substitute these in to methods that expect certain behaviors from Fly and Altitude is likely to cause problems. The problem here is that the initial assumption that all birds can fly was inherently flawed.</p>
<p>In business software, we don't usually worry about birds or squares, but we often model things like policies, accounts, orders, etc. and often there are different varieties of these concepts. You'll know when you're violating LSP when you see code that shouldn't care about the specific variety of something, but has to run a type check to do its work properly. A method takes in an Account, and then checks to see if Account Is PremiumAccount, for instance. This signals an LSP violation, and can usually be corrected with a refactoring that shifts behavior up or down the inheritance tree. Pretty much the only place where you might have a conditional on the specific type of an instance of a class is in a factory method that's responsible for creating that specific type. Otherwise, the Replace Conditional with Polymorphism refactoring is your friend. Use it to eliminate excessive conditional logic from your code by making proper use of inheritance in your object model.</p>
<p>Obviously examples of these principles are tougher to describe in a podcast than in video, so to see them in action check out my courses on Pluralsight on the <a href="https://www.pluralsight.com/courses/csharp-solid-principles">SOLID principles</a>. I just produced a revised course for 2019, but <a href="https://www.pluralsight.com/courses/principles-oo-design">my original SOLID principles of object-oriented design course</a> is out there as well and uses different examples, so you might get benefit from seeing both of them. You'll find links to both in this episode's show notes.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://www.pluralsight.com/courses/csharp-solid-principles">SOLID Principles for C# Developers</a></li>
<li><a href="https://www.pluralsight.com/courses/principles-oo-design">SOLID Principles of Object Oriented Design</a> -and the DRY Principle</li>
<li><a href="https://www.pluralsight.com/courses/refactoring-fundamentals">Refactoring Fundamentals</a></li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="3418025" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/0b9ba8df-3c51-4a8a-ad3f-5f8c3a93d378/053_liskovsubstitution_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Liskov Substitution</itunes:title>
      <itunes:author>Steve &quot;ardalis&quot; Smith</itunes:author>
      <itunes:duration>00:05:41</itunes:duration>
      <itunes:summary>This is episode 53, on the Liskov Substitution principle. The typical definition used today is that subtypes should always be substitutable for their base types. If this isn&apos;t the case, it likely means you have the wrong inheritance relationship, or your interface isn&apos;t cohesive enough, or there is some other code smell you should consider addressing through refactoring.</itunes:summary>
      <itunes:subtitle>This is episode 53, on the Liskov Substitution principle. The typical definition used today is that subtypes should always be substitutable for their base types. If this isn&apos;t the case, it likely means you have the wrong inheritance relationship, or your interface isn&apos;t cohesive enough, or there is some other code smell you should consider addressing through refactoring.</itunes:subtitle>
      <itunes:keywords>principle, dev, liskov, inheritance, c#, clean code, software developemnt, java, programming, solid principles, object oriented programming, oop, solid</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>53</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">25d487b4-b9a6-4b4c-a0fc-500d439d1a5b</guid>
      <title>Continuous Testing Continuously with Guest Al Rodriguez</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 52, on feedback loops and continuous testing with guest Al Rodriguez.</p>
<h1>Continuous Testing Continuously</h1>
<p>This week's tip is brought to you by devBetter.com.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>Need to level up your career? Looking for a mentor or a the support of some motivated, tech-savvy peers? devBetter is a group coaching program I started last year. We meet for weekly group Q&amp;A sessions and have an ongoing private Slack channel the rest of the week. I offer advice, networking opportunities, coding exercises, marketing and branding tips, and occasional assignments to help members improve. Interested? Check it out at <a href="https://devbetter.com/">devBetter.com</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>This week's tip is on how to be more productive by reducing feedback loops. Our guest is Al Rodriguez. Al is a multiclassing wizard spending most of his time using .NET wherever possible but levels up in other tools to get the job done. Take it away, Al:</p>
<p>Hi. I'm Al Rodriguez and I'm here to talk to you about Continuous Testing.</p>
<p>One way to improve development productivity is to reduce the time of your feedback loop.</p>
<p>A classic example of this is application startup time to validate a UI change.<br />
A 3 minute wait for an application to build and startup feels like an eternity when you've only changed a background color.<br />
This is why some tools exist to hot reload only the part of the application that has changed. Thus reducing the time that you, a busy developer, have to wait.<br />
We see tools like this all over the development space to reduce the feedback loop time.</p>
<p>One example is inside our Text Editors. If you miss a semicolon or misspell a variable name, you immediately get feedback in the form of a red squiggly underline.<br />
Another example of this is a Continuous Integration pipeline. Once you check code in, a pipeline is invoked to build your application, run any tests it needs to, and alert the team if there are any issues.<br />
All three of these examples I've mentioned have wildly different feedback times because they're for very different types of tasks.</p>
<p>But lets move on and talk about unit tests.<br />
The common loop I see when working with unit tests is to write the test, then click the button to run it.</p>
<p>It's a very manual process.<br />
The feedback loop there is usually a couple of seconds. Short and sweet.<br />
As time goes on you'll change some code and eventually click the button to run the tests again.<br />
But which tests? All of them? One class at a time? The individual tests you think are impacted by your changes?<br />
Even worse, what happens if you forget to run the tests?<br />
Now you're checking code into source control that hasn't been fully tested.<br />
What does the feedback loop look like in that situation?</p>
<p>Best case scenario, the tests are run after a few changes are made.<br />
Worst case scenario, they're not even run.<br />
And that's just you. There's also the scenario of people on your team who don't think to run the tests.<br />
On a project with historically low, or no, tests, the idea of running them doesn't cross your mind because it's not part of the normal flow. So new code could have broken the tests, and since they weren't run, no one will find out for a what may be a few weeks.<br />
That's fun and all. But you know what's better? What can reduce that feedback loop?</p>
<p>What you said is right, sure,<br />
but the answer I was looking for is: Not clicking the button. Or more<br />
accurately, not having to click the button. Having a tool that will run<br />
your tests for you.<br />
Continuous Testing is when you have a tool to run your tests as soon as the they are created, changed, or any code impacted by a test has been changed.</p>
<p>And if that's not continuous, I don't know what is. Which would be a problem. So if that's not what Continuous means, please let me know. I can't have another situation where I go years using a word wrong. That would be unfortuitous.<br />
Other benefits of Continuous Testing tools include a UI element to show the current state of the code under test.</p>
<p>For example, when looking at your code there is a visual indicator inside your IDE to show you each line of code that has any failing tests, or if there are no tests for that line. Which is a great reminder that you need to write those tests.<br />
If you want to get started with Continuous Testing there are several options depending on your choice of tooling.<br />
In the .NET space you can use the Live Testing feature built-in to Visual Studio Enterprise.</p>
<p>If you don't have an Enterprise license, another great tool is NCrunch. You can only get <a href="https://www.ncrunch.net/download">NCrunch</a> by purchasing a license, but it's cheaper than upgrading to Visual Studio Enterprise. Which is the reason I use it for my own personal projects.<br />
Finally, if you're working with .NET Core you can use the dotnet CLI command: dotnet watch test<br />
The watch command listens for file changes. Once a file has changed, the test command is run on that folder.<br />
Note that this isn't as efficient as the previous tools because it re-runs all of the tests, not just the ones that have related changes.<br />
If you're in the<br />
javascript realm you can do something similar with npm's watch package. Using<br />
the command npm run test --watch will continually run your test task whenever<br />
files change just like we saw with dotnet.</p>
<p>In summary, do what you can to reduce your feedback loop with automated tests.</p>
<p>And that's all I have to say on this topic.</p>
<p>If you'd like, you can find me on twitter under the handle <a href="https://twitter.com/programmeral">@ProgrammerAl, that's P-R-O-G-R-A-M-M-E-R-A-L</a>.<br />
Or you can find me interviewing people on their side projects on the Developer Side Quests podcast.</p>
<p>Now go forth and forget where that Run Tests button is. Or even better, remove it from your IDE if that's an option.</p>
<p>Thanks for letting me ramble on your show Steve. Back to you!</p>
<p>Thanks, Al! Great tips! It's great that CLI tools make it so easy to set up this continuous feedback loop, even for developers who don't have access to great commercial tools like VS Enterprise and NCrunch. I hope a few listeners will give continuous testing a try, and if they have any questions or feedback, leave it on the show's page at <a href="https://weeklydevtips.com/episodes/52">weeklydevtips.com/episodes/52</a>. I've also added links to the resources covered this week.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://www.ncrunch.net/download">NCrunch</a></li>
<li><a href="https://twitter.com/programmeral">Al on Twitter</a></li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 22 Jul 2019 06:00:02 +0000</pubDate>
      <author>steve@ardalis.com (Al Rodriguez)</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 52, on feedback loops and continuous testing with guest Al Rodriguez.</p>
<h1>Continuous Testing Continuously</h1>
<p>This week's tip is brought to you by devBetter.com.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>Need to level up your career? Looking for a mentor or a the support of some motivated, tech-savvy peers? devBetter is a group coaching program I started last year. We meet for weekly group Q&amp;A sessions and have an ongoing private Slack channel the rest of the week. I offer advice, networking opportunities, coding exercises, marketing and branding tips, and occasional assignments to help members improve. Interested? Check it out at <a href="https://devbetter.com/">devBetter.com</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>This week's tip is on how to be more productive by reducing feedback loops. Our guest is Al Rodriguez. Al is a multiclassing wizard spending most of his time using .NET wherever possible but levels up in other tools to get the job done. Take it away, Al:</p>
<p>Hi. I'm Al Rodriguez and I'm here to talk to you about Continuous Testing.</p>
<p>One way to improve development productivity is to reduce the time of your feedback loop.</p>
<p>A classic example of this is application startup time to validate a UI change.<br />
A 3 minute wait for an application to build and startup feels like an eternity when you've only changed a background color.<br />
This is why some tools exist to hot reload only the part of the application that has changed. Thus reducing the time that you, a busy developer, have to wait.<br />
We see tools like this all over the development space to reduce the feedback loop time.</p>
<p>One example is inside our Text Editors. If you miss a semicolon or misspell a variable name, you immediately get feedback in the form of a red squiggly underline.<br />
Another example of this is a Continuous Integration pipeline. Once you check code in, a pipeline is invoked to build your application, run any tests it needs to, and alert the team if there are any issues.<br />
All three of these examples I've mentioned have wildly different feedback times because they're for very different types of tasks.</p>
<p>But lets move on and talk about unit tests.<br />
The common loop I see when working with unit tests is to write the test, then click the button to run it.</p>
<p>It's a very manual process.<br />
The feedback loop there is usually a couple of seconds. Short and sweet.<br />
As time goes on you'll change some code and eventually click the button to run the tests again.<br />
But which tests? All of them? One class at a time? The individual tests you think are impacted by your changes?<br />
Even worse, what happens if you forget to run the tests?<br />
Now you're checking code into source control that hasn't been fully tested.<br />
What does the feedback loop look like in that situation?</p>
<p>Best case scenario, the tests are run after a few changes are made.<br />
Worst case scenario, they're not even run.<br />
And that's just you. There's also the scenario of people on your team who don't think to run the tests.<br />
On a project with historically low, or no, tests, the idea of running them doesn't cross your mind because it's not part of the normal flow. So new code could have broken the tests, and since they weren't run, no one will find out for a what may be a few weeks.<br />
That's fun and all. But you know what's better? What can reduce that feedback loop?</p>
<p>What you said is right, sure,<br />
but the answer I was looking for is: Not clicking the button. Or more<br />
accurately, not having to click the button. Having a tool that will run<br />
your tests for you.<br />
Continuous Testing is when you have a tool to run your tests as soon as the they are created, changed, or any code impacted by a test has been changed.</p>
<p>And if that's not continuous, I don't know what is. Which would be a problem. So if that's not what Continuous means, please let me know. I can't have another situation where I go years using a word wrong. That would be unfortuitous.<br />
Other benefits of Continuous Testing tools include a UI element to show the current state of the code under test.</p>
<p>For example, when looking at your code there is a visual indicator inside your IDE to show you each line of code that has any failing tests, or if there are no tests for that line. Which is a great reminder that you need to write those tests.<br />
If you want to get started with Continuous Testing there are several options depending on your choice of tooling.<br />
In the .NET space you can use the Live Testing feature built-in to Visual Studio Enterprise.</p>
<p>If you don't have an Enterprise license, another great tool is NCrunch. You can only get <a href="https://www.ncrunch.net/download">NCrunch</a> by purchasing a license, but it's cheaper than upgrading to Visual Studio Enterprise. Which is the reason I use it for my own personal projects.<br />
Finally, if you're working with .NET Core you can use the dotnet CLI command: dotnet watch test<br />
The watch command listens for file changes. Once a file has changed, the test command is run on that folder.<br />
Note that this isn't as efficient as the previous tools because it re-runs all of the tests, not just the ones that have related changes.<br />
If you're in the<br />
javascript realm you can do something similar with npm's watch package. Using<br />
the command npm run test --watch will continually run your test task whenever<br />
files change just like we saw with dotnet.</p>
<p>In summary, do what you can to reduce your feedback loop with automated tests.</p>
<p>And that's all I have to say on this topic.</p>
<p>If you'd like, you can find me on twitter under the handle <a href="https://twitter.com/programmeral">@ProgrammerAl, that's P-R-O-G-R-A-M-M-E-R-A-L</a>.<br />
Or you can find me interviewing people on their side projects on the Developer Side Quests podcast.</p>
<p>Now go forth and forget where that Run Tests button is. Or even better, remove it from your IDE if that's an option.</p>
<p>Thanks for letting me ramble on your show Steve. Back to you!</p>
<p>Thanks, Al! Great tips! It's great that CLI tools make it so easy to set up this continuous feedback loop, even for developers who don't have access to great commercial tools like VS Enterprise and NCrunch. I hope a few listeners will give continuous testing a try, and if they have any questions or feedback, leave it on the show's page at <a href="https://weeklydevtips.com/episodes/52">weeklydevtips.com/episodes/52</a>. I've also added links to the resources covered this week.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://www.ncrunch.net/download">NCrunch</a></li>
<li><a href="https://twitter.com/programmeral">Al on Twitter</a></li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="4043831" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/59bd5dcc-0017-42bb-966e-dec01d1ccdaf/052_continuoustesting_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Continuous Testing Continuously with Guest Al Rodriguez</itunes:title>
      <itunes:author>Al Rodriguez</itunes:author>
      <itunes:duration>00:06:42</itunes:duration>
      <itunes:summary>This week&apos;s tip is on how to be more productive by reducing feedback loops with continuous testing. Our guest is Al Rodriguez. Al is a multiclassing wizard spending most of his time using .NET wherever possible but levels up in other tools to get the job done.</itunes:summary>
      <itunes:subtitle>This week&apos;s tip is on how to be more productive by reducing feedback loops with continuous testing. Our guest is Al Rodriguez. Al is a multiclassing wizard spending most of his time using .NET wherever possible but levels up in other tools to get the job done.</itunes:subtitle>
      <itunes:keywords>unit testing, visual studio, ci, software development, ci/cd, npm, coding, programming, tdd, testing, ncrunch, continuous integration, code</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>52</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">70e2fc3d-a25e-45f5-a040-07ab79a23bf4</guid>
      <title>Open Closed</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 51, on the Open/Closed principle.</p>
<h1>Open/Closed Principle</h1>
<p>This week's tip is brought to you by devBetter.com.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>Need to level up your career? Looking for a mentor or a the support of some motivated, tech-savvy peers? devBetter is a group coaching program I started last year. We meet for weekly group Q&amp;A sessions and have an ongoing private Slack channel the rest of the week. I offer advice, networking opportunities, coding exercises, marketing and branding tips, and occasional assignments to help members improve. Interested? Check it out at <a href="https://devbetter.com/">devBetter.com</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>My goal is to have every other tip for the next few weeks focus on one of the SOLID principles. If you're listening in order, which I recommend, you'll note that episode 49 was on Single Responsibility. Thus, here we are with episode 51, talking about the O in SOLID, the <a href="https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle">Open/Closed Principle</a>.</p>
<p>The name of this principle is somewhat oxymoronic. It sometimes reminds me of the classic Star Wars scene where the stormtroopers are chasing Han Solo, yelling &quot;close the blast doors, close the blast doors!&quot; only to find themselves blocked by the doors moments later, crying &quot;open the blast doors, open the blast doors!&quot; What does the principle of being both open and closed mean, really?</p>
<p>The full principle says that software entities (no, not <em>those</em> entities - we mean classes, modules, functions, etc. here) should be open for extension but closed for modification. Ok, so what does each of these mean?</p>
<p>Open for extension means that it's possible to add to the behavior of the class or method. We can make it do new or different things.</p>
<p>Closed for modification means that the class or method itself should not be changed. Imagine that it's inside of a nuget package or its source is otherwise unavailable to modify.</p>
<p>If we think about open for extension all by itself, it's a pretty easy one. It's saying some class or method should be open to changes in how it works. We do that all the time. We need to fix a bug or add a feature, we find where the code is that does that work, and we add a few lines to change the behavior. Often this just means adding an if statement or something similar, to account for the new behavior required. This is the typical, obvious way to add behavior to our systems, and generally there's nothing wrong with this approach. But it doesn't follow the open/closed principle, because such code is clearly not closed for modification.</p>
<p>Now imagine that the code with the behavior you need to modify is not available to you to edit. How might you change its behavior, then? This might sound like a trick or impossible question, but we do this all the time, too. You change the behavior of classes and functions by changing their inputs. Passing in arguments or modifying data accessed by the class or method, such as configuration files or data stores, are all examples of ways in which you can modify system behavior without modifying source code. And there are some parts of your application that will benefit from being closed to modification, especially the parts that are depended on the most. By following OCP for your most fundamental classes, you'll make changes to them far more rare, which in turn will result in far fewer issues downstream due to updates to them.</p>
<p>If you'd like to learn more about OCP, check out my courses on Pluralsight on the <a href="https://www.pluralsight.com/courses/csharp-solid-principles">SOLID principles</a>. I just produced a revised course for 2019, but <a href="https://www.pluralsight.com/courses/principles-oo-design">my original SOLID principles of object-oriented design course</a> is out there as well and uses different examples, so you might get benefit from seeing both of them. You'll find links to both in this episode's show notes.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://www.pluralsight.com/courses/csharp-solid-principles">SOLID Principles for C# Developers</a></li>
<li><a href="https://www.pluralsight.com/courses/principles-oo-design">SOLID Principles of Object Oriented Design</a> -and the DRY Principle</li>
<li><a href="https://www.pluralsight.com/courses/refactoring-fundamentals">Refactoring Fundamentals</a></li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 10 Jun 2019 04:05:05 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 51, on the Open/Closed principle.</p>
<h1>Open/Closed Principle</h1>
<p>This week's tip is brought to you by devBetter.com.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>Need to level up your career? Looking for a mentor or a the support of some motivated, tech-savvy peers? devBetter is a group coaching program I started last year. We meet for weekly group Q&amp;A sessions and have an ongoing private Slack channel the rest of the week. I offer advice, networking opportunities, coding exercises, marketing and branding tips, and occasional assignments to help members improve. Interested? Check it out at <a href="https://devbetter.com/">devBetter.com</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>My goal is to have every other tip for the next few weeks focus on one of the SOLID principles. If you're listening in order, which I recommend, you'll note that episode 49 was on Single Responsibility. Thus, here we are with episode 51, talking about the O in SOLID, the <a href="https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle">Open/Closed Principle</a>.</p>
<p>The name of this principle is somewhat oxymoronic. It sometimes reminds me of the classic Star Wars scene where the stormtroopers are chasing Han Solo, yelling &quot;close the blast doors, close the blast doors!&quot; only to find themselves blocked by the doors moments later, crying &quot;open the blast doors, open the blast doors!&quot; What does the principle of being both open and closed mean, really?</p>
<p>The full principle says that software entities (no, not <em>those</em> entities - we mean classes, modules, functions, etc. here) should be open for extension but closed for modification. Ok, so what does each of these mean?</p>
<p>Open for extension means that it's possible to add to the behavior of the class or method. We can make it do new or different things.</p>
<p>Closed for modification means that the class or method itself should not be changed. Imagine that it's inside of a nuget package or its source is otherwise unavailable to modify.</p>
<p>If we think about open for extension all by itself, it's a pretty easy one. It's saying some class or method should be open to changes in how it works. We do that all the time. We need to fix a bug or add a feature, we find where the code is that does that work, and we add a few lines to change the behavior. Often this just means adding an if statement or something similar, to account for the new behavior required. This is the typical, obvious way to add behavior to our systems, and generally there's nothing wrong with this approach. But it doesn't follow the open/closed principle, because such code is clearly not closed for modification.</p>
<p>Now imagine that the code with the behavior you need to modify is not available to you to edit. How might you change its behavior, then? This might sound like a trick or impossible question, but we do this all the time, too. You change the behavior of classes and functions by changing their inputs. Passing in arguments or modifying data accessed by the class or method, such as configuration files or data stores, are all examples of ways in which you can modify system behavior without modifying source code. And there are some parts of your application that will benefit from being closed to modification, especially the parts that are depended on the most. By following OCP for your most fundamental classes, you'll make changes to them far more rare, which in turn will result in far fewer issues downstream due to updates to them.</p>
<p>If you'd like to learn more about OCP, check out my courses on Pluralsight on the <a href="https://www.pluralsight.com/courses/csharp-solid-principles">SOLID principles</a>. I just produced a revised course for 2019, but <a href="https://www.pluralsight.com/courses/principles-oo-design">my original SOLID principles of object-oriented design course</a> is out there as well and uses different examples, so you might get benefit from seeing both of them. You'll find links to both in this episode's show notes.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://www.pluralsight.com/courses/csharp-solid-principles">SOLID Principles for C# Developers</a></li>
<li><a href="https://www.pluralsight.com/courses/principles-oo-design">SOLID Principles of Object Oriented Design</a> -and the DRY Principle</li>
<li><a href="https://www.pluralsight.com/courses/refactoring-fundamentals">Refactoring Fundamentals</a></li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="2844858" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/06391e46-7dde-4f23-99de-fc51cdbc524c/051_Open_Closed_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Open Closed</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:duration>00:04:54</itunes:duration>
      <itunes:summary>This is episode 51, on the Open/Closed principle.</itunes:summary>
      <itunes:subtitle>This is episode 51, on the Open/Closed principle.</itunes:subtitle>
      <itunes:keywords>open closed principle, software development, software engineering, open closed, .net, dev, coding, c#, clean code, java, programming, oop, principles, solid</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>51</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">1fd8f82b-d3e1-467d-83c5-f7afb8409c02</guid>
      <title>Test All The Things with Guest Corey Weathers</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 50 with some guest tips on Testing All The Things!</p>
<h1>Test All The Things</h1>
<p>This week's tip is brought to you by devBetter.com.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>Are you a software developer looking to advance in your career more quickly? Would you find a mentor and a group of like-minded professionals valuable? If so, check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page. Sign up for a risk free membership if you're interested in growing your network and skills with us.</p>
<h2>Show Notes / Transcript</h2>
<p>I'm glad to have a new guest offering some tips. Corey Weathers of <a href="https://twilio.com/">Twilio</a> is going to offer his perspective on the importance of software testing. Corey loves .NET and has worked for companies including Microsoft and the US federal government before joining Twilio as a developer evangelist. He works to inspire and equip .NET developer, underrepresented developers, and the Twitch community of developers with the tools they need to build the future of communications.</p>
<p>Welcome, Corey!</p>
<hr />
<p>My name is Corey Weathers and I have the privilege and pleasure of being a .NET developer evangelist for a great company named Twilio. I’d like to start this week by saying a big thank you to Steve for inviting me on the Weekly Dev Tips podcast. This week I’d like to talk about something very near and dear to my heart as a developer – software testing.</p>
<h2>WHY TEST</h2>
<p>Now you may be wondering why testing. After being a developer for a number of years, I have found the following things to happen pretty consistently – someone usually has a problem and says “hey a developer can fix that”. Hopefully they’ve checked in with a software developer before making that assumption, but that’s not often the case. It’s usually problems like these that turn into use cases, user stories, or requirements.</p>
<p>As product development happens, it can also be the case that these stories become more specific, nuanced, and refined in scope. When that happens, it’s not unusual to see more user stories created to cover the new scope that was removed from existing stories. What you end up with is one problem that a developer can fix turning into an ever-expanding list of user stories that become very complicated.</p>
<p>Now when we start writing the code for one use case, and more show up, we continue writing more and more code to meet the ever expanding list of requirements and after this, we miss the opportunities to validate the code that we’re building.</p>
<h2>WHAT DOES TESTING DO</h2>
<p>So one of the first mantras to remember here is – TEST EARLY.<br />
Why? Because when you start early, you get to check one box that is super important – that is, you’re making sure that you’re building the right thing. This allows you to clarify your assumptions and confirm the suspicions you may have but that haven’t already been identified and figured out.</p>
<p>Which leads me to the second mantra – TEST OFTEN.<br />
If Test Early ensures that you’re building the right thing, Test Often makes sure that you’re building the thing right. By making your code testable, you’ve added so much to your code base: maintainability, a measure of quality, and confidence in that things will work as you’ve both built and expected them to.</p>
<h2>WHERE DO I START</h2>
<p>At this point you may be wondering, ok well where do I start? And I realize a number of you may be coming from different starting points. Some of you may be at the very beginning and haven’t written a single line of code; whereas others of you may have an application deploying into a production environment that has poor test coverage. I know that it can be tough to get started.</p>
<p>Hopefully this piece of advice should be relevant for you no matter where you’re starting from. My third and final mantra is START SIMPLE</p>
<p>Let’s use an example here. For our conversation – let’s assume we have an application that has a user interface, and this user interfaces connects to an API that takes some data and saves it in a database.</p>
<p>Assuming everything works as expected, you can start by writing a test for each part of this sequence. So one test can reproduce what happens when you click on the button when rendering the UI; a second test can simulate what happens when the UI calls the API; a third test can confirm that the database actually saved the data; and a final test can simulate all of the steps here by testing this one action with an API and database that looks close to what it will be in the real world. We could probably have an entire conversation as well about making sure you test setting up your application, but if you’re just getting started with testing there’s no need to start there.</p>
<h2>WHAT DO I DO WITH ALL OF THE TESTS</h2>
<p>With this suite of tests, you now have 4 tests that you can very easily expand on. You’ve started by testing the simplest path forward and can now add different modifications to this path, like what happens when my computer isn’t connected to the internet and my UI can’t talk to the API.</p>
<p>Now here’s where we reach the inevitable – well if I’m just starting out with writing tests and something doesn’t pass as I expect it to, what do I do? Here is where I usually say – this is a good thing. Your test is starting to work. Think about it for a second. If you start writing tests and they start making you ask questions about how your test is working, then you’ll probably end up changing your test a bit so that this question focuses more on your application. This is a win because you’ll learn how to write better tests in the process.</p>
<p>Alternatively, if you start writing tests and they make you question how your application is working, this is a win because it’s forcing you to make sure your application is meeting its intended need AND is testable as it is doing so. So write more tests, look for their results, and respond when the results don’t match what you expect.</p>
<h2>CALL TO ACTION</h2>
<p>That’s it from me this week friends. Remember TEST EARLY, TEST OFTEN, AND START SIMPLE. If you are interested in following up on testing, take a look at the Art of Unit Testing, written by Roy Osherove. He’s built an amazing body of content to help describe some of the why and how to begin testing. If you’d like to follow up with me, feel free to email me at corey@twilio.com. That’s C-O-R-E-Y@T-W-I-L-I-O.COM. That’s it from me this week. I’ll pass it back to Steve.</p>
<hr />
<p>Great stuff, Corey! Thanks for sharing with everyone. <a href="https://amzn.to/2MqGf6p">Art of Unit Testing</a> is definitely a good book - I'll post a link in the show notes.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://amzn.to/2MqGf6p">Art of Unit Testing</a> by Roy Osherove</li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 3 Jun 2019 14:59:21 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 50 with some guest tips on Testing All The Things!</p>
<h1>Test All The Things</h1>
<p>This week's tip is brought to you by devBetter.com.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>Are you a software developer looking to advance in your career more quickly? Would you find a mentor and a group of like-minded professionals valuable? If so, check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page. Sign up for a risk free membership if you're interested in growing your network and skills with us.</p>
<h2>Show Notes / Transcript</h2>
<p>I'm glad to have a new guest offering some tips. Corey Weathers of <a href="https://twilio.com/">Twilio</a> is going to offer his perspective on the importance of software testing. Corey loves .NET and has worked for companies including Microsoft and the US federal government before joining Twilio as a developer evangelist. He works to inspire and equip .NET developer, underrepresented developers, and the Twitch community of developers with the tools they need to build the future of communications.</p>
<p>Welcome, Corey!</p>
<hr />
<p>My name is Corey Weathers and I have the privilege and pleasure of being a .NET developer evangelist for a great company named Twilio. I’d like to start this week by saying a big thank you to Steve for inviting me on the Weekly Dev Tips podcast. This week I’d like to talk about something very near and dear to my heart as a developer – software testing.</p>
<h2>WHY TEST</h2>
<p>Now you may be wondering why testing. After being a developer for a number of years, I have found the following things to happen pretty consistently – someone usually has a problem and says “hey a developer can fix that”. Hopefully they’ve checked in with a software developer before making that assumption, but that’s not often the case. It’s usually problems like these that turn into use cases, user stories, or requirements.</p>
<p>As product development happens, it can also be the case that these stories become more specific, nuanced, and refined in scope. When that happens, it’s not unusual to see more user stories created to cover the new scope that was removed from existing stories. What you end up with is one problem that a developer can fix turning into an ever-expanding list of user stories that become very complicated.</p>
<p>Now when we start writing the code for one use case, and more show up, we continue writing more and more code to meet the ever expanding list of requirements and after this, we miss the opportunities to validate the code that we’re building.</p>
<h2>WHAT DOES TESTING DO</h2>
<p>So one of the first mantras to remember here is – TEST EARLY.<br />
Why? Because when you start early, you get to check one box that is super important – that is, you’re making sure that you’re building the right thing. This allows you to clarify your assumptions and confirm the suspicions you may have but that haven’t already been identified and figured out.</p>
<p>Which leads me to the second mantra – TEST OFTEN.<br />
If Test Early ensures that you’re building the right thing, Test Often makes sure that you’re building the thing right. By making your code testable, you’ve added so much to your code base: maintainability, a measure of quality, and confidence in that things will work as you’ve both built and expected them to.</p>
<h2>WHERE DO I START</h2>
<p>At this point you may be wondering, ok well where do I start? And I realize a number of you may be coming from different starting points. Some of you may be at the very beginning and haven’t written a single line of code; whereas others of you may have an application deploying into a production environment that has poor test coverage. I know that it can be tough to get started.</p>
<p>Hopefully this piece of advice should be relevant for you no matter where you’re starting from. My third and final mantra is START SIMPLE</p>
<p>Let’s use an example here. For our conversation – let’s assume we have an application that has a user interface, and this user interfaces connects to an API that takes some data and saves it in a database.</p>
<p>Assuming everything works as expected, you can start by writing a test for each part of this sequence. So one test can reproduce what happens when you click on the button when rendering the UI; a second test can simulate what happens when the UI calls the API; a third test can confirm that the database actually saved the data; and a final test can simulate all of the steps here by testing this one action with an API and database that looks close to what it will be in the real world. We could probably have an entire conversation as well about making sure you test setting up your application, but if you’re just getting started with testing there’s no need to start there.</p>
<h2>WHAT DO I DO WITH ALL OF THE TESTS</h2>
<p>With this suite of tests, you now have 4 tests that you can very easily expand on. You’ve started by testing the simplest path forward and can now add different modifications to this path, like what happens when my computer isn’t connected to the internet and my UI can’t talk to the API.</p>
<p>Now here’s where we reach the inevitable – well if I’m just starting out with writing tests and something doesn’t pass as I expect it to, what do I do? Here is where I usually say – this is a good thing. Your test is starting to work. Think about it for a second. If you start writing tests and they start making you ask questions about how your test is working, then you’ll probably end up changing your test a bit so that this question focuses more on your application. This is a win because you’ll learn how to write better tests in the process.</p>
<p>Alternatively, if you start writing tests and they make you question how your application is working, this is a win because it’s forcing you to make sure your application is meeting its intended need AND is testable as it is doing so. So write more tests, look for their results, and respond when the results don’t match what you expect.</p>
<h2>CALL TO ACTION</h2>
<p>That’s it from me this week friends. Remember TEST EARLY, TEST OFTEN, AND START SIMPLE. If you are interested in following up on testing, take a look at the Art of Unit Testing, written by Roy Osherove. He’s built an amazing body of content to help describe some of the why and how to begin testing. If you’d like to follow up with me, feel free to email me at corey@twilio.com. That’s C-O-R-E-Y@T-W-I-L-I-O.COM. That’s it from me this week. I’ll pass it back to Steve.</p>
<hr />
<p>Great stuff, Corey! Thanks for sharing with everyone. <a href="https://amzn.to/2MqGf6p">Art of Unit Testing</a> is definitely a good book - I'll post a link in the show notes.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://amzn.to/2MqGf6p">Art of Unit Testing</a> by Roy Osherove</li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="4279681" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/cfce7405-ca78-49af-aca2-aeed5683a3c7/050_Test_All_The_Things_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Test All The Things with Guest Corey Weathers</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:duration>00:07:20</itunes:duration>
      <itunes:summary>I&apos;m glad to have a new guest offering some tips. Corey Weathers of [Twilio](https://twilio.com/) is going to offer his perspective on the importance of software testing. Corey loves .NET and has worked for companies including Microsoft and the US federal government before joining Twilio as a developer evangelist. He works to inspire and equip .NET developer, underrepresented developers, and the Twitch community of developers with the tools they need to build the future of communications.</itunes:summary>
      <itunes:subtitle>I&apos;m glad to have a new guest offering some tips. Corey Weathers of [Twilio](https://twilio.com/) is going to offer his perspective on the importance of software testing. Corey loves .NET and has worked for companies including Microsoft and the US federal government before joining Twilio as a developer evangelist. He works to inspire and equip .NET developer, underrepresented developers, and the Twitch community of developers with the tools they need to build the future of communications.</itunes:subtitle>
      <itunes:keywords>software development, software quality, dev, coding, clean code, tdd, testing</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>50</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">65474acb-c323-4b64-8f14-a35efee6b0cb</guid>
      <title>Single Responsibility Principle</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 49 on the Single Responsibility Principle.</p>
<h1>Single Responsibility</h1>
<p>This week's tip is brought to you by devBetter.com.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>Are you a software developer looking to advance in your career more quickly? Would you find a mentor and a group of like-minded professionals valuable? If so, check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page. Sign up for a risk free membership if you're interested in growing your network and skills with us.</p>
<h2>Show Notes / Transcript</h2>
<p>The Single Responsibility Principle, or SRP, is the S in the SOLID principles macronym. The short version of it is that a class should have only one reason to change. Specifically, the reason referred to here is tied to the application's requirements. Each class should only be required to change in response to a single change in the application's requirements. These requirements typically correspond to real world things. For example, let's say the application needs to display a report for quarterly sales performance. The system's requirements might be that the report be rendered in a browser, that it include all sales for a given quarter grouped by individual sales representative. Either of these requirements might change in the future. Perhaps the reports need to be emailed as PDFs. Perhaps they need to be calculated monthly instead of quarterly or rolled up by sales region. Ideally, the format of the report and the details of how it is calculated should be separate responsibilities of separate classes.</p>
<p>Why is SRP important? Back in <a href="/015">episode 15, Maintain Legacy Code with New Code</a>, I explain one reason. Every time you change a class, you risk breaking classes that work with it. When a class has multiple responsibilities, it will likely need to change more often. Also, it's likely these responsibilities will be tightly coupled together by the class, making it harder to change them independently and further increasing the inherent risk of changing them. Let's say you have to fix a bug in an application. Would you rather have to work in a single class that literally only does the thing that has the bug in it, or would you prefer to work in a 2000 line long class that does 10 different things, all of which are intermixed in the class's 50 methods and properties? I know which one I prefer.</p>
<p>Too often, developers new to SOLID will hear about SRP and misunderstand a bit what a responsibility really is. They might have a class they've carved out from the rest of the application. Something like <code>CustomerManager</code>. They'll happily explain how <code>CustomerManager</code> is only responsible for <code>Customers</code> in the application, and thus is following SRP. But upon reviewing the code, it's clear that <code>CustomerManager</code> is responsible for <code>Customer</code> validation, <code>Customer</code> persistence, and <code>Customer</code> formatting for various user interfaces. It's responsible for notifying <code>Customers</code> when they place orders and oh yeah, it also is responsible for <code>Customers</code> placing orders, as well as managing their orders and their payment providers and their account history. But don't worry - <code>CustomerManager</code> only has one responsibility: Customers!</p>
<p>Although I said responsibilities typically map to business requirements, they don't typically map to entities like customers or orders or policies. This is because these entities will often have a lot of rich behavior that can be isolated into separate responsibilities, often with cross-cutting concerns within the application. For instance, how a customer is validated will likely be very similar to how an order is validated. The same goes for persistence and UI formatting and a host of other activities. Each of these is a responsibility, and should be isolated in its own class.</p>
<p>Now, it might seem like breaking up big classes into small ones is going to result in a lot more code, but often just the opposite occurs. As you pull cross-cutting concerns like validation, persistence, logging, notifications, formatting, etc. into their own classes, you'll often find ways to standardize the codebase and reuse these classes. A common way to achieve this reuse is through <a href="/019">the strategy pattern, which I discuss in episode episode 19</a>. The Strategy pattern lets you move responsibilities out of a class by delegating to other classes, which are often defined as fields or properties on the original class. These fields or properties have their instances set by having them passed in through the constructor, in what's commonly called dependency injection. Dependency injection and the strategy design pattern go hand-in-hand, and are my favorite way to <a href="https://www.pluralsight.com/courses/refactoring-fundamentals">refactor to achieve SRP</a> in classes that I find have too many responsibilities.</p>
<p>If you'd like to learn more about SRP and SOLID, check out my newly revised course, <a href="https://www.pluralsight.com/courses/csharp-solid-principles">SOLID Principles for C# Developers, on Pluralsight</a>. It's a complete update of my original <a href="https://www.pluralsight.com/courses/principles-oo-design">SOLID Principles of Object Oriented Design course</a> that has been in the top 100 for Pluralsight since it was published in 2010. The new one is shorter and streamlined, though it doesn't cover some topics the original course has. The new course also uses Visual Studio 2019 and has all of its course samples on GitHub. Check both of them out and let me know what you think.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://www.pluralsight.com/courses/csharp-solid-principles">SOLID Principles for C# Developers</a></li>
<li><a href="https://www.pluralsight.com/courses/principles-oo-design">SOLID Principles of Object Oriented Design</a> -and the DRY Principle</li>
<li><a href="https://www.pluralsight.com/courses/refactoring-fundamentals">Refactoring Fundamentals</a></li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 20 May 2019 06:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 49 on the Single Responsibility Principle.</p>
<h1>Single Responsibility</h1>
<p>This week's tip is brought to you by devBetter.com.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>Are you a software developer looking to advance in your career more quickly? Would you find a mentor and a group of like-minded professionals valuable? If so, check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page. Sign up for a risk free membership if you're interested in growing your network and skills with us.</p>
<h2>Show Notes / Transcript</h2>
<p>The Single Responsibility Principle, or SRP, is the S in the SOLID principles macronym. The short version of it is that a class should have only one reason to change. Specifically, the reason referred to here is tied to the application's requirements. Each class should only be required to change in response to a single change in the application's requirements. These requirements typically correspond to real world things. For example, let's say the application needs to display a report for quarterly sales performance. The system's requirements might be that the report be rendered in a browser, that it include all sales for a given quarter grouped by individual sales representative. Either of these requirements might change in the future. Perhaps the reports need to be emailed as PDFs. Perhaps they need to be calculated monthly instead of quarterly or rolled up by sales region. Ideally, the format of the report and the details of how it is calculated should be separate responsibilities of separate classes.</p>
<p>Why is SRP important? Back in <a href="/015">episode 15, Maintain Legacy Code with New Code</a>, I explain one reason. Every time you change a class, you risk breaking classes that work with it. When a class has multiple responsibilities, it will likely need to change more often. Also, it's likely these responsibilities will be tightly coupled together by the class, making it harder to change them independently and further increasing the inherent risk of changing them. Let's say you have to fix a bug in an application. Would you rather have to work in a single class that literally only does the thing that has the bug in it, or would you prefer to work in a 2000 line long class that does 10 different things, all of which are intermixed in the class's 50 methods and properties? I know which one I prefer.</p>
<p>Too often, developers new to SOLID will hear about SRP and misunderstand a bit what a responsibility really is. They might have a class they've carved out from the rest of the application. Something like <code>CustomerManager</code>. They'll happily explain how <code>CustomerManager</code> is only responsible for <code>Customers</code> in the application, and thus is following SRP. But upon reviewing the code, it's clear that <code>CustomerManager</code> is responsible for <code>Customer</code> validation, <code>Customer</code> persistence, and <code>Customer</code> formatting for various user interfaces. It's responsible for notifying <code>Customers</code> when they place orders and oh yeah, it also is responsible for <code>Customers</code> placing orders, as well as managing their orders and their payment providers and their account history. But don't worry - <code>CustomerManager</code> only has one responsibility: Customers!</p>
<p>Although I said responsibilities typically map to business requirements, they don't typically map to entities like customers or orders or policies. This is because these entities will often have a lot of rich behavior that can be isolated into separate responsibilities, often with cross-cutting concerns within the application. For instance, how a customer is validated will likely be very similar to how an order is validated. The same goes for persistence and UI formatting and a host of other activities. Each of these is a responsibility, and should be isolated in its own class.</p>
<p>Now, it might seem like breaking up big classes into small ones is going to result in a lot more code, but often just the opposite occurs. As you pull cross-cutting concerns like validation, persistence, logging, notifications, formatting, etc. into their own classes, you'll often find ways to standardize the codebase and reuse these classes. A common way to achieve this reuse is through <a href="/019">the strategy pattern, which I discuss in episode episode 19</a>. The Strategy pattern lets you move responsibilities out of a class by delegating to other classes, which are often defined as fields or properties on the original class. These fields or properties have their instances set by having them passed in through the constructor, in what's commonly called dependency injection. Dependency injection and the strategy design pattern go hand-in-hand, and are my favorite way to <a href="https://www.pluralsight.com/courses/refactoring-fundamentals">refactor to achieve SRP</a> in classes that I find have too many responsibilities.</p>
<p>If you'd like to learn more about SRP and SOLID, check out my newly revised course, <a href="https://www.pluralsight.com/courses/csharp-solid-principles">SOLID Principles for C# Developers, on Pluralsight</a>. It's a complete update of my original <a href="https://www.pluralsight.com/courses/principles-oo-design">SOLID Principles of Object Oriented Design course</a> that has been in the top 100 for Pluralsight since it was published in 2010. The new one is shorter and streamlined, though it doesn't cover some topics the original course has. The new course also uses Visual Studio 2019 and has all of its course samples on GitHub. Check both of them out and let me know what you think.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://www.pluralsight.com/courses/csharp-solid-principles">SOLID Principles for C# Developers</a></li>
<li><a href="https://www.pluralsight.com/courses/principles-oo-design">SOLID Principles of Object Oriented Design</a> -and the DRY Principle</li>
<li><a href="https://www.pluralsight.com/courses/refactoring-fundamentals">Refactoring Fundamentals</a></li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="3876161" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/ddb6be7d-1ffc-47f0-8043-5a5d34ea8a8d/8087a39a_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Single Responsibility Principle</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/ddb6be7d-1ffc-47f0-8043-5a5d34ea8a8d/3000x3000/1558302938artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:05:46</itunes:duration>
      <itunes:summary>This is episode 49 on the Single Responsibility Principle.</itunes:summary>
      <itunes:subtitle>This is episode 49 on the Single Responsibility Principle.</itunes:subtitle>
      <itunes:keywords>ci, di, single responsibility, software development, srp, dependency inversion, dependency injection, coding, design patterns, clean code, programming, tdd, testing, continuous integration, solid</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>49</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">5c965d2b-9250-4ac3-b4e9-4f2ed474340b</guid>
      <title>Effective Ways to Accelerate Your Career</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 48 on Effective Ways to Accelerate Your Career, with guest James Hickey.</p>
<h1>Effective Ways to Accelerate Your Career</h1>
<p>This week's tip is brought to you by devBetter.com.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>Are you a software developer looking to advance in your career more quickly? Would you find a mentor and a group of like-minded professionals valuable? If so, check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page. Sign up for a risk free membership if you're interested in growing your network and skills with us.</p>
<h2>Show Notes / Transcript</h2>
<p>This week's tip is brought to you by guest James Hickey. James is a software developer working remotely in eastern Canada. James helps software developers gain traction in their careers with his free email newsletter, &quot;Navigating Your Software Development Career&quot;, which I link to in the show notes. He's also the author of an open source .NET Core library called Coravel, which provides advanced capabilities to web applications. James is going to share some tips on accelerating your career. Welcome to Weekly Dev Tips, James!</p>
<p>Hi! I'm James Hickey.</p>
<p>I'm a senior .NET developer and consultant based in eastern Canada. I'm also the author of an open source .NET Core library you might be familiar with called Coravel.</p>
<p>One of the big realizations I had early on in my career was that doing a good job and doing what I was told to do would actually not lead to:</p>
<p>Promotions, recognition, becoming really skilled at my craft, and opening up more opportunities.</p>
<p>Many developers find themselves comfortable with having an easy and carefree job with minimal responsibilities.</p>
<p>Other developers, like myself, have an inner drive, ambition, and passion to be the best that we can be.</p>
<p>We recognize that having options means we can support our families better, have more money and resources to help our friends when in need, have the ability to create new businesses that solve important problems in our world, and know that we can inspire others to conquer obstacles in their own lives.</p>
<p>Are you one of these developers?</p>
<p>Here are some tips for you to accelerate a bit faster in your career!</p>
<h1>Find Gaps</h1>
<p>Here's my first tip.</p>
<p>Early in my own career, there were times when I would solve a problem and developers who were more senior than I would ask, &quot;How did you that?&quot;</p>
<p>One example was when I worked on a large database migration project. My colleagues were building various scripts that could take days to run.</p>
<p>When I started building my own scripts, I started using regular expressions in SQL to fetch certain patterns in the data, manipulate it and then store the results. My solutions were taking mere hours to run!</p>
<p>I became known as the guy who could migrate these large data sets very well. The senior developers would start coming to me for advice whenever they needed help in this area.</p>
<p>Have you ever solved a problem and then been asked questions like these?</p>
<ul>
<li>&quot;How did you do that?&quot;</li>
<li>&quot;What did you do there?&quot;</li>
<li>&quot;Why did you do that?&quot;</li>
</ul>
<p>This probably indicates that you've found a knowledge or skills gap in your team. You should jump all over that topic and become the &quot;go to&quot; person.</p>
<p>You might think that being known as the &quot;regular expression guy&quot; is not that useful.</p>
<p>But that's not what people will think.</p>
<p>In reality, you will be viewed as someone who can think outside the box. You will be viewed as someone who can solve tough problems.</p>
<p>So, when promotion time comes along, guess who will be already on the minds of the decision makers?</p>
<h1>Connecting With Past Co-workers</h1>
<p>Here's tip number 2.</p>
<p>If you've been in the field for a few years and have worked for a few different companies, then this next tip is for you.</p>
<p>One thing I started doing is contacting past co-workers and managers on LinkedIn.</p>
<p>First, I will ask them how they are doing. Next, I'll let them know - in a couple sentences - what I've been up to recently. And finally, I'll let them know that I am available to chat with them and help them with anything they need.</p>
<p>This is a short and concise way to connect with them on a personal level and let them know that you are just there to help them in any way.</p>
<p>Don't expect to be told immediately that your past co-workers have something they need help with. (Although that has happened to me, and I've landed some big opportunities this way.)</p>
<p>The main point is to merely put it in the minds of these people that you are available. When they move on to another company and are looking to hire software developers, guess who's going to come to mind first?</p>
<p>If you have a history of doing good work and being friendly and helpful to your co-workers, then you will be surprised where this simple tactic can lead!</p>
<h1>Teaching</h1>
<p>Have you noticed that the vast majority of the tech leaders you follow have either done public speaking, written books or recorded video tutorials?</p>
<p>My final tip will really accelerate your career: teach other developers in public.</p>
<p>Start speaking and presenting at user groups, meetups or even conferences.</p>
<p>Start writing technical blog articles that address very specific issues developers are facing in their day-to-day work.</p>
<p>You could even write a book which can skyrocket your credibility.</p>
<p>Or, you could begin recording video tutorials that help developers learn to build software better, use their tools more effectively, and so forth.</p>
<p>At the end of the day, simply helping people by teaching them to be better than they were yesterday will always win.</p>
<h1>Thanks!</h1>
<p>I hope you found these tips practical and useful! Thanks for letting me steal your thunder for a few minutes, Steve!</p>
<p>No problem, Jmaes. Thanks for the great tips. Listeners, I hope you'll sign up for James' newsletter to get more career-oriented tips from James in your inbox.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://www.blog.jamesmichaelhickey.com/">Find James Online</a></li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 13 May 2019 06:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 48 on Effective Ways to Accelerate Your Career, with guest James Hickey.</p>
<h1>Effective Ways to Accelerate Your Career</h1>
<p>This week's tip is brought to you by devBetter.com.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>Are you a software developer looking to advance in your career more quickly? Would you find a mentor and a group of like-minded professionals valuable? If so, check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page. Sign up for a risk free membership if you're interested in growing your network and skills with us.</p>
<h2>Show Notes / Transcript</h2>
<p>This week's tip is brought to you by guest James Hickey. James is a software developer working remotely in eastern Canada. James helps software developers gain traction in their careers with his free email newsletter, &quot;Navigating Your Software Development Career&quot;, which I link to in the show notes. He's also the author of an open source .NET Core library called Coravel, which provides advanced capabilities to web applications. James is going to share some tips on accelerating your career. Welcome to Weekly Dev Tips, James!</p>
<p>Hi! I'm James Hickey.</p>
<p>I'm a senior .NET developer and consultant based in eastern Canada. I'm also the author of an open source .NET Core library you might be familiar with called Coravel.</p>
<p>One of the big realizations I had early on in my career was that doing a good job and doing what I was told to do would actually not lead to:</p>
<p>Promotions, recognition, becoming really skilled at my craft, and opening up more opportunities.</p>
<p>Many developers find themselves comfortable with having an easy and carefree job with minimal responsibilities.</p>
<p>Other developers, like myself, have an inner drive, ambition, and passion to be the best that we can be.</p>
<p>We recognize that having options means we can support our families better, have more money and resources to help our friends when in need, have the ability to create new businesses that solve important problems in our world, and know that we can inspire others to conquer obstacles in their own lives.</p>
<p>Are you one of these developers?</p>
<p>Here are some tips for you to accelerate a bit faster in your career!</p>
<h1>Find Gaps</h1>
<p>Here's my first tip.</p>
<p>Early in my own career, there were times when I would solve a problem and developers who were more senior than I would ask, &quot;How did you that?&quot;</p>
<p>One example was when I worked on a large database migration project. My colleagues were building various scripts that could take days to run.</p>
<p>When I started building my own scripts, I started using regular expressions in SQL to fetch certain patterns in the data, manipulate it and then store the results. My solutions were taking mere hours to run!</p>
<p>I became known as the guy who could migrate these large data sets very well. The senior developers would start coming to me for advice whenever they needed help in this area.</p>
<p>Have you ever solved a problem and then been asked questions like these?</p>
<ul>
<li>&quot;How did you do that?&quot;</li>
<li>&quot;What did you do there?&quot;</li>
<li>&quot;Why did you do that?&quot;</li>
</ul>
<p>This probably indicates that you've found a knowledge or skills gap in your team. You should jump all over that topic and become the &quot;go to&quot; person.</p>
<p>You might think that being known as the &quot;regular expression guy&quot; is not that useful.</p>
<p>But that's not what people will think.</p>
<p>In reality, you will be viewed as someone who can think outside the box. You will be viewed as someone who can solve tough problems.</p>
<p>So, when promotion time comes along, guess who will be already on the minds of the decision makers?</p>
<h1>Connecting With Past Co-workers</h1>
<p>Here's tip number 2.</p>
<p>If you've been in the field for a few years and have worked for a few different companies, then this next tip is for you.</p>
<p>One thing I started doing is contacting past co-workers and managers on LinkedIn.</p>
<p>First, I will ask them how they are doing. Next, I'll let them know - in a couple sentences - what I've been up to recently. And finally, I'll let them know that I am available to chat with them and help them with anything they need.</p>
<p>This is a short and concise way to connect with them on a personal level and let them know that you are just there to help them in any way.</p>
<p>Don't expect to be told immediately that your past co-workers have something they need help with. (Although that has happened to me, and I've landed some big opportunities this way.)</p>
<p>The main point is to merely put it in the minds of these people that you are available. When they move on to another company and are looking to hire software developers, guess who's going to come to mind first?</p>
<p>If you have a history of doing good work and being friendly and helpful to your co-workers, then you will be surprised where this simple tactic can lead!</p>
<h1>Teaching</h1>
<p>Have you noticed that the vast majority of the tech leaders you follow have either done public speaking, written books or recorded video tutorials?</p>
<p>My final tip will really accelerate your career: teach other developers in public.</p>
<p>Start speaking and presenting at user groups, meetups or even conferences.</p>
<p>Start writing technical blog articles that address very specific issues developers are facing in their day-to-day work.</p>
<p>You could even write a book which can skyrocket your credibility.</p>
<p>Or, you could begin recording video tutorials that help developers learn to build software better, use their tools more effectively, and so forth.</p>
<p>At the end of the day, simply helping people by teaching them to be better than they were yesterday will always win.</p>
<h1>Thanks!</h1>
<p>I hope you found these tips practical and useful! Thanks for letting me steal your thunder for a few minutes, Steve!</p>
<p>No problem, Jmaes. Thanks for the great tips. Listeners, I hope you'll sign up for James' newsletter to get more career-oriented tips from James in your inbox.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://www.blog.jamesmichaelhickey.com/">Find James Online</a></li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="3912046" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/f34bfb17-9e18-418a-af74-10728ef9ece0/754a9429_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Effective Ways to Accelerate Your Career</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/f34bfb17-9e18-418a-af74-10728ef9ece0/3000x3000/1557747698artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:06:48</itunes:duration>
      <itunes:summary>This is episode 48 on Effective Ways to Accelerate Your Career, with guest James Hickey.</itunes:summary>
      <itunes:subtitle>This is episode 48 on Effective Ways to Accelerate Your Career, with guest James Hickey.</itunes:subtitle>
      <itunes:keywords>jobs, software development, leadership, advancement, development, dev, training, job, career, programming, software, team, growth, networking, tips, promotions</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>48</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">7ff20f10-3965-493d-817e-c86968dd1598</guid>
      <title>Introducing SOLID Principles</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 47, in which we'll introduce the SOLID principles. I'll spend a little time reviewing these principles in the upcoming episodes.</p>
<h1>What are the SOLID principles of object-oriented design?</h1>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>Are you a software developer looking to advance in your career more quickly? Would you find a mentor and a group of like-minded professionals valuable? If so, check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page. Sign up for a risk free membership if you're interested in growing your network and skills with us.</p>
<h2>Show Notes / Transcript</h2>
<p>Depending on how long you've been programming, you may have heard of the <a href="https://www.pluralsight.com/courses/csharp-solid-principles">SOLID principles</a>. These are a set of 5 principles that have been around for several decades, and about 15 years ago someone - I think it was Michael Feathers - had the idea to arrange them in such a way that they formed the macronym SOLID. Prior to that, I think the first time they were all published together was in Robert C. Martin's 2003 book, <a href="https://amzn.to/2DksEqj">Agile Software Development: Principles, Patterns, and Practices</a> in which their sequence spelled SOLDI - so close! This same sequence was used in the 2006 book <a href="https://amzn.to/2UJ8Arv">Agile Principles, Patterns, and Practices in C#</a>.</p>
<p>So what are the SOLID principles? As I mentioned, SOLID is a macronym, meaning it is an acronym formed by other acronyms. In this case, these are SRP, OCP, LSP, ISP, and DIP. All those Ps at the end of each acronym stand for <em>principle</em>, of course. Listing each principle, we have:</p>
<ul>
<li>Single Responsibility</li>
<li>Open/Closed</li>
<li>Liskov Substitution</li>
<li>Interface Segregation</li>
<li>Dependency Inversion</li>
</ul>
<p>You may already be familiar with these principles. If you're a developer who's using a strongly typed language like C# or Java, you should be extremely familiar with them. If you're not, I recommend digging into them more deeply. Applying them can make a massive difference in the quality of code you write. How do I define quality? Well, that's probably a topic I could devote an episode to, but the short version is that quality code is code that is easy to understand and easy to change to suit new requirements. It's easily and quickly tested by automated tests, which reduces the need for expensive manual testing. And it's loosely coupled to infrastructure concerns like databases or files.</p>
<p>How do these principles help you to write quality code? They provide guidance. You need to write code that solves a problem, first and foremost. But once you have code that does that, before you call it done and check it in, you should evaluate its design and see if it makes sense to spend a few moments cleaning anything up. Back in <a href="/006">Episode 6</a> - you are listening to these in sequential, not reverse, order, right? - I talked about Kent Beck's approach of Make It Work, Make It Right, Make It Fast. SOLID principles should generally be applied during the Make It Right step. Don't apply them up front, but as I discussed in <a href="/010">Episode 10, follow Pain Driven Development</a>. If you try to apply every principle to every part of your codebase from the start, you'll end up with extremely abstract code that could do anything but actually does nothing. Don't do that.</p>
<p>Instead, build the code you need to solve the problem at hand, and then evaluate whether that code has any <a href="/030">major code smells like I discussed in episode 30</a>. One huge code smell is code that is hard to unit test, meaning it's hard to write an automated test that can just test your code, without any external infrastructure or dependencies like databases, files, or web servers. Code that is easy to unit test is generally easy to change, and code that has tests is also easier to <a href="https://www.pluralsight.com/courses/refactoring-fundamentals">refactor</a> because when you're done you'll have some degree of confidence that you haven't broken anything.</p>
<p>In upcoming episodes, I'll drill into each principle a bit more. I've published two courses on SOLID at Pluralsight where you can obviously learn a lot more and see real code as opposed to just hearing me through a podcast. The <a href="https://www.pluralsight.com/courses/principles-oo-design">first one was published in 2010</a> and so the tools and look were a bit dated. The <a href="https://www.pluralsight.com/courses/csharp-solid-principles">more recent one</a> is slimmed down and uses the latest version of Visual Studio and .NET Core. There are links to both courses in the show notes - the original one also covers the Don't Repeat Yourself principle. Let me wrap this episode up with a very brief overview of each principle.</p>
<p>The Single Responsibility Principle is generally applied to classes and suggests that classes should have only one responsibility, which can also be thought of as one reason to change. Responsibilities include things like business logic, ui logic, data access, and more. Following this principle, you'll tend to have smaller, more focused classes.</p>
<p>The Open/Closed Principle suggests that you should be able to change the behavior of your system without changing its source code. This generally relies on some kind of parameter or plug-in capability to provide new behavior to an existing class or service.</p>
<p>The Liskov Substitution Principle cautions against creating inheritance hierarchies in which child types are not 100% substitutable for their base types. When violated, this can result in messy code and bugs.</p>
<p>The Interface Segregation Principle suggests that classes that use interfaces should use all or most of the interface's exposed members. This then leads to interfaces that are small, focused, and cohesive, much like SRP.</p>
<p>Finally, the Dependency Inversion Principle recommends that low-level concerns depend on high level concerns, not the other way around. This means for example that business layer code shouldn't directly depend on data access code, but rather an abstraction should exist that the business code works with and that the data access code implements. At runtime, the data access code will be provided as an implementation of the interface the business code is written to work with, providing loose coupling and more testable code.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://www.pluralsight.com/courses/csharp-solid-principles">SOLID Principles for C#</a> on Pluralsight</li>
<li><a href="https://www.pluralsight.com/courses/refactoring-fundamentals">Refactoring Fundamentals</a> on Pluralsight</li>
<li><a href="https://www.pluralsight.com/courses/principles-oo-design">SOLID Principles of Object Oriented Design</a> on Pluralsight (published in 2010)</li>
<li><a href="https://amzn.to/2DksEqj">Agile Software Development: Principles, Patterns, and Practices</a> on Amazon</li>
<li><a href="https://amzn.to/2UJ8Arv">Agile Principles, Patterns, and Practices in C#</a> on Amazon</li>
<li><a href="https://www.youtube.com/channel/UC1OeiOnqUZHVinzRK5MuHsA">See Visualizations and Subscribe to WeeklyDevTips in YouTube</a></li>
<li><a href="https://amzn.to/2Hbulc5">Clean Code</a> on Amazon</li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 6 May 2019 06:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 47, in which we'll introduce the SOLID principles. I'll spend a little time reviewing these principles in the upcoming episodes.</p>
<h1>What are the SOLID principles of object-oriented design?</h1>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>Are you a software developer looking to advance in your career more quickly? Would you find a mentor and a group of like-minded professionals valuable? If so, check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page. Sign up for a risk free membership if you're interested in growing your network and skills with us.</p>
<h2>Show Notes / Transcript</h2>
<p>Depending on how long you've been programming, you may have heard of the <a href="https://www.pluralsight.com/courses/csharp-solid-principles">SOLID principles</a>. These are a set of 5 principles that have been around for several decades, and about 15 years ago someone - I think it was Michael Feathers - had the idea to arrange them in such a way that they formed the macronym SOLID. Prior to that, I think the first time they were all published together was in Robert C. Martin's 2003 book, <a href="https://amzn.to/2DksEqj">Agile Software Development: Principles, Patterns, and Practices</a> in which their sequence spelled SOLDI - so close! This same sequence was used in the 2006 book <a href="https://amzn.to/2UJ8Arv">Agile Principles, Patterns, and Practices in C#</a>.</p>
<p>So what are the SOLID principles? As I mentioned, SOLID is a macronym, meaning it is an acronym formed by other acronyms. In this case, these are SRP, OCP, LSP, ISP, and DIP. All those Ps at the end of each acronym stand for <em>principle</em>, of course. Listing each principle, we have:</p>
<ul>
<li>Single Responsibility</li>
<li>Open/Closed</li>
<li>Liskov Substitution</li>
<li>Interface Segregation</li>
<li>Dependency Inversion</li>
</ul>
<p>You may already be familiar with these principles. If you're a developer who's using a strongly typed language like C# or Java, you should be extremely familiar with them. If you're not, I recommend digging into them more deeply. Applying them can make a massive difference in the quality of code you write. How do I define quality? Well, that's probably a topic I could devote an episode to, but the short version is that quality code is code that is easy to understand and easy to change to suit new requirements. It's easily and quickly tested by automated tests, which reduces the need for expensive manual testing. And it's loosely coupled to infrastructure concerns like databases or files.</p>
<p>How do these principles help you to write quality code? They provide guidance. You need to write code that solves a problem, first and foremost. But once you have code that does that, before you call it done and check it in, you should evaluate its design and see if it makes sense to spend a few moments cleaning anything up. Back in <a href="/006">Episode 6</a> - you are listening to these in sequential, not reverse, order, right? - I talked about Kent Beck's approach of Make It Work, Make It Right, Make It Fast. SOLID principles should generally be applied during the Make It Right step. Don't apply them up front, but as I discussed in <a href="/010">Episode 10, follow Pain Driven Development</a>. If you try to apply every principle to every part of your codebase from the start, you'll end up with extremely abstract code that could do anything but actually does nothing. Don't do that.</p>
<p>Instead, build the code you need to solve the problem at hand, and then evaluate whether that code has any <a href="/030">major code smells like I discussed in episode 30</a>. One huge code smell is code that is hard to unit test, meaning it's hard to write an automated test that can just test your code, without any external infrastructure or dependencies like databases, files, or web servers. Code that is easy to unit test is generally easy to change, and code that has tests is also easier to <a href="https://www.pluralsight.com/courses/refactoring-fundamentals">refactor</a> because when you're done you'll have some degree of confidence that you haven't broken anything.</p>
<p>In upcoming episodes, I'll drill into each principle a bit more. I've published two courses on SOLID at Pluralsight where you can obviously learn a lot more and see real code as opposed to just hearing me through a podcast. The <a href="https://www.pluralsight.com/courses/principles-oo-design">first one was published in 2010</a> and so the tools and look were a bit dated. The <a href="https://www.pluralsight.com/courses/csharp-solid-principles">more recent one</a> is slimmed down and uses the latest version of Visual Studio and .NET Core. There are links to both courses in the show notes - the original one also covers the Don't Repeat Yourself principle. Let me wrap this episode up with a very brief overview of each principle.</p>
<p>The Single Responsibility Principle is generally applied to classes and suggests that classes should have only one responsibility, which can also be thought of as one reason to change. Responsibilities include things like business logic, ui logic, data access, and more. Following this principle, you'll tend to have smaller, more focused classes.</p>
<p>The Open/Closed Principle suggests that you should be able to change the behavior of your system without changing its source code. This generally relies on some kind of parameter or plug-in capability to provide new behavior to an existing class or service.</p>
<p>The Liskov Substitution Principle cautions against creating inheritance hierarchies in which child types are not 100% substitutable for their base types. When violated, this can result in messy code and bugs.</p>
<p>The Interface Segregation Principle suggests that classes that use interfaces should use all or most of the interface's exposed members. This then leads to interfaces that are small, focused, and cohesive, much like SRP.</p>
<p>Finally, the Dependency Inversion Principle recommends that low-level concerns depend on high level concerns, not the other way around. This means for example that business layer code shouldn't directly depend on data access code, but rather an abstraction should exist that the business code works with and that the data access code implements. At runtime, the data access code will be provided as an implementation of the interface the business code is written to work with, providing loose coupling and more testable code.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://www.pluralsight.com/courses/csharp-solid-principles">SOLID Principles for C#</a> on Pluralsight</li>
<li><a href="https://www.pluralsight.com/courses/refactoring-fundamentals">Refactoring Fundamentals</a> on Pluralsight</li>
<li><a href="https://www.pluralsight.com/courses/principles-oo-design">SOLID Principles of Object Oriented Design</a> on Pluralsight (published in 2010)</li>
<li><a href="https://amzn.to/2DksEqj">Agile Software Development: Principles, Patterns, and Practices</a> on Amazon</li>
<li><a href="https://amzn.to/2UJ8Arv">Agile Principles, Patterns, and Practices in C#</a> on Amazon</li>
<li><a href="https://www.youtube.com/channel/UC1OeiOnqUZHVinzRK5MuHsA">See Visualizations and Subscribe to WeeklyDevTips in YouTube</a></li>
<li><a href="https://amzn.to/2Hbulc5">Clean Code</a> on Amazon</li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="4478377" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/0f2a068a-d1ff-4021-96d5-676a54301471/416f001e_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Introducing SOLID Principles</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/0f2a068a-d1ff-4021-96d5-676a54301471/3000x3000/1557155024artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:07:26</itunes:duration>
      <itunes:summary>This is episode 47, in which we&apos;ll introduce the SOLID principles. I&apos;ll spend a little time reviewing these principles in the upcoming episodes.</itunes:summary>
      <itunes:subtitle>This is episode 47, in which we&apos;ll introduce the SOLID principles. I&apos;ll spend a little time reviewing these principles in the upcoming episodes.</itunes:subtitle>
      <itunes:keywords>software development, coding, clean code, programming, tdd, solid principles, testing, uncle bob martin, solid, robert c martin</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>47</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">3c16758f-a6a6-4d47-9c69-63e8a121befc</guid>
      <title>On Sleep with Guest Jamie Taylor</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 46, with guest Jamie Taylor, aka GaProgMan.</p>
<h1>On The Importance of Sleep</h1>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>Are you a software developer looking to advance in your career more quickly? Would you find a mentor and a group of like-minded professionals valuable? If so, check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page. Sign up for a risk free membership if you're interested in growing your network and skills with us.</p>
<h2>Show Notes / Transcript</h2>
<p>This week's tip comes to us from the UK, where fellow podcast host Jamie Taylor lives. He has a great tip that will help improve your health and productivity. Take it away, Jamie!</p>
<hr />
<p>Hello everyone, I'm Jamie &quot;GaProgMan&quot; Taylor, I'm the host of The .NET Core Podcast, and Steve has graciously agreed to let me share a tip with you all. My plan isn't to talk to you about .NET Core or even development, per se, but I might use them as a background for what I <em>do</em> want to talk about: and that's finding the time to relax and getting enough sleep.</p>
<p>We work in a very fast paced industry, it seems like the technology space is constantly evolving. The breakneck pace of our industry can seem overwhelming to most of us, especially if you want to keep up with the latest innovations. I know that I've been guilty, in the past, of saying something like:</p>
<blockquote>
<p>the moment that you stop learning, you're already a day behind</p>
</blockquote>
<p>Which, other than being hyperbole, is a bit of a double edged sword. On the one hand, it's a great idea to keep to speed with what's going on; but on the other hand, you need down time.</p>
<p>Now I don't care how long you can sit at your laptop, coding into the wee hours of the morning, drinking coffee, Red Bull, Mountain Dew, or whatever your incredibly sugary caffeinated drink of choice is. Eventually, you are going to need some rest and relaxation.</p>
<p>And rest is the most important thing. Your body, whether you are aware of it or not, can go for days without food - it would be tough, but it's doable. But you <em>cannot</em> go for days without resting. To quote one UC Berkley article on the subject:</p>
<blockquote>
<p>As little as one night without sleep is enough to turn a reasonable person into &quot;emotional Jell-O,&quot; says Matthew Walker, director of Berkeley’s Sleep and Neuroimaging Laboratory</p>
</blockquote>
<ul>
<li>source: <a href="https://alumni.berkeley.edu/california-magazine/march-april-2008-mind-matters/your-brain-without-sleep">https://alumni.berkeley.edu/california-magazine/march-april-2008-mind-matters/your-brain-without-sleep</a></li>
</ul>
<p>The brain is the most important part of the body for a developer. Without it, we can't function (if you'll pardon the pun). We need the ability to deal with complex business logic, hold several layers of the application's design in our short term memory, and to be able to parse customer requirements.</p>
<p>Without a healthy, well rested brain you can't do any of this. In the words of John Silva (host of National Geographic Channel's &quot;Brain Games&quot;):</p>
<blockquote>
<p>One of the things that happens when you're sleep-deprived is that your ability to regulate emotions goes haywire. Your brain becomes disorganised in its capacity to process information and your sensitivity to information also get scrambled.</p>
</blockquote>
<p>Regulating emotions is an incredibly important skill to have, and becoming disorganised is quite possibly the antithesis of the state of mind that a developer needs to be in. You need to be able to focus on the task at hand.</p>
<p>&quot;But I'm an extremely well motivated go-getter, Jamie. I really don't care.&quot; Eventually you are either going to crash and burn, or you're going to need the help of a team of doctors, and possibly a hospital.</p>
<p>When you don't rest, you're not just affecting you're physical health, but you're also putting your mental health at risk. Without sleep, you'll be unable to put your thoughts in order, which means that you won't be able to communicate with others, which will lead to you becoming agitated, and that will lead to stress.</p>
<p>And stress (or more correctly, &quot;distress&quot;) can wreak havoc on your body. We're talking headaches, increased blood pressure, chest pain, heart problems, skin conditions, depression, and anxiety to say the least.</p>
<h3>So what can we do?</h3>
<p>Firstly, get up and walk away from your computer. Maybe not, right now. But the next time you get a chance to do so: do it. Take a walk, preferably outside; and if you really must have a coffee, walk to the next coffee shop along - the extra time in the fresh air will really help you.</p>
<p>Spend time away from a computer of phone screen, as little as 15 minutes for every 45 will really help. Walk over to the water cooler and have a chat with someone while you get a cup of water. And if you don't have a water cooler, figure out another place to go and to be social - some companies have breakout rooms for this purpose.</p>
<p>But what about outside of work?</p>
<p>It's so easy to get trapped in a cycle of:</p>
<ul>
<li>Wake up</li>
<li>Commute to work</li>
<li>Only leave the desk to go to the bathroom or get lunch</li>
<li>Commute home</li>
<li>Spend all evening working on some personal projects, or staring at your phone</li>
</ul>
<p>So let's use the Japanese idea of Kaizen (which means &quot;improvement&quot;) to break that, little by little.</p>
<p>I've taken up running in an evening (well, it's more like jogging, because I'm so out of shape). I'll occasionally call my brother and talk with him about everything and nothing, or we'll talk about video games for hours.</p>
<p>I attend a number of meetups which are not even remotely to technology related. By spending time away from computer screens and talking to folks, I've found that I feel more balanced, and rested. Remember: we're social beings.</p>
<p>But the number one, most important thing, is sleep. And that can be hard to achieve when you're so used to sitting in front of a bright screen for hours. Our brains are tuned to think that bright light equals day time, so when we're surrounded by unnatural, bright lights, we tend to stay awake for longer. Which is why it's sometimes hard to sleep if you end up using a computer, tablet, or mobile phone before you go to bed.</p>
<p>Fixing this is super easy: just don't spend all day and night sitting in front of a bright screen. Give yourself a cut off point, say 30 minutes before bed, and don't use a computer, tablet or phone during that period. But if you have to use your computer or phone during that window, know that the white light emitted by these screens contains harsh blue hues, which will make your brain think that it's day time. So just don't use them. Or, if you have to use them, look for apps similar to <a href="https://justgetflux.com/">f.lux</a>, or <a href="https://play.google.com/store/apps/details?id=com.jmstudios.redmoon">Red Moon</a> if you're an Android user, or if you use iOS devices then you can use a combination of <a href="https://support.apple.com/en-us/HT207570">NightShift</a> and True Tone.</p>
<h3>What About You Jamie?</h3>
<p>I occasionally get insomnia, and when it strikes I have a number of ways to rest even when I can't seem to sleep.</p>
<p>The very first thing that I do is make myself a cup of chamomile tea. I've always found that it chills me out, and it can really help me to rest. This might not work for everyone, but the combination of a hot drink <em>without</em> caffeine before bed really helps me. You know how some people like to have a cup of hot cocoa before bed? It's the same thing.</p>
<p>Then I try to focus on not ruminating on anything - this is the medical term for when you can't sleep because you're thinking about that bug you've been trying to recreate for 3 days. It's hard to do make these thoughts just go away, but just try to put it out of your mind. Thinking about things like this when you're meant to be sleeping isn't going to help you sleep. Trust me.</p>
<p>The next thing that I do - and this isn't going to be to everyone's tastes, so feel free to skip over this one - is I practise mindfulness meditation. It sounds unintuitive, but focusing my attention on the breath seems to really help me to relax, which helps lead to me feeling super tired. Again, this isn't going to be to everyone's tastes.</p>
<p>I also subscribe to a number of podcasts specifically designed to help me sleep (obviously, Weekly Dev Tips is <em>not</em> one of these podcasts). I used to do this with audio books, especially technical books where the reader doesn't really emphasise any particular parts of the story, but I've since found a number of podcasts which are designed to help you sleep. <a href="https://www.sleepwithmepodcast.com/">Sleep With Me</a> is one of my favourite ones. I simply start an episode playing through my phone (at a low volume obviously), lay in bed and close my eyes. Some people that I've talked to about this have said that the sound white noise, or the sound of rainfall can produce a similar effect.</p>
<h3>In Summary</h3>
<p>You need to find a way to get rest which works for you. After all, you need good quality rest in order to be productive, NOT the other way around. You cannot be productive without being well rested, and no matter which way you look at it, developers need to be productive.</p>
<p>One last thing before I go: take a look into <a href="https://www.sleepfoundation.org/articles/what-circadian-rhythm">circadian rhythm</a> (I've probably mispronounced that completely).</p>
<p>The tl;dr (or too long; didn't read) is that we have a certain number of states when we sleep: light sleep, deep sleep, and REM sleep. The deeper your sleeping state is when you wake up, the more groggy you'll feel when you do wake up. There are apps that you can get which will attempt to measure which sleep cycle you are in, and try to wake you while in a light sleep cycle as your alarm time approaches.</p>
<p>This can leave you feeling less groggy, and less like you need that first cup of coffee in the morning.</p>
<p>Now, I'd like for you all to get some good quality rest.</p>
<p>And thank you Steve for allowing me to share this tip with everyone.</p>
<hr />
<p>Thanks, Jamie!</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://alumni.berkeley.edu/california-magazine/march-april-2008-mind-matters/your-brain-without-sleep">Your Brain Without Sleep</a></li>
<li><a href="https://www.sleepwithmepodcast.com/">Sleep With Me</a> podcast</li>
<li><a href="https://www.sleepfoundation.org/articles/what-circadian-rhythm">Circadian rhythm</a></li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 15 Apr 2019 06:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 46, with guest Jamie Taylor, aka GaProgMan.</p>
<h1>On The Importance of Sleep</h1>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>Are you a software developer looking to advance in your career more quickly? Would you find a mentor and a group of like-minded professionals valuable? If so, check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page. Sign up for a risk free membership if you're interested in growing your network and skills with us.</p>
<h2>Show Notes / Transcript</h2>
<p>This week's tip comes to us from the UK, where fellow podcast host Jamie Taylor lives. He has a great tip that will help improve your health and productivity. Take it away, Jamie!</p>
<hr />
<p>Hello everyone, I'm Jamie &quot;GaProgMan&quot; Taylor, I'm the host of The .NET Core Podcast, and Steve has graciously agreed to let me share a tip with you all. My plan isn't to talk to you about .NET Core or even development, per se, but I might use them as a background for what I <em>do</em> want to talk about: and that's finding the time to relax and getting enough sleep.</p>
<p>We work in a very fast paced industry, it seems like the technology space is constantly evolving. The breakneck pace of our industry can seem overwhelming to most of us, especially if you want to keep up with the latest innovations. I know that I've been guilty, in the past, of saying something like:</p>
<blockquote>
<p>the moment that you stop learning, you're already a day behind</p>
</blockquote>
<p>Which, other than being hyperbole, is a bit of a double edged sword. On the one hand, it's a great idea to keep to speed with what's going on; but on the other hand, you need down time.</p>
<p>Now I don't care how long you can sit at your laptop, coding into the wee hours of the morning, drinking coffee, Red Bull, Mountain Dew, or whatever your incredibly sugary caffeinated drink of choice is. Eventually, you are going to need some rest and relaxation.</p>
<p>And rest is the most important thing. Your body, whether you are aware of it or not, can go for days without food - it would be tough, but it's doable. But you <em>cannot</em> go for days without resting. To quote one UC Berkley article on the subject:</p>
<blockquote>
<p>As little as one night without sleep is enough to turn a reasonable person into &quot;emotional Jell-O,&quot; says Matthew Walker, director of Berkeley’s Sleep and Neuroimaging Laboratory</p>
</blockquote>
<ul>
<li>source: <a href="https://alumni.berkeley.edu/california-magazine/march-april-2008-mind-matters/your-brain-without-sleep">https://alumni.berkeley.edu/california-magazine/march-april-2008-mind-matters/your-brain-without-sleep</a></li>
</ul>
<p>The brain is the most important part of the body for a developer. Without it, we can't function (if you'll pardon the pun). We need the ability to deal with complex business logic, hold several layers of the application's design in our short term memory, and to be able to parse customer requirements.</p>
<p>Without a healthy, well rested brain you can't do any of this. In the words of John Silva (host of National Geographic Channel's &quot;Brain Games&quot;):</p>
<blockquote>
<p>One of the things that happens when you're sleep-deprived is that your ability to regulate emotions goes haywire. Your brain becomes disorganised in its capacity to process information and your sensitivity to information also get scrambled.</p>
</blockquote>
<p>Regulating emotions is an incredibly important skill to have, and becoming disorganised is quite possibly the antithesis of the state of mind that a developer needs to be in. You need to be able to focus on the task at hand.</p>
<p>&quot;But I'm an extremely well motivated go-getter, Jamie. I really don't care.&quot; Eventually you are either going to crash and burn, or you're going to need the help of a team of doctors, and possibly a hospital.</p>
<p>When you don't rest, you're not just affecting you're physical health, but you're also putting your mental health at risk. Without sleep, you'll be unable to put your thoughts in order, which means that you won't be able to communicate with others, which will lead to you becoming agitated, and that will lead to stress.</p>
<p>And stress (or more correctly, &quot;distress&quot;) can wreak havoc on your body. We're talking headaches, increased blood pressure, chest pain, heart problems, skin conditions, depression, and anxiety to say the least.</p>
<h3>So what can we do?</h3>
<p>Firstly, get up and walk away from your computer. Maybe not, right now. But the next time you get a chance to do so: do it. Take a walk, preferably outside; and if you really must have a coffee, walk to the next coffee shop along - the extra time in the fresh air will really help you.</p>
<p>Spend time away from a computer of phone screen, as little as 15 minutes for every 45 will really help. Walk over to the water cooler and have a chat with someone while you get a cup of water. And if you don't have a water cooler, figure out another place to go and to be social - some companies have breakout rooms for this purpose.</p>
<p>But what about outside of work?</p>
<p>It's so easy to get trapped in a cycle of:</p>
<ul>
<li>Wake up</li>
<li>Commute to work</li>
<li>Only leave the desk to go to the bathroom or get lunch</li>
<li>Commute home</li>
<li>Spend all evening working on some personal projects, or staring at your phone</li>
</ul>
<p>So let's use the Japanese idea of Kaizen (which means &quot;improvement&quot;) to break that, little by little.</p>
<p>I've taken up running in an evening (well, it's more like jogging, because I'm so out of shape). I'll occasionally call my brother and talk with him about everything and nothing, or we'll talk about video games for hours.</p>
<p>I attend a number of meetups which are not even remotely to technology related. By spending time away from computer screens and talking to folks, I've found that I feel more balanced, and rested. Remember: we're social beings.</p>
<p>But the number one, most important thing, is sleep. And that can be hard to achieve when you're so used to sitting in front of a bright screen for hours. Our brains are tuned to think that bright light equals day time, so when we're surrounded by unnatural, bright lights, we tend to stay awake for longer. Which is why it's sometimes hard to sleep if you end up using a computer, tablet, or mobile phone before you go to bed.</p>
<p>Fixing this is super easy: just don't spend all day and night sitting in front of a bright screen. Give yourself a cut off point, say 30 minutes before bed, and don't use a computer, tablet or phone during that period. But if you have to use your computer or phone during that window, know that the white light emitted by these screens contains harsh blue hues, which will make your brain think that it's day time. So just don't use them. Or, if you have to use them, look for apps similar to <a href="https://justgetflux.com/">f.lux</a>, or <a href="https://play.google.com/store/apps/details?id=com.jmstudios.redmoon">Red Moon</a> if you're an Android user, or if you use iOS devices then you can use a combination of <a href="https://support.apple.com/en-us/HT207570">NightShift</a> and True Tone.</p>
<h3>What About You Jamie?</h3>
<p>I occasionally get insomnia, and when it strikes I have a number of ways to rest even when I can't seem to sleep.</p>
<p>The very first thing that I do is make myself a cup of chamomile tea. I've always found that it chills me out, and it can really help me to rest. This might not work for everyone, but the combination of a hot drink <em>without</em> caffeine before bed really helps me. You know how some people like to have a cup of hot cocoa before bed? It's the same thing.</p>
<p>Then I try to focus on not ruminating on anything - this is the medical term for when you can't sleep because you're thinking about that bug you've been trying to recreate for 3 days. It's hard to do make these thoughts just go away, but just try to put it out of your mind. Thinking about things like this when you're meant to be sleeping isn't going to help you sleep. Trust me.</p>
<p>The next thing that I do - and this isn't going to be to everyone's tastes, so feel free to skip over this one - is I practise mindfulness meditation. It sounds unintuitive, but focusing my attention on the breath seems to really help me to relax, which helps lead to me feeling super tired. Again, this isn't going to be to everyone's tastes.</p>
<p>I also subscribe to a number of podcasts specifically designed to help me sleep (obviously, Weekly Dev Tips is <em>not</em> one of these podcasts). I used to do this with audio books, especially technical books where the reader doesn't really emphasise any particular parts of the story, but I've since found a number of podcasts which are designed to help you sleep. <a href="https://www.sleepwithmepodcast.com/">Sleep With Me</a> is one of my favourite ones. I simply start an episode playing through my phone (at a low volume obviously), lay in bed and close my eyes. Some people that I've talked to about this have said that the sound white noise, or the sound of rainfall can produce a similar effect.</p>
<h3>In Summary</h3>
<p>You need to find a way to get rest which works for you. After all, you need good quality rest in order to be productive, NOT the other way around. You cannot be productive without being well rested, and no matter which way you look at it, developers need to be productive.</p>
<p>One last thing before I go: take a look into <a href="https://www.sleepfoundation.org/articles/what-circadian-rhythm">circadian rhythm</a> (I've probably mispronounced that completely).</p>
<p>The tl;dr (or too long; didn't read) is that we have a certain number of states when we sleep: light sleep, deep sleep, and REM sleep. The deeper your sleeping state is when you wake up, the more groggy you'll feel when you do wake up. There are apps that you can get which will attempt to measure which sleep cycle you are in, and try to wake you while in a light sleep cycle as your alarm time approaches.</p>
<p>This can leave you feeling less groggy, and less like you need that first cup of coffee in the morning.</p>
<p>Now, I'd like for you all to get some good quality rest.</p>
<p>And thank you Steve for allowing me to share this tip with everyone.</p>
<hr />
<p>Thanks, Jamie!</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://alumni.berkeley.edu/california-magazine/march-april-2008-mind-matters/your-brain-without-sleep">Your Brain Without Sleep</a></li>
<li><a href="https://www.sleepwithmepodcast.com/">Sleep With Me</a> podcast</li>
<li><a href="https://www.sleepfoundation.org/articles/what-circadian-rhythm">Circadian rhythm</a></li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="4715913" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/ed811152-d1ad-447d-9f60-899fdddb8cae/d4b647a8_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>On Sleep with Guest Jamie Taylor</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/ed811152-d1ad-447d-9f60-899fdddb8cae/3000x3000/1554989413artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:08:49</itunes:duration>
      <itunes:summary>This week&apos;s tip comes to us from the UK, where fellow podcast host Jamie Taylor lives. He has a great tip that will help improve your health and productivity. </itunes:summary>
      <itunes:subtitle>This week&apos;s tip comes to us from the UK, where fellow podcast host Jamie Taylor lives. He has a great tip that will help improve your health and productivity. </itunes:subtitle>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>46</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">92215d1e-4c70-4506-89f0-74442957de98</guid>
      <title>Work Alone with Mystery Guest</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 45 on working alone with a mystery guest.</p>
<h1>Working Alone</h1>
<h2>Show Notes / Transcript</h2>
<p>This week's show was recorded on 1 April 2019 with a special guest who has chosen to remain anonymous.</p>
<hr />
<p>I'm a developer with a regular day job, but at night I do freelance work in the shadows. I mostly right wrongs committed (to source control) by other developers, so the people who use their software can sleep better at night. I work alone, and have a secret identity to protect those closest to me. And because I signed a strict employee agreement with my day job and I don't want them to find out about my moonlighting activities.</p>
<p>My tip to other developers: work alone. After years of working with other team members, I can tell you it's for the best. My team members at my day job are like my personal nemesis. There's this one guy who doesn't take the work seriously enough. He refuses to follow team conventions. Half the time it seems like he's intentionally trying to blow up our code. He should probably consider changing roles to testing. I'm constantly fighting with this joker.</p>
<p>Then there's another dev I work with - I swear he thinks writing impossible to understand code is his ticket to job security. Most of the code he writes, even if it 'works', is like a riddle, wrapped in a mystery, inside an enigma. I think he gets a kick out of seeing if the other developers on the team can figure out his clever code. I don't have time for his games.</p>
<p>When I'm not fighting with these two, it seems like as soon as I'm able to add a cool feature to our code, we're closing in on a ship date and the product manager puts a freeze on new features. If 'Mr. Freeze,' as we call him, weren't involved, I'm sure I could get a few more features into the product for each version.</p>
<p>Even when I'm not having to deal with this group, I have to compete with another dev who thinks he's a gift to the team. I think he prefers to work alone, too, or at least he doesn't like to work with me. His work is always superb, which grates on me partly out of jealousy, but also because when he's out sick (he has really bad allergies), there's nobody but me to stand against the rest of the team.</p>
<p>At night, working alone, I can do my best work. Hiding behind a bitmask, I knock out issues in client projects before they see me coming. I don't always follow the rules, but I get the job done. I may not always deliver the code teams want, but I give them the code they deserve.</p>
<hr />
<p>Ok... well thanks for that tip... uh...</p>
<hr />
<h2><em>I'm batdev</em></h2>
<hr />
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 1 Apr 2019 06:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 45 on working alone with a mystery guest.</p>
<h1>Working Alone</h1>
<h2>Show Notes / Transcript</h2>
<p>This week's show was recorded on 1 April 2019 with a special guest who has chosen to remain anonymous.</p>
<hr />
<p>I'm a developer with a regular day job, but at night I do freelance work in the shadows. I mostly right wrongs committed (to source control) by other developers, so the people who use their software can sleep better at night. I work alone, and have a secret identity to protect those closest to me. And because I signed a strict employee agreement with my day job and I don't want them to find out about my moonlighting activities.</p>
<p>My tip to other developers: work alone. After years of working with other team members, I can tell you it's for the best. My team members at my day job are like my personal nemesis. There's this one guy who doesn't take the work seriously enough. He refuses to follow team conventions. Half the time it seems like he's intentionally trying to blow up our code. He should probably consider changing roles to testing. I'm constantly fighting with this joker.</p>
<p>Then there's another dev I work with - I swear he thinks writing impossible to understand code is his ticket to job security. Most of the code he writes, even if it 'works', is like a riddle, wrapped in a mystery, inside an enigma. I think he gets a kick out of seeing if the other developers on the team can figure out his clever code. I don't have time for his games.</p>
<p>When I'm not fighting with these two, it seems like as soon as I'm able to add a cool feature to our code, we're closing in on a ship date and the product manager puts a freeze on new features. If 'Mr. Freeze,' as we call him, weren't involved, I'm sure I could get a few more features into the product for each version.</p>
<p>Even when I'm not having to deal with this group, I have to compete with another dev who thinks he's a gift to the team. I think he prefers to work alone, too, or at least he doesn't like to work with me. His work is always superb, which grates on me partly out of jealousy, but also because when he's out sick (he has really bad allergies), there's nobody but me to stand against the rest of the team.</p>
<p>At night, working alone, I can do my best work. Hiding behind a bitmask, I knock out issues in client projects before they see me coming. I don't always follow the rules, but I get the job done. I may not always deliver the code teams want, but I give them the code they deserve.</p>
<hr />
<p>Ok... well thanks for that tip... uh...</p>
<hr />
<h2><em>I'm batdev</em></h2>
<hr />
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="1698853" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/5dbe5f53-bb61-4f84-948c-0a861c5ed501/aa52d8c3_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Work Alone with Mystery Guest</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/5dbe5f53-bb61-4f84-948c-0a861c5ed501/3000x3000/1554124126artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:02:52</itunes:duration>
      <itunes:summary>This is episode 45 on working alone with a mystery guest.</itunes:summary>
      <itunes:subtitle>This is episode 45 on working alone with a mystery guest.</itunes:subtitle>
      <itunes:keywords>podcast, clean code, programming, teams</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>45</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">0eccdfaa-d4c3-4204-8646-f9455d1a46c1</guid>
      <title>Work From Home Tips with Andrew Lock</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 44 with some guest tips on working from home that I hope you'll find useful.</p>
<h1>Working From Home Tips</h1>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>Are you a software developer looking to advance in your career more quickly? Would you find a mentor and a group of like-minded professionals valuable? If so, check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page. Sign up for a risk free membership if you're interested in growing your network and skills with us.</p>
<h2>Show Notes / Transcript</h2>
<p>This week we have a special guest, Andrew Lock, who like me does a lot of work with ASP.NET Core. Andrew, why don't you go ahead and introduce yourself for our listeners, and then just go right into the tips you'd like to share.</p>
<hr />
<p>Hi, my name's Andrew Lock, I'm a developer and author of the book <a href="https://amzn.to/2CpEFtX">ASP.NET Core in Action</a>.</p>
<p>I live in Devon in the UK but I work for a company in London.</p>
<p>I work 100% remotely, which is becoming more and more common in the dev community,</p>
<p>But one question I hear a lot is &quot;how do you stay focused when you're working from home all day?&quot;</p>
<p>That's one of those questions where the answer is going to depend a lot on the particular person.</p>
<p>Many people who haven't worked remotely before remember the occasional time they &quot;worked from home&quot; and worry about all the distractions that are around you: the TV, kids running around, all those little chores that need doing.</p>
<p>So how can you cope with all this, and actually be productive when working from home. I thought I'd share a few things that I've found work for me. You might find some of them work for you too, but don't worry if they don't!</p>
<h2>Have a dedicated work area</h2>
<p>A really important part of working from home for me is having a dedicated work area. We have a spare bedroom with a desk and that's where I work when I'm working from home. There's two parts to this. First it's important to have a comfortable chair and a desk that's the right height for you, to avoid fatigue and injuries. So no slumping on a sofa with the laptop!</p>
<p>Secondly, it separates my life into Work and Home. If you work in the same rooms as you relax and do other things in, it can be easy to get distracted. When I'm working, I'm in the office and it's a lot easier to get into that working mentality. This also helps when you have other people in the house, as it's easy to say &quot;if I'm in the office, I'm at work&quot;.</p>
<p>It's worth mentioning that some people find that even with this approach, being at home all day is still too distracting, and they like to completely separate their work time by going to a shared working area, or a coffee shop. Personally I find that far more distracting, but it might work for you.</p>
<h2>Routine</h2>
<p>As well as having a dedicated work area, I find routine to be extremely useful. Whether you're able to follow a fixed routine or not will likely depend a lot on your specific job and your living situation, as well as other commitments, but I find any structure you can add to your day helps. It's all part of getting into the &quot;I'm at work now&quot; mentality, and trying to shut off other distractions.</p>
<p>Of course, just because you're following a routine and working in your office, doesn't mean that you should be head-down working the whole time. Far from it! In fact, it's very easy to lose track of time when you're working from home, and be sat still for hours. Not only is that bad for you physically, I find it's actually detrimental to my productivity in the long run.</p>
<p>The first few weeks of working remotely, I felt <em>so</em> productive in the morning. I would get my head down, code for several hours, and feel like I was really going strong. By the time it got to the afternoon however, I was drained, and unable to focus for the rest of the day.</p>
<p>Instead, I find I can stay productive for a whole day by ensuring I take a <em>lot</em> of small breaks. In particular, I often use the Pomodoro technique. There's lots about this approach on the internet, and there's various apps you can use to follow it, but I'll give a brief summary of how I apply it to my day.</p>
<h2>The Pomodoro technique</h2>
<p>The Pomodoro technique involves working in relatively short, timed blocks. So I set a timer for 25 minutes, and focus 100% on the task at hand. When an alarm goes off I take a 5 minute break - make a cup of tea or coffee, check my emails, anything really. When the break timer goes off, I get straight back to working again for another 25 minute block. After 5 blocks of working, I take a longer 30 minute break - get some lunch or go for a run - before settling down to another 5 blocks of work.</p>
<p>If you haven't tried it before, I strongly suggest giving the Pomodoro technique a go. Adjust the timings to what works for you. I was sceptical at first, but I've found it helps me stay focused for a whole day, without burning out in the afternoon. In fact it's the approach I used to write my book while also working a full time job, and I don't think I would have managed that without it! IT can feel unnatural at first to break up those long coding sessions, but it really pays off in the long run.</p>
<h2>Don't beat yourself up</h2>
<p>The last thing I want to mention is the feeling that you're being unproductive when you're working from home, even if you aren't! Something I struggled with a lot initially was the feeling that everyone <em>assumed</em> I wasn't working hard when I was at home. So I felt like I had to go above and beyond to show that I was - by not taking breaks, or working longer than the hours I was paid for.</p>
<p>I'm sure this is how a lot of people think when they start working remotely, but I really encourage you to fight against it. When I was working in an office, I wasn't working 100% of the time. In fact, I was <em>way</em> less productive in the office, so try not to beat yourself up. Take breaks. Don't overwork yourself, and try and add some structure to your day - it's far more sustainable, and you'll probably find you're more productive than you ever thought you could be.</p>
<p>Thanks for inviting me on Steve!</p>
<hr />
<p>You're very welcome - thanks for sharing your advice with us! I've added links to the resources you mentioned to the show notes at <a href="https://weeklydevtips.com/044">weeklydevtips.com/044</a>.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://www.youtube.com/channel/UC1OeiOnqUZHVinzRK5MuHsA">See Visualizations and Subscribe to WeeklyDevTips in YouTube</a></li>
<li><a href="https://andrewlock.net/">Andrew Lock blog</a></li>
<li><a href="https://twitter.com/andrewlocknet">Andrew Lock on Twitter</a></li>
<li><a href="https://en.wikipedia.org/wiki/Pomodoro_Technique">Pomodoro Technique</a></li>
<li><a href="https://amzn.to/2CpEFtX">ASP.NET Core in Action</a> on Amazon</li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 25 Mar 2019 06:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 44 with some guest tips on working from home that I hope you'll find useful.</p>
<h1>Working From Home Tips</h1>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>Are you a software developer looking to advance in your career more quickly? Would you find a mentor and a group of like-minded professionals valuable? If so, check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page. Sign up for a risk free membership if you're interested in growing your network and skills with us.</p>
<h2>Show Notes / Transcript</h2>
<p>This week we have a special guest, Andrew Lock, who like me does a lot of work with ASP.NET Core. Andrew, why don't you go ahead and introduce yourself for our listeners, and then just go right into the tips you'd like to share.</p>
<hr />
<p>Hi, my name's Andrew Lock, I'm a developer and author of the book <a href="https://amzn.to/2CpEFtX">ASP.NET Core in Action</a>.</p>
<p>I live in Devon in the UK but I work for a company in London.</p>
<p>I work 100% remotely, which is becoming more and more common in the dev community,</p>
<p>But one question I hear a lot is &quot;how do you stay focused when you're working from home all day?&quot;</p>
<p>That's one of those questions where the answer is going to depend a lot on the particular person.</p>
<p>Many people who haven't worked remotely before remember the occasional time they &quot;worked from home&quot; and worry about all the distractions that are around you: the TV, kids running around, all those little chores that need doing.</p>
<p>So how can you cope with all this, and actually be productive when working from home. I thought I'd share a few things that I've found work for me. You might find some of them work for you too, but don't worry if they don't!</p>
<h2>Have a dedicated work area</h2>
<p>A really important part of working from home for me is having a dedicated work area. We have a spare bedroom with a desk and that's where I work when I'm working from home. There's two parts to this. First it's important to have a comfortable chair and a desk that's the right height for you, to avoid fatigue and injuries. So no slumping on a sofa with the laptop!</p>
<p>Secondly, it separates my life into Work and Home. If you work in the same rooms as you relax and do other things in, it can be easy to get distracted. When I'm working, I'm in the office and it's a lot easier to get into that working mentality. This also helps when you have other people in the house, as it's easy to say &quot;if I'm in the office, I'm at work&quot;.</p>
<p>It's worth mentioning that some people find that even with this approach, being at home all day is still too distracting, and they like to completely separate their work time by going to a shared working area, or a coffee shop. Personally I find that far more distracting, but it might work for you.</p>
<h2>Routine</h2>
<p>As well as having a dedicated work area, I find routine to be extremely useful. Whether you're able to follow a fixed routine or not will likely depend a lot on your specific job and your living situation, as well as other commitments, but I find any structure you can add to your day helps. It's all part of getting into the &quot;I'm at work now&quot; mentality, and trying to shut off other distractions.</p>
<p>Of course, just because you're following a routine and working in your office, doesn't mean that you should be head-down working the whole time. Far from it! In fact, it's very easy to lose track of time when you're working from home, and be sat still for hours. Not only is that bad for you physically, I find it's actually detrimental to my productivity in the long run.</p>
<p>The first few weeks of working remotely, I felt <em>so</em> productive in the morning. I would get my head down, code for several hours, and feel like I was really going strong. By the time it got to the afternoon however, I was drained, and unable to focus for the rest of the day.</p>
<p>Instead, I find I can stay productive for a whole day by ensuring I take a <em>lot</em> of small breaks. In particular, I often use the Pomodoro technique. There's lots about this approach on the internet, and there's various apps you can use to follow it, but I'll give a brief summary of how I apply it to my day.</p>
<h2>The Pomodoro technique</h2>
<p>The Pomodoro technique involves working in relatively short, timed blocks. So I set a timer for 25 minutes, and focus 100% on the task at hand. When an alarm goes off I take a 5 minute break - make a cup of tea or coffee, check my emails, anything really. When the break timer goes off, I get straight back to working again for another 25 minute block. After 5 blocks of working, I take a longer 30 minute break - get some lunch or go for a run - before settling down to another 5 blocks of work.</p>
<p>If you haven't tried it before, I strongly suggest giving the Pomodoro technique a go. Adjust the timings to what works for you. I was sceptical at first, but I've found it helps me stay focused for a whole day, without burning out in the afternoon. In fact it's the approach I used to write my book while also working a full time job, and I don't think I would have managed that without it! IT can feel unnatural at first to break up those long coding sessions, but it really pays off in the long run.</p>
<h2>Don't beat yourself up</h2>
<p>The last thing I want to mention is the feeling that you're being unproductive when you're working from home, even if you aren't! Something I struggled with a lot initially was the feeling that everyone <em>assumed</em> I wasn't working hard when I was at home. So I felt like I had to go above and beyond to show that I was - by not taking breaks, or working longer than the hours I was paid for.</p>
<p>I'm sure this is how a lot of people think when they start working remotely, but I really encourage you to fight against it. When I was working in an office, I wasn't working 100% of the time. In fact, I was <em>way</em> less productive in the office, so try not to beat yourself up. Take breaks. Don't overwork yourself, and try and add some structure to your day - it's far more sustainable, and you'll probably find you're more productive than you ever thought you could be.</p>
<p>Thanks for inviting me on Steve!</p>
<hr />
<p>You're very welcome - thanks for sharing your advice with us! I've added links to the resources you mentioned to the show notes at <a href="https://weeklydevtips.com/044">weeklydevtips.com/044</a>.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://www.youtube.com/channel/UC1OeiOnqUZHVinzRK5MuHsA">See Visualizations and Subscribe to WeeklyDevTips in YouTube</a></li>
<li><a href="https://andrewlock.net/">Andrew Lock blog</a></li>
<li><a href="https://twitter.com/andrewlocknet">Andrew Lock on Twitter</a></li>
<li><a href="https://en.wikipedia.org/wiki/Pomodoro_Technique">Pomodoro Technique</a></li>
<li><a href="https://amzn.to/2CpEFtX">ASP.NET Core in Action</a> on Amazon</li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="4242309" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/47471b7f-05e6-4069-ac55-f04f403b45e0/fb8f7c38_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Work From Home Tips with Andrew Lock</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/47471b7f-05e6-4069-ac55-f04f403b45e0/3000x3000/1552937289artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:06:31</itunes:duration>
      <itunes:summary>This is episode 44 with some guest tips on working from home that I hope you&apos;ll find useful.</itunes:summary>
      <itunes:subtitle>This is episode 44 with some guest tips on working from home that I hope you&apos;ll find useful.</itunes:subtitle>
      <itunes:keywords>software development, pomodoro, telecommuting, agile, coding, remote work, programming, work from home, productivity</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>44</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">3076c018-dbf8-4b71-8564-44ea1fbfbfab</guid>
      <title>A Dependency Injection Story</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 43, with a quick story about dependency injection.</p>
<h1>A Dependency Injection Story</h1>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>Are you a software developer looking to advance in your career more quickly? Would you find a mentor and a group of like-minded professionals valuable? If so, check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page. Sign up for a risk free membership if you're interested in growing your network and skills with us.</p>
<h2>Show Notes / Transcript</h2>
<p>A few years and several businesses ago, my wife and I ran an online ad business, Lake Quincy Media, that served banner ads on software developer web sites like W3Schools, www.asp.net, and ASPAlliance.com. I wrote the original ad serving software for the company, and over the years as we grew we built a team and rewrote it a couple of times. We were using ASP.NET, what would now be called web forms, at the time I first really understood how to use dependency injection. I still remember exactly how it happened, and it dramatically changed how I looked at structuring my object-oriented applications from that point forward.</p>
<p>Backing up a bit, I'd learned about and bought into practices like automated testing and continuous integration some years earlier. These practices were not as widespread as they are today, especially in the Microsoft development space, but we were using them at Lake Quincy Media to good effect on our ad server software (which also included publisher and advertiser portals, etc.). We were using a CI server called Cruise Control which included a nice system tray tool called CCTray that would pop up a notification and play a sound any time the build failed or was fixed. It worked great and problems that broke the build were quickly addressed by our small team. However, the application was architected using a traditional N-Tier architecture that was the recommended approach at that time. This meant that the ASP.NET application depended on the business logic application which in turn depended on the data access layer that called the database. Tests of the business logic required a test database, and so our tests ran SQL scripts that reset the database to a known good state before every test. Running several hundred of these tests took about 5-10 minutes on the build server as a result, which wasn't ideal. The point is, we were using automated tests, but our architecture was forcing us to rely more on integration tests rather than unit tests. This background leads to the next part of the story.</p>
<p>I remember distinctly trying to write a test for a method that dealt with saving new banner ad media files once they were uploaded to the server. The method in question needed to save the file, perform some work on the file, and then based on some other factors, call some other methods. I was trying to write tests for this, but I was forced to write tests that actually dealt with the file system, and these were very painful. A configuration file was required to specify the upload path, this path wasn't the same between servers and developer machines. Sometimes the file would be locked and tests would fail, or someone would check in a different version of the config file with the path set wrong, and the tests would fail. It was quite brittle, and the files access really wasn't what was being tested - the conditional logic of the method was.</p>
<p>By chance I was chatting with my friend and fellow MVP and Iraq war veteran, <a href="https://twitter.com/jeffreypalermo">Jeffrey Palermo</a> as I was struggling with this. He hopped on a screenshare with me and showed me how to change my business-level class so it wasn't working directly with the file system. Instead, he created an interface that included the required file operations like save and rename file, and moved the actual logic for working with the file system into a new class that implemented this interface. Then he created an instance of the interface in the business-level class, which was set by the constructor.</p>
<p>However, in our test code, he showed me how to create a fake implementation of the file interface, which we could have the tests configure to return whatever kind of result we needed for the test case we were validating. This was huge! It literally blew my mind and changed how I thought about and wrote code from that day forward. Aaron B., who recently joined my tips mailing list, prompted this tip with his question, &quot;What is one thing you wish you knew when you first started your development career?&quot; and this is what I thought of. Thanks, Aaron, and thanks again, Jeffrey, for showing me this awesome technique for reducing painful coupling in software applications.</p>
<p>Needless to say, armed with this technique and a desire to learn more about the related SOLID principles, my tests quickly started to emphasize unit tests wherever possible instead of intregration tests for everything. Our builds started to get faster, and we found tests were quicker and easier to write as well. This was over ten years ago now, but I wish I'd learned it much sooner in my career, and I hope sharing it here will help some of you.</p>
<p>If you have a story you'd like to share about something you learned later in your career that you wish you'd learned sooner, go to weeklydevtips.com/043 and leave it as a comment. Thanks!</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://www.youtube.com/channel/UC1OeiOnqUZHVinzRK5MuHsA">See Visualizations and Subscribe to WeeklyDevTips in YouTube</a></li>
<li><a href="https://amzn.to/2Hbulc5">Clean Code</a> on Amazon</li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 18 Mar 2019 06:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 43, with a quick story about dependency injection.</p>
<h1>A Dependency Injection Story</h1>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>Are you a software developer looking to advance in your career more quickly? Would you find a mentor and a group of like-minded professionals valuable? If so, check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page. Sign up for a risk free membership if you're interested in growing your network and skills with us.</p>
<h2>Show Notes / Transcript</h2>
<p>A few years and several businesses ago, my wife and I ran an online ad business, Lake Quincy Media, that served banner ads on software developer web sites like W3Schools, www.asp.net, and ASPAlliance.com. I wrote the original ad serving software for the company, and over the years as we grew we built a team and rewrote it a couple of times. We were using ASP.NET, what would now be called web forms, at the time I first really understood how to use dependency injection. I still remember exactly how it happened, and it dramatically changed how I looked at structuring my object-oriented applications from that point forward.</p>
<p>Backing up a bit, I'd learned about and bought into practices like automated testing and continuous integration some years earlier. These practices were not as widespread as they are today, especially in the Microsoft development space, but we were using them at Lake Quincy Media to good effect on our ad server software (which also included publisher and advertiser portals, etc.). We were using a CI server called Cruise Control which included a nice system tray tool called CCTray that would pop up a notification and play a sound any time the build failed or was fixed. It worked great and problems that broke the build were quickly addressed by our small team. However, the application was architected using a traditional N-Tier architecture that was the recommended approach at that time. This meant that the ASP.NET application depended on the business logic application which in turn depended on the data access layer that called the database. Tests of the business logic required a test database, and so our tests ran SQL scripts that reset the database to a known good state before every test. Running several hundred of these tests took about 5-10 minutes on the build server as a result, which wasn't ideal. The point is, we were using automated tests, but our architecture was forcing us to rely more on integration tests rather than unit tests. This background leads to the next part of the story.</p>
<p>I remember distinctly trying to write a test for a method that dealt with saving new banner ad media files once they were uploaded to the server. The method in question needed to save the file, perform some work on the file, and then based on some other factors, call some other methods. I was trying to write tests for this, but I was forced to write tests that actually dealt with the file system, and these were very painful. A configuration file was required to specify the upload path, this path wasn't the same between servers and developer machines. Sometimes the file would be locked and tests would fail, or someone would check in a different version of the config file with the path set wrong, and the tests would fail. It was quite brittle, and the files access really wasn't what was being tested - the conditional logic of the method was.</p>
<p>By chance I was chatting with my friend and fellow MVP and Iraq war veteran, <a href="https://twitter.com/jeffreypalermo">Jeffrey Palermo</a> as I was struggling with this. He hopped on a screenshare with me and showed me how to change my business-level class so it wasn't working directly with the file system. Instead, he created an interface that included the required file operations like save and rename file, and moved the actual logic for working with the file system into a new class that implemented this interface. Then he created an instance of the interface in the business-level class, which was set by the constructor.</p>
<p>However, in our test code, he showed me how to create a fake implementation of the file interface, which we could have the tests configure to return whatever kind of result we needed for the test case we were validating. This was huge! It literally blew my mind and changed how I thought about and wrote code from that day forward. Aaron B., who recently joined my tips mailing list, prompted this tip with his question, &quot;What is one thing you wish you knew when you first started your development career?&quot; and this is what I thought of. Thanks, Aaron, and thanks again, Jeffrey, for showing me this awesome technique for reducing painful coupling in software applications.</p>
<p>Needless to say, armed with this technique and a desire to learn more about the related SOLID principles, my tests quickly started to emphasize unit tests wherever possible instead of intregration tests for everything. Our builds started to get faster, and we found tests were quicker and easier to write as well. This was over ten years ago now, but I wish I'd learned it much sooner in my career, and I hope sharing it here will help some of you.</p>
<p>If you have a story you'd like to share about something you learned later in your career that you wish you'd learned sooner, go to weeklydevtips.com/043 and leave it as a comment. Thanks!</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://www.youtube.com/channel/UC1OeiOnqUZHVinzRK5MuHsA">See Visualizations and Subscribe to WeeklyDevTips in YouTube</a></li>
<li><a href="https://amzn.to/2Hbulc5">Clean Code</a> on Amazon</li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="3616597" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/1c79a7d1-360b-4a4c-8034-e85a755b1e14/6985c1bc_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>A Dependency Injection Story</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/1c79a7d1-360b-4a4c-8034-e85a755b1e14/3000x3000/1552858229artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:05:50</itunes:duration>
      <itunes:summary>This is episode 43, with a quick story about dependency injection.</itunes:summary>
      <itunes:subtitle>This is episode 43, with a quick story about dependency injection.</itunes:subtitle>
      <itunes:keywords>ci, di, software development, dependency inversion, dependency injection, coding, design patterns, clean code, programming, tdd, testing, continuous integration, solid</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>43</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">35adb2f1-c3c1-487b-9e6a-14c3d36b692f</guid>
      <title>On Learning TDD and LISP with Uncle Bob Martin</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 42 - the answer to life, the universe, and everything - with some guest tips on learning TDD and Lisp.</p>
<h1>Learning TDD and Lisp</h1>
<p>This week we have a special guest. He is the author of the books <a href="https://amzn.to/2Hbulc5">Clean Code</a>, <a href="https://amzn.to/2XxORte">The Clean Coder</a>, and <a href="https://amzn.to/2EtwbSI">Clean Architecture</a>, all of which I think should be required reading for professional software developers. Robert C. Martin, aka &quot;Uncle Bob&quot;, is here to share a couple of tips for software developers. You'll find him online at <a href="https://twitter.com/unclebobmartin">@unclebobmartin on twitter</a> and at <a href="http://cleancoder.com">cleancoder.com</a>. We'll jump right into his tip after this quick word from this week's sponsor.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>Are you a software developer looking to advance in your career more quickly? Would you find a mentor and a group of like-minded professionals valuable? If so, check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page. Sign up for a risk free membership if you're interested in growing your network and skills with us.</p>
<h2>Show Notes / Transcript</h2>
<p>Ok, so without further ado, please welcome Uncle Bob to WeeklyDevTips!</p>
<p>...</p>
<p>Thanks so much, Bob! <a href="https://amzn.to/2SGeJj4">Structure and Interpretation of Computer Programs</a> was actually the first computer science text book I had in college, in a class that used another Lisp variant, Scheme. I've added links to the resources you mentioned to the show notes, which you'll find in your podcast client or at weeklydevtips.com/042.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://www.youtube.com/channel/UC1OeiOnqUZHVinzRK5MuHsA">See Visualizations and Subscribe to WeeklyDevTips in YouTube</a></li>
<li><a href="https://twitter.com/unclebobmartin">Uncle Bob on Twitter</a></li>
<li><a href="http://cleancoder.com">CleanCoder.com</a></li>
<li><a href="https://cleancoders.com/videos">Clean Coders Videos</a></li>
<li><a href="https://amzn.to/2SGeJj4">Structure and Interpretation of Computer Programs</a> on Amazon</li>
<li><a href="https://web.mit.edu/alexmv/6.037/sicp.pdf">Structure and Interpretation of Computer Programs</a> free PDF</li>
<li><a href="https://clojure.org/about/lisp">Clojure as a Dialect of Lisp</a></li>
<li><a href="https://amzn.to/2Hbulc5">Clean Code</a> on Amazon</li>
<li><a href="https://amzn.to/2XxORte">The Clean Coder</a> on Amazon</li>
<li><a href="https://amzn.to/2EtwbSI">Clean Architecture</a> on Amazon</li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 4 Mar 2019 07:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 42 - the answer to life, the universe, and everything - with some guest tips on learning TDD and Lisp.</p>
<h1>Learning TDD and Lisp</h1>
<p>This week we have a special guest. He is the author of the books <a href="https://amzn.to/2Hbulc5">Clean Code</a>, <a href="https://amzn.to/2XxORte">The Clean Coder</a>, and <a href="https://amzn.to/2EtwbSI">Clean Architecture</a>, all of which I think should be required reading for professional software developers. Robert C. Martin, aka &quot;Uncle Bob&quot;, is here to share a couple of tips for software developers. You'll find him online at <a href="https://twitter.com/unclebobmartin">@unclebobmartin on twitter</a> and at <a href="http://cleancoder.com">cleancoder.com</a>. We'll jump right into his tip after this quick word from this week's sponsor.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>Are you a software developer looking to advance in your career more quickly? Would you find a mentor and a group of like-minded professionals valuable? If so, check out <a href="https://devbetter.com/">devBetter.com</a> and read the testimonials at the bottom of the page. Sign up for a risk free membership if you're interested in growing your network and skills with us.</p>
<h2>Show Notes / Transcript</h2>
<p>Ok, so without further ado, please welcome Uncle Bob to WeeklyDevTips!</p>
<p>...</p>
<p>Thanks so much, Bob! <a href="https://amzn.to/2SGeJj4">Structure and Interpretation of Computer Programs</a> was actually the first computer science text book I had in college, in a class that used another Lisp variant, Scheme. I've added links to the resources you mentioned to the show notes, which you'll find in your podcast client or at weeklydevtips.com/042.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://www.youtube.com/channel/UC1OeiOnqUZHVinzRK5MuHsA">See Visualizations and Subscribe to WeeklyDevTips in YouTube</a></li>
<li><a href="https://twitter.com/unclebobmartin">Uncle Bob on Twitter</a></li>
<li><a href="http://cleancoder.com">CleanCoder.com</a></li>
<li><a href="https://cleancoders.com/videos">Clean Coders Videos</a></li>
<li><a href="https://amzn.to/2SGeJj4">Structure and Interpretation of Computer Programs</a> on Amazon</li>
<li><a href="https://web.mit.edu/alexmv/6.037/sicp.pdf">Structure and Interpretation of Computer Programs</a> free PDF</li>
<li><a href="https://clojure.org/about/lisp">Clojure as a Dialect of Lisp</a></li>
<li><a href="https://amzn.to/2Hbulc5">Clean Code</a> on Amazon</li>
<li><a href="https://amzn.to/2XxORte">The Clean Coder</a> on Amazon</li>
<li><a href="https://amzn.to/2EtwbSI">Clean Architecture</a> on Amazon</li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="5470476" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/7c74989f-3287-4def-967d-b9e6b7ec3e42/0492e301_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>On Learning TDD and LISP with Uncle Bob Martin</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/7c74989f-3287-4def-967d-b9e6b7ec3e42/3000x3000/1551643041artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:08:58</itunes:duration>
      <itunes:summary>This is episode 42 - the answer to life, the universe, and everything - with some guest tips on learning TDD and Lisp.</itunes:summary>
      <itunes:subtitle>This is episode 42 - the answer to life, the universe, and everything - with some guest tips on learning TDD and Lisp.</itunes:subtitle>
      <itunes:keywords>lisp, software development, coding, clean code, programming, clojure, tdd, testing, uncle bob martin, robert c martin</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>42</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">42bd34b9-69b4-4e12-a397-f750175b55a1</guid>
      <title>Sprints Versus Continuous Flow</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 41, in which I'll talk about the difference between sprint and iteration-based software processes compared to continuous processes.</p>
<p>If you’re enjoying these tips, please subscribe in your app. You can leave a rating and better yet, a comment in your app, too. I also accept subscriptions to @WeeklyDevTips on twitter and comments and requests for topics there or in the show comments, too. Thanks for all of your support!</p>
<h1>Sprints Versus Continuous Flow</h1>
<p>Sprint and iteration-based processes are stepping stones on the path from waterfall toward continuous flow. In this episode we'll make some comparisons to build and integration processes to demonstrate this.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>If you're not advancing as quickly in your career as you'd like, you may find value in joining a semi-formal career and technical coaching program like devBetter.com. devBetter is a small group of motivated developers meeting every week or two, and staying connected in the meantime via a private Slack community. I answer questions, review code, suggest areas in which to improve, and occasionally assign homework. Interested? Learn more at <a href="https://devbetter.com/">devBetter.com</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>I've been a fan of continuous integration, or CI, for many years. When I was first getting started in professional software development, CI was still new and unproven. Some of my first consulting engagements had me working on teams where there was a team member who was the designated integrator. Their job was to understand how to put all the components of the application together so that the app could be deployed. This was a major ordeal every couple of months when a deployment needed to be made.</p>
<p>In the 1990s, automated builds started to become increasingly popular. Tools like Ant, and later in .NET NAnt, were growing in popularity. Automated builds started to enable periodic scheduled integrations. Instead of having someone manually integrate and deploy the system every few months, these automated tools enabled weekly integrations, providing much more rapid feedback. Eventually, the frequency of these builds increased from weekly to daily (or more typically, nightly), and finally to the extreme of continuous integration. Continuous integration builds and tests the application every time a change is made to the application's source control.</p>
<p>It's hard to get much better than continuous integration, but there are still a couple of nice features that can and have been added. Today, I most of my projects use continuous integration, but continuous integration by itself doesn't prevent developers from breaking the build by checking in broken stuff to the main branch. Two features that tools like Azure DevOps and GitHub support now are the ability to run builds on pull requests and the ability to restrict merging pull requests so that they require a passing build before they can be pulled in. Adding in these two features eliminates the vast majority of broken build scenarios, ensuring the main branch of the application remains in a working state at all times.</p>
<p>So, what does this have to do with sprints? Before we had XP iterations and Scrum sprints, most software development used some kind of waterfall-like process. Iterations, such as they were, were quite long: months and sometimes years. Iterative development approaches popularized by agile software development recommended much shorter iterations, with many developer organizations shifting to 2- or 4-week iterations. Each iteration, the team would estimate the backlog, prioritize the work, plan out the iteration or sprint, commit to the plan, get work done, test it, try to deploy it, and potentially hold a retrospective about the iteration. It's not uncommon to look at iteration-based agile and compare it to a series of mini-waterfalls. The analogy from infrequent deployments to more frequent integrations is an easy one to see.</p>
<p>So, with integrations, there's an obvious spectrum of increased benefit associated with increased frequency. There aren't many dissenting voices crying out that continuous integration is a waste of time and we should only build software once a month. The feedback benefits of CI over even daily builds is quite clear. So, if you see a certain amount of benefit when going from long-term waterfall delivery to 4-week iterative delivery, it should be obvious that this benefit will increase further if you go from 4-week to 2-week. But most teams stop there. The reason why most teams never shorten their iterations below 2-week sprints is because of the pain involved in some of the required ceremonies that are tied to the sprint. I literally saw this happen last week, when a client initially planned on 1-week sprints but dropped back to 2-week sprints because there were too many meetings to make 1-week sprints work.</p>
<p>The issue is that the ceremonies eat into time to actually get work done. For instance, a reasonable retrospective probably takes an hour. Investing an hour every 2 weeks may seem reasonable, but what about every week, or every day? Estimating and prioritizing the backlog is a similarly painful part of most sprint plans - would it make sense to do it more often? This may sound crazy if you didn't listen to last week's episode yet, but give it some thought.</p>
<p>Here's the thing - these ceremonies aren't strictly tied to delivering software. You could increase or decrease your sprint cadence, and still have monthly retrospectives. The same is true for prioritizing work. You can still do it every two weeks while your sprints are one week long, if you want. You can even do it literally just-in-time as things are pulled from the backlog. Imagine how quick sprint planning sessions would be if they only had to choose the next item the dev team would start working on? You could do that 10 times a day with an email exchange if the product owner made it a priority.</p>
<p>Once you realize that really long iterations, like traditional waterfall, are not great, and shorter iterations are better, you should be able to make the jump to continuous flow pretty easily. If there are things that make this too painful, then <a href="/040">listen to the last episode</a>, and do those things more often. Or, realize they're not in the critical path to delivering software, and stop tying them to your software delivery cadence and schedule them on whatever cadence makes sense for your team.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="/040">If It Hurts, Do It More Often</a></li>
<li><a href="https://www.youtube.com/channel/UC1OeiOnqUZHVinzRK5MuHsA">See Visualizations and Subscribe to WeeklyDevTips in YouTube</a></li>
</ul>
<p>That’s it for this week. Next week we have a special guest as Robert &quot;Uncle Bob&quot; Martin will provide a couple of tips - be sure to check back for that. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 25 Feb 2019 07:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 41, in which I'll talk about the difference between sprint and iteration-based software processes compared to continuous processes.</p>
<p>If you’re enjoying these tips, please subscribe in your app. You can leave a rating and better yet, a comment in your app, too. I also accept subscriptions to @WeeklyDevTips on twitter and comments and requests for topics there or in the show comments, too. Thanks for all of your support!</p>
<h1>Sprints Versus Continuous Flow</h1>
<p>Sprint and iteration-based processes are stepping stones on the path from waterfall toward continuous flow. In this episode we'll make some comparisons to build and integration processes to demonstrate this.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>If you're not advancing as quickly in your career as you'd like, you may find value in joining a semi-formal career and technical coaching program like devBetter.com. devBetter is a small group of motivated developers meeting every week or two, and staying connected in the meantime via a private Slack community. I answer questions, review code, suggest areas in which to improve, and occasionally assign homework. Interested? Learn more at <a href="https://devbetter.com/">devBetter.com</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>I've been a fan of continuous integration, or CI, for many years. When I was first getting started in professional software development, CI was still new and unproven. Some of my first consulting engagements had me working on teams where there was a team member who was the designated integrator. Their job was to understand how to put all the components of the application together so that the app could be deployed. This was a major ordeal every couple of months when a deployment needed to be made.</p>
<p>In the 1990s, automated builds started to become increasingly popular. Tools like Ant, and later in .NET NAnt, were growing in popularity. Automated builds started to enable periodic scheduled integrations. Instead of having someone manually integrate and deploy the system every few months, these automated tools enabled weekly integrations, providing much more rapid feedback. Eventually, the frequency of these builds increased from weekly to daily (or more typically, nightly), and finally to the extreme of continuous integration. Continuous integration builds and tests the application every time a change is made to the application's source control.</p>
<p>It's hard to get much better than continuous integration, but there are still a couple of nice features that can and have been added. Today, I most of my projects use continuous integration, but continuous integration by itself doesn't prevent developers from breaking the build by checking in broken stuff to the main branch. Two features that tools like Azure DevOps and GitHub support now are the ability to run builds on pull requests and the ability to restrict merging pull requests so that they require a passing build before they can be pulled in. Adding in these two features eliminates the vast majority of broken build scenarios, ensuring the main branch of the application remains in a working state at all times.</p>
<p>So, what does this have to do with sprints? Before we had XP iterations and Scrum sprints, most software development used some kind of waterfall-like process. Iterations, such as they were, were quite long: months and sometimes years. Iterative development approaches popularized by agile software development recommended much shorter iterations, with many developer organizations shifting to 2- or 4-week iterations. Each iteration, the team would estimate the backlog, prioritize the work, plan out the iteration or sprint, commit to the plan, get work done, test it, try to deploy it, and potentially hold a retrospective about the iteration. It's not uncommon to look at iteration-based agile and compare it to a series of mini-waterfalls. The analogy from infrequent deployments to more frequent integrations is an easy one to see.</p>
<p>So, with integrations, there's an obvious spectrum of increased benefit associated with increased frequency. There aren't many dissenting voices crying out that continuous integration is a waste of time and we should only build software once a month. The feedback benefits of CI over even daily builds is quite clear. So, if you see a certain amount of benefit when going from long-term waterfall delivery to 4-week iterative delivery, it should be obvious that this benefit will increase further if you go from 4-week to 2-week. But most teams stop there. The reason why most teams never shorten their iterations below 2-week sprints is because of the pain involved in some of the required ceremonies that are tied to the sprint. I literally saw this happen last week, when a client initially planned on 1-week sprints but dropped back to 2-week sprints because there were too many meetings to make 1-week sprints work.</p>
<p>The issue is that the ceremonies eat into time to actually get work done. For instance, a reasonable retrospective probably takes an hour. Investing an hour every 2 weeks may seem reasonable, but what about every week, or every day? Estimating and prioritizing the backlog is a similarly painful part of most sprint plans - would it make sense to do it more often? This may sound crazy if you didn't listen to last week's episode yet, but give it some thought.</p>
<p>Here's the thing - these ceremonies aren't strictly tied to delivering software. You could increase or decrease your sprint cadence, and still have monthly retrospectives. The same is true for prioritizing work. You can still do it every two weeks while your sprints are one week long, if you want. You can even do it literally just-in-time as things are pulled from the backlog. Imagine how quick sprint planning sessions would be if they only had to choose the next item the dev team would start working on? You could do that 10 times a day with an email exchange if the product owner made it a priority.</p>
<p>Once you realize that really long iterations, like traditional waterfall, are not great, and shorter iterations are better, you should be able to make the jump to continuous flow pretty easily. If there are things that make this too painful, then <a href="/040">listen to the last episode</a>, and do those things more often. Or, realize they're not in the critical path to delivering software, and stop tying them to your software delivery cadence and schedule them on whatever cadence makes sense for your team.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="/040">If It Hurts, Do It More Often</a></li>
<li><a href="https://www.youtube.com/channel/UC1OeiOnqUZHVinzRK5MuHsA">See Visualizations and Subscribe to WeeklyDevTips in YouTube</a></li>
</ul>
<p>That’s it for this week. Next week we have a special guest as Robert &quot;Uncle Bob&quot; Martin will provide a couple of tips - be sure to check back for that. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="4338452" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/f9938728-b063-479a-90a5-a300e28e37b0/ec12baae_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Sprints Versus Continuous Flow</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/f9938728-b063-479a-90a5-a300e28e37b0/3000x3000/1551099560artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:07:01</itunes:duration>
      <itunes:summary>Sprint and iteration-based processes are stepping stones on the path from waterfall toward continuous flow. In this episode we&apos;ll make some comparisons to build and integration processes to demonstrate this.</itunes:summary>
      <itunes:subtitle>Sprint and iteration-based processes are stepping stones on the path from waterfall toward continuous flow. In this episode we&apos;ll make some comparisons to build and integration processes to demonstrate this.</itunes:subtitle>
      <itunes:keywords>software development, agile, continuous delivery, programming, dev ops, software, devops, kanban, continuous integration, scrum, xp</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>41</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">ab308bcf-47ae-4fcf-b639-8ac7182b9cb2</guid>
      <title>If It Hurts, Do It More Often</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 40, in which I'll talk about the paradoxical advice, &quot;if it hurts, do it more often.&quot;</p>
<p>If you’re enjoying these tips, please subscribe in your app. You can leave a rating and better yet, a comment in your app, too. I also accept subscriptions to @WeeklyDevTips on twitter and comments and requests for topics there or in the show comments, too. Thanks for all of your support!</p>
<h1>If It Hurts, Do It More Often</h1>
<p>I've meant to do an episode or article on this topic for a while. It's advice I've been giving to my mentoring and corporate clients for years. Let's dive in after a quick plug for this show's sponsor, devBetter.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>If you're not advancing as quickly in your career as you'd like, you may find value in joining a semi-formal career and technical coaching program like devBetter.com. devBetter is a small group of motivated developers meeting every week or two, and staying connected in the meantime via a private Slack community. I answer questions, review code, suggest areas in which to improve, and occasionally assign homework. Interested? Learn more at <a href="https://devbetter.com/">devBetter.com</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>I've given the advice &quot;if it hurts, do it more often&quot; for years, but in preparing for this episode I did some research on the phrase to see where I might have picked it up. I found a few articles, including a nice one from Martin Fowler, which I've linked from the show notes. I'll describe my own thoughts and how I usually present the concept, and then add in some of the interesting elements Fowler and others expand upon.</p>
<p>&quot;If it hurts, do it more often.&quot; On its face this phrase makes no sense. Putting your hand on a hot stove hurts... so, should you do that more often? Of course not. The advice applies to business and software processes, and the implied context is that whatever &quot;it&quot; is, it's something that you need to do as part of your process. You'll find that a list of painful-but-necessary activities involved in shipping working software includes almost every step of building software. Compiling. Integrating. Deploying. Installing. Debugging. Testing. Pretty much all of these activities are much more difficult and painful if you try and do them rarely compared to if you do them all the time.</p>
<p>So, if you find yourself looking at your process and making decisions in order to minimize how often you perform some necessary part of your process because it's painful, I'm going to go the other way and say do it MORE OFTEN, not less. There's a scene in the Tom Clancy story Clear and Present Danger in which Jack Ryan is in a briefing with the President, who is having to deal with some scandal involving a friend of his. The President's team are advising him to distance himself from his friend, but Jack speaks up and advises just the opposite. Instead of distancing, go the other way. If the press asks if you're friends, tell them you're LIFELONG friends. Don't give them anywhere to go with it. Everyone is aghast at this advice, but of course the president takes the advice and presumably it works out well for him. I feel just like Jack Ryan when I'm giving the counterintuitive advice of doing things more frequently despite how painful they are. It's only natural to minimize pain, and the obvious approach is avoidance. But this just increases how much pain there is when the task must, eventually be done.</p>
<p>When you force yourself to perform part of your process more frequently, the pain decreases dramatically. There are several reasons for this. The tasks becomes more familiar, you gain proficiency, you haven't forgotten what you did last time, and there's been less time to add scope and complexity between steps. All of these natural effects of putting less time between repetitions of the task result in less pain. There are also steps that your team will almost certainly take to reduce pain, like automation. If you have a painful task you do twice a year, it's almost certainly not worth automating. The effort involved in automation will only be recovered a couple of times per year. But if you are performing that same task every month, every week, or every day it very quickly starts to make sense to automate the parts of the process that you can. And once it's automated, the pain drops dramatically.</p>
<p>A client I work with used to have very painful deployments. They would only deploy every month or two, and doing so was always a big source of pain. Many team members would come into the office at 4am on a weekday to get ready for the deployment. The goal was to complete the deployment before customers came into the office that day. There were a lot of QA and dev team heroics. Most of the time, he deployment wouldn't be 100% successful, and often 2-3 or more additional small deployments would be required to address issues that were discovered in production. In discussing this problem, my recommendation was, wait for it, to deploy more often. Nobody really was excited by this notion, least of all the team members who were getting up at 4am for these deployment days. I decided to bet on my recommendation with data. The team didn't have a fixed deployment schedule, so there was enough variability that we could capture some statistics and draw some conclusions. I had the team start tracking the number of days since the last deployment, the number of bugs found post-deployment, and whether the deployment was successful, where success meant that it didn't need rolled back and didn't have any major problems.</p>
<p>They captured this data, along with trying to deploy a little more frequently, for a number of months. When we reviewed the data, it was clear that there was a direct correlation between failed deployments and number of days between deployments. This made sense, especially when the team reviewed the data and saw that most of the deployments that took place within very small time windows were just fixes to deployments that had just been made earlier that week. These deployments were made during regular business hours because they weren't considered high risk! With this data backing up the recommendation, the team was ready to buy into more frequent deployments. Last year, they doubled the number of deployments they made. It's February as I'm recording this show, and this year they're looking to double that number again, which will require multiple deployments per week.</p>
<p>Martin Fowler's article on this topic notes that many of these activities have an amount of pain that increases dramatically as a function of time between repetitions. There's an exponential increase in pain as time increases, and this is why it makes sense to increases the frequency of the task. Not all activities will necessarily have this exponential increase in pain relative to time, but if you suspect part of your process does, see if you can boost its frequency. The most obvious cause of this exponential relationship is complexity. Working with large, complex things is exponentially more difficult compared to a series of small, simple things. This is why pull requests should be small and focus on one thing. It's why methods and classes should be small and focused. And it's a reason why parts of your software process should be pipelines working on small changes rather than huge, stressful ordeals that only happen once in a blue moon.</p>
<p>Incidentally, this same concept is one of the reasons I prefer Kanban to Scrum and other sprint-based processes, but perhaps I'll cover that in another episode.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://martinfowler.com/bliki/FrequencyReducesDifficulty.html">Frequency Reduces Difficulty</a></li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 18 Feb 2019 07:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 40, in which I'll talk about the paradoxical advice, &quot;if it hurts, do it more often.&quot;</p>
<p>If you’re enjoying these tips, please subscribe in your app. You can leave a rating and better yet, a comment in your app, too. I also accept subscriptions to @WeeklyDevTips on twitter and comments and requests for topics there or in the show comments, too. Thanks for all of your support!</p>
<h1>If It Hurts, Do It More Often</h1>
<p>I've meant to do an episode or article on this topic for a while. It's advice I've been giving to my mentoring and corporate clients for years. Let's dive in after a quick plug for this show's sponsor, devBetter.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>If you're not advancing as quickly in your career as you'd like, you may find value in joining a semi-formal career and technical coaching program like devBetter.com. devBetter is a small group of motivated developers meeting every week or two, and staying connected in the meantime via a private Slack community. I answer questions, review code, suggest areas in which to improve, and occasionally assign homework. Interested? Learn more at <a href="https://devbetter.com/">devBetter.com</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>I've given the advice &quot;if it hurts, do it more often&quot; for years, but in preparing for this episode I did some research on the phrase to see where I might have picked it up. I found a few articles, including a nice one from Martin Fowler, which I've linked from the show notes. I'll describe my own thoughts and how I usually present the concept, and then add in some of the interesting elements Fowler and others expand upon.</p>
<p>&quot;If it hurts, do it more often.&quot; On its face this phrase makes no sense. Putting your hand on a hot stove hurts... so, should you do that more often? Of course not. The advice applies to business and software processes, and the implied context is that whatever &quot;it&quot; is, it's something that you need to do as part of your process. You'll find that a list of painful-but-necessary activities involved in shipping working software includes almost every step of building software. Compiling. Integrating. Deploying. Installing. Debugging. Testing. Pretty much all of these activities are much more difficult and painful if you try and do them rarely compared to if you do them all the time.</p>
<p>So, if you find yourself looking at your process and making decisions in order to minimize how often you perform some necessary part of your process because it's painful, I'm going to go the other way and say do it MORE OFTEN, not less. There's a scene in the Tom Clancy story Clear and Present Danger in which Jack Ryan is in a briefing with the President, who is having to deal with some scandal involving a friend of his. The President's team are advising him to distance himself from his friend, but Jack speaks up and advises just the opposite. Instead of distancing, go the other way. If the press asks if you're friends, tell them you're LIFELONG friends. Don't give them anywhere to go with it. Everyone is aghast at this advice, but of course the president takes the advice and presumably it works out well for him. I feel just like Jack Ryan when I'm giving the counterintuitive advice of doing things more frequently despite how painful they are. It's only natural to minimize pain, and the obvious approach is avoidance. But this just increases how much pain there is when the task must, eventually be done.</p>
<p>When you force yourself to perform part of your process more frequently, the pain decreases dramatically. There are several reasons for this. The tasks becomes more familiar, you gain proficiency, you haven't forgotten what you did last time, and there's been less time to add scope and complexity between steps. All of these natural effects of putting less time between repetitions of the task result in less pain. There are also steps that your team will almost certainly take to reduce pain, like automation. If you have a painful task you do twice a year, it's almost certainly not worth automating. The effort involved in automation will only be recovered a couple of times per year. But if you are performing that same task every month, every week, or every day it very quickly starts to make sense to automate the parts of the process that you can. And once it's automated, the pain drops dramatically.</p>
<p>A client I work with used to have very painful deployments. They would only deploy every month or two, and doing so was always a big source of pain. Many team members would come into the office at 4am on a weekday to get ready for the deployment. The goal was to complete the deployment before customers came into the office that day. There were a lot of QA and dev team heroics. Most of the time, he deployment wouldn't be 100% successful, and often 2-3 or more additional small deployments would be required to address issues that were discovered in production. In discussing this problem, my recommendation was, wait for it, to deploy more often. Nobody really was excited by this notion, least of all the team members who were getting up at 4am for these deployment days. I decided to bet on my recommendation with data. The team didn't have a fixed deployment schedule, so there was enough variability that we could capture some statistics and draw some conclusions. I had the team start tracking the number of days since the last deployment, the number of bugs found post-deployment, and whether the deployment was successful, where success meant that it didn't need rolled back and didn't have any major problems.</p>
<p>They captured this data, along with trying to deploy a little more frequently, for a number of months. When we reviewed the data, it was clear that there was a direct correlation between failed deployments and number of days between deployments. This made sense, especially when the team reviewed the data and saw that most of the deployments that took place within very small time windows were just fixes to deployments that had just been made earlier that week. These deployments were made during regular business hours because they weren't considered high risk! With this data backing up the recommendation, the team was ready to buy into more frequent deployments. Last year, they doubled the number of deployments they made. It's February as I'm recording this show, and this year they're looking to double that number again, which will require multiple deployments per week.</p>
<p>Martin Fowler's article on this topic notes that many of these activities have an amount of pain that increases dramatically as a function of time between repetitions. There's an exponential increase in pain as time increases, and this is why it makes sense to increases the frequency of the task. Not all activities will necessarily have this exponential increase in pain relative to time, but if you suspect part of your process does, see if you can boost its frequency. The most obvious cause of this exponential relationship is complexity. Working with large, complex things is exponentially more difficult compared to a series of small, simple things. This is why pull requests should be small and focus on one thing. It's why methods and classes should be small and focused. And it's a reason why parts of your software process should be pipelines working on small changes rather than huge, stressful ordeals that only happen once in a blue moon.</p>
<p>Incidentally, this same concept is one of the reasons I prefer Kanban to Scrum and other sprint-based processes, but perhaps I'll cover that in another episode.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://martinfowler.com/bliki/FrequencyReducesDifficulty.html">Frequency Reduces Difficulty</a></li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="5361809" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/3cc4e155-5b54-4f2f-be55-e0131a45e2e0/75ce7e48_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>If It Hurts, Do It More Often</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/3cc4e155-5b54-4f2f-be55-e0131a45e2e0/3000x3000/1550504086artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:08:12</itunes:duration>
      <itunes:summary>&quot;If it hurts, do it more often.&quot; On its face this phrase makes no sense. Putting your hand on a hot stove hurts... so, should you do that more often? Of course not. The advice applies to business and software processes, and the implied context is that whatever &quot;it&quot; is, it&apos;s something that you need to do as part of your process.</itunes:summary>
      <itunes:subtitle>&quot;If it hurts, do it more often.&quot; On its face this phrase makes no sense. Putting your hand on a hot stove hurts... so, should you do that more often? Of course not. The advice applies to business and software processes, and the implied context is that whatever &quot;it&quot; is, it&apos;s something that you need to do as part of your process.</itunes:subtitle>
      <itunes:keywords>software development, agile, continuous delivery, programming, dev ops, software, devops, continuous integration, scrum, xp</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>40</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">03d0ca60-ce9d-4816-af59-5cf024863e6e</guid>
      <title>Better Code Reviews</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 39, in which I'll talk a bit about how to make code reviews a little less painful of an experience.</p>
<p>If you’re enjoying these tips, please leave a comment or rating in your podcast app, tell a friend about the podcast, or follow us on twitter and retweet our episode announcements. There are millions of software developers in the world; help me try to reach a few more of them with these tips.</p>
<h1>Better Code Reviews</h1>
<p>I wrote an article about a year ago about <a href="https://ardalis.com/positive-reinforcement-in-code-reviews">Positive Reinforcement in Code Reviews</a>. It generated a lot of feedback (on twitter if not in the article itself), so I thought I'd dedicate a Weekly Dev Tips episode to the topic.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>If you're not advancing as quickly in your career as you'd like, you may find value in joining a semi-formal career and technical coaching program like devBetter.com. I launched <a href="https://devbetter.com/">devBetter</a> a few months ago and so far we have a small group of motivated developers meeting every week or two. I answer questions, review code, suggest areas in which to improve, and occasionally assign homework. Interested? Learn more at <a href="https://devbetter.com/">devBetter.com</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>I remember my first internship in college working in a professional software development team. It was at a big company not too far from campus. The building was a three story rectangle. The second floor was basically a giant single room - you could see out the windows on all sides. In the middle were cubicles. Hundreds of cubicles. One of these became mine while I worked there. I was given a work computer, a bunch of 3-ring binders full of documentation, and once a week there was a code review that I participated in.</p>
<p>I say I participated, but the internship didn't last very long and I spent most of my time fixing relatively simple bugs in C code, along with trying not to fall asleep while working through documentation binders. Thus, during the weekly code reviews, I mostly listened. These code reviews were conducted by the development manager. The week's updates were printed out and marked up by hand with questions and suggestions. From my perspective it was mostly a one-way conversation, though occasionally the more senior developers on the team would have a discussion about the code in question. The reviews weren't particularly insightful to me at the time, but the process itself stuck with me.</p>
<p>I understood the intent of the reviews - to up the quality of the code - but the process reminded me more of getting an essay back from a professor marked up in red than of teamwork and collaboration. And the relative infrequency of the reviews meant that, more often than not, the printed updates being discussed were no longer current anyway. A fact that often resulted in discussions about whether it was worth making recommended changes at this point, due to the rework it would require.</p>
<p>Over a decade later I found myself working at another company whose developers were required to conduct code reviews. This team's process was slightly different, in that each week a different senior developer took on the reviewer responsibility, and the reviews were done without any discussion or meeting. Once a week, whoever was in the reviewer role would go through the version control history and review all updates made in the last week (since the previous reviewer had done so). Any questions, suggestions, or changes were done in the form of TODO comments and emails, with management mandates that such requests be dealt with in a timely manner. It wasn't unusual, however, for deadline pressure to cause the review queue to build up, resulting in much more work to review or possibly in abandoning reviews for some period in order to get caught up.</p>
<p>In both of these cases, there were two major problems with the code review process. First, it didn't happen fast enough. Frequently reviews were looking at code that was days or often more than a week old, which on projects under active development meant that the team had long since moved on by the time the review was taking place. Second, the reviews felt more like the code author was being graded or evaluated than like the team was working together.</p>
<p><em>Fix this.</em></p>
<p><em>This is a bad name. Come up with something better.</em></p>
<p><em>You didn't follow the coding standard here.</em></p>
<p>So, what can we do differently today? Here are some quick tips - apply the ones that you think will work best for you and your team. First, do code reviews as early as possible. The earliest way is by collaborating while you're writing the code. I'm a fan of using <a href="https://www.pluralsight.com/courses/pair-programming">pair programming</a> especially on mission-critical code, and if you've ever asked for a coworker to take a look at what you're doing to help you out, you understand the value having another team member participating can bring. Code reviews can certainly still be helpful even for code written by a pair, but the pair should catch a lot of problems so early that you may not even realize it.</p>
<p>If collaborating while you code is too extreme for you or your organization, the next best thing is gated checkins. Many source control systems support this approach. My favorite at the moment is GitHub, who basically invented the idea and term pull request. A pull request is a conversation that happens about a change <em>before it is made to the main source code branch</em>. Teams I work with today use pull requests and reviews to ensure another team member looks over every PR before it's merged into the project's codebase. Usually the time from &quot;hey can someone look at this PR for me&quot; to someone actually reviewing it is under 10 minutes, because of notifications, Slack channels, and tight feedback loops.</p>
<p>Of course, maybe you don't <em>want</em> code reviews to happen more often. Maybe you don't <em>want</em> someone to look at your beautiful code - and maybe call it ugly - right after you've declared it's perfect. Part of that might have to do with how your team reviews code. Code reviews are an opportunity not only to catch and fix problems but also to encourage and recognize the good stuff. Positive reinforcement works, and can help make code reviews less painful and thus more useful, as well as providing another way to get your coworkers to write what you think is better code.</p>
<p>If a sincere accolade or positive message seems too cheesy for your tastes, consider easing up on the negativity by asking more questions and helping the author of the code arrive at a better solution themselves. Instead of saying &quot;This code is a mess!&quot; you might say &quot;I'm having trouble understanding this code - could we work to make its intent more clear?&quot; A related approach is to have a face to face or separate IM conversation with the author so you can have a more candid conversation that's not in front of the whole team (or company or world). As a rule it's better to offer praise in public but harsh criticism privately, and in any case it may be that you simply don't have all the information and a quick conversation will save you and the author a lot of trouble.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://www.pluralsight.com/courses/pair-programming">Pair Programming Course</a></li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and we’ll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 11 Feb 2019 07:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 39, in which I'll talk a bit about how to make code reviews a little less painful of an experience.</p>
<p>If you’re enjoying these tips, please leave a comment or rating in your podcast app, tell a friend about the podcast, or follow us on twitter and retweet our episode announcements. There are millions of software developers in the world; help me try to reach a few more of them with these tips.</p>
<h1>Better Code Reviews</h1>
<p>I wrote an article about a year ago about <a href="https://ardalis.com/positive-reinforcement-in-code-reviews">Positive Reinforcement in Code Reviews</a>. It generated a lot of feedback (on twitter if not in the article itself), so I thought I'd dedicate a Weekly Dev Tips episode to the topic.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>If you're not advancing as quickly in your career as you'd like, you may find value in joining a semi-formal career and technical coaching program like devBetter.com. I launched <a href="https://devbetter.com/">devBetter</a> a few months ago and so far we have a small group of motivated developers meeting every week or two. I answer questions, review code, suggest areas in which to improve, and occasionally assign homework. Interested? Learn more at <a href="https://devbetter.com/">devBetter.com</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>I remember my first internship in college working in a professional software development team. It was at a big company not too far from campus. The building was a three story rectangle. The second floor was basically a giant single room - you could see out the windows on all sides. In the middle were cubicles. Hundreds of cubicles. One of these became mine while I worked there. I was given a work computer, a bunch of 3-ring binders full of documentation, and once a week there was a code review that I participated in.</p>
<p>I say I participated, but the internship didn't last very long and I spent most of my time fixing relatively simple bugs in C code, along with trying not to fall asleep while working through documentation binders. Thus, during the weekly code reviews, I mostly listened. These code reviews were conducted by the development manager. The week's updates were printed out and marked up by hand with questions and suggestions. From my perspective it was mostly a one-way conversation, though occasionally the more senior developers on the team would have a discussion about the code in question. The reviews weren't particularly insightful to me at the time, but the process itself stuck with me.</p>
<p>I understood the intent of the reviews - to up the quality of the code - but the process reminded me more of getting an essay back from a professor marked up in red than of teamwork and collaboration. And the relative infrequency of the reviews meant that, more often than not, the printed updates being discussed were no longer current anyway. A fact that often resulted in discussions about whether it was worth making recommended changes at this point, due to the rework it would require.</p>
<p>Over a decade later I found myself working at another company whose developers were required to conduct code reviews. This team's process was slightly different, in that each week a different senior developer took on the reviewer responsibility, and the reviews were done without any discussion or meeting. Once a week, whoever was in the reviewer role would go through the version control history and review all updates made in the last week (since the previous reviewer had done so). Any questions, suggestions, or changes were done in the form of TODO comments and emails, with management mandates that such requests be dealt with in a timely manner. It wasn't unusual, however, for deadline pressure to cause the review queue to build up, resulting in much more work to review or possibly in abandoning reviews for some period in order to get caught up.</p>
<p>In both of these cases, there were two major problems with the code review process. First, it didn't happen fast enough. Frequently reviews were looking at code that was days or often more than a week old, which on projects under active development meant that the team had long since moved on by the time the review was taking place. Second, the reviews felt more like the code author was being graded or evaluated than like the team was working together.</p>
<p><em>Fix this.</em></p>
<p><em>This is a bad name. Come up with something better.</em></p>
<p><em>You didn't follow the coding standard here.</em></p>
<p>So, what can we do differently today? Here are some quick tips - apply the ones that you think will work best for you and your team. First, do code reviews as early as possible. The earliest way is by collaborating while you're writing the code. I'm a fan of using <a href="https://www.pluralsight.com/courses/pair-programming">pair programming</a> especially on mission-critical code, and if you've ever asked for a coworker to take a look at what you're doing to help you out, you understand the value having another team member participating can bring. Code reviews can certainly still be helpful even for code written by a pair, but the pair should catch a lot of problems so early that you may not even realize it.</p>
<p>If collaborating while you code is too extreme for you or your organization, the next best thing is gated checkins. Many source control systems support this approach. My favorite at the moment is GitHub, who basically invented the idea and term pull request. A pull request is a conversation that happens about a change <em>before it is made to the main source code branch</em>. Teams I work with today use pull requests and reviews to ensure another team member looks over every PR before it's merged into the project's codebase. Usually the time from &quot;hey can someone look at this PR for me&quot; to someone actually reviewing it is under 10 minutes, because of notifications, Slack channels, and tight feedback loops.</p>
<p>Of course, maybe you don't <em>want</em> code reviews to happen more often. Maybe you don't <em>want</em> someone to look at your beautiful code - and maybe call it ugly - right after you've declared it's perfect. Part of that might have to do with how your team reviews code. Code reviews are an opportunity not only to catch and fix problems but also to encourage and recognize the good stuff. Positive reinforcement works, and can help make code reviews less painful and thus more useful, as well as providing another way to get your coworkers to write what you think is better code.</p>
<p>If a sincere accolade or positive message seems too cheesy for your tastes, consider easing up on the negativity by asking more questions and helping the author of the code arrive at a better solution themselves. Instead of saying &quot;This code is a mess!&quot; you might say &quot;I'm having trouble understanding this code - could we work to make its intent more clear?&quot; A related approach is to have a face to face or separate IM conversation with the author so you can have a more candid conversation that's not in front of the whole team (or company or world). As a rule it's better to offer praise in public but harsh criticism privately, and in any case it may be that you simply don't have all the information and a quick conversation will save you and the author a lot of trouble.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://www.pluralsight.com/courses/pair-programming">Pair Programming Course</a></li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and we’ll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="4367704" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/6e9a80b6-ffef-4ecf-85c2-319ff42be454/532c55d2_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Better Code Reviews</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/6e9a80b6-ffef-4ecf-85c2-319ff42be454/3000x3000/1549862062artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:07:31</itunes:duration>
      <itunes:summary>I wrote an article about a year ago about [Positive Reinforcement in Code Reviews](https://ardalis.com/positive-reinforcement-in-code-reviews). It generated a lot of feedback (on twitter if not in the article itself), so I thought I&apos;d dedicate a Weekly Dev Tips episode to the topic.</itunes:summary>
      <itunes:subtitle>I wrote an article about a year ago about [Positive Reinforcement in Code Reviews](https://ardalis.com/positive-reinforcement-in-code-reviews). It generated a lot of feedback (on twitter if not in the article itself), so I thought I&apos;d dedicate a Weekly Dev Tips episode to the topic.</itunes:subtitle>
      <itunes:keywords>agile software development, github, code reviews, clean code, programming, pair programming, extreme programming</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>39</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">04fdb7f7-7c91-4119-ae45-7a0c9bc76105</guid>
      <title>How do you get so much done?</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 38, in which I'll offer some personal productivity tips.</p>
<p>If you’re enjoying these tips, please leave a comment or rating in your podcast app, tell a friend about the podcast, or follow us on twitter and retweet our episode announcements. All these things help increase the reach of this podcast, so more people can benefit from these tips.</p>
<h1>Getting stuff done</h1>
<p>Occasionally I get asked questions like this one that came from a LinkedIn connection. He wrote, &quot;how in the world do you accomplish so much? Would love to know the strategy.&quot; I'm flattered of course, but it's not the first time someone's claimed to be impressed by how much I get done, so I thought I'd share a bit about my approach.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>If you're not advancing as quickly in your career as you'd like, you may find value in joining a semi-formal career and technical coaching program like devBetter.com. I launched devBetter a few months ago and so far we have a small group of motivated developers meeting every week or two. I answer questions, review code, suggest areas in which to improve, and occasionally assign homework. Interested? Learn more at devBetter.com.</p>
<h2>Show Notes / Transcript</h2>
<p>So, &quot;how do I get so much done?&quot; Let me start out by saying that I try to be pretty modest. I don't have superpowers. I'm not Bill Gates or Elon Musk, either, with billions of dollars. I don't even have online following of Scott Hanselman or Robert Martin or dozens of others. But I do alright, and I'm willing to share how that is a bit here.</p>
<p>First, I made a realization years ago that every day I have 24 hours to utilize. No more and no less (except twice a year because of stupid daylight savings time). I used to say &quot;I don't have time&quot; for this or that. I'm sure I still say that sometimes, but at least in my head I try to remember that what I actually mean is &quot;I choose not to make time&quot; for it. It may be that you're in a position where you literally do not have control over your time, such as if you're in the military or in prison for example. But unless someone is directly controlling your freedom to choose how to spend your time, your use of time is a choice. Embrace that.</p>
<p>Next, decide where your priorities are. What do you want out of your life? What does success look like to you. If you're a gamer, you can approach life like a strategy game. What's your strategy? Are you trying to max out income? Optimize for the best possible family? Slide through with as few commitments as possible? For me I'd say I'm following the fairly common strategy of trying to maximize my family's well-being while achieving success in my career. Within that strategy I'm focusing on entpreneurship and maximizing how many others I can help, as opposed to trying to climb as high up a corporate ladder as possible. Not having a strategy just means you're letting someone else choose your moves. Figure out what your strategy is, then figure out if the moves you're making - i.e. the way you're spending your time - is in line with what you think your strategy is. Remember, &quot;How we spend our days is how we spend our lives.&quot; (<a href="https://www.goodreads.com/author/quotes/5209.Annie_Dillard">Annie Dillard</a>). Be sure you're spending your time wisely - it's the most precious resource you have.</p>
<p>Ok, so that's the high level strategy side of the equation. At the tactical level, there are a few things I do that probably at least make it look like I'm being super productive. First, I minimize my commute. In the past I've had commutes of as long as an hour into work in some city where I then had the privilege of paying an obscene amount of money to park my car every day. Now, I can work from home if I choose or I have about a 10 minute country road drive to my office, which is also just a few minutes from my kids' school so it's often convenient when dropping off or picking up kids (there's no bus so driving them is one of those things my wife and I &quot;get to&quot; make time to do most weekdays). Not having that commute adds up. If I'm spending 10 minutes instead of 60 minutes twice a day driving, that's 100 minutes per day of bonus productivity. Think about that for a few minutes. Now, if we get self-driving cars maybe that commute time can be used productively (or if you're lucky enough to have decent public transportation). But until then I optimize for minimal time wasted on commuting.</p>
<p>Another thing I do is minimize time spent on TV. I watch some, but pretty much only with family members as we enjoy time together, or occasionally when working out. I'm not perfect on this front, and recently I've been spending more time than I used to on video games which can suck up at least as much time as binging Netflix, but the idea is to be mindful of how much time you're spending on this and make sure you're OK with it. If you decide it's more time than you'd like to have invested in that, figure out a way to adjust. Also, if you're spending a ton of money on cable, consider dropping that cost in favor of nothing or a much cheaper Netflix or Amazon Prime subscription, which typically costs as much per year as cable with lots of channels does per month. This saves you time and money.</p>
<p>Here's a simple, crazy idea. Typing speed. I produce a fair bit of content, between blog posts, podcasts (I script them ahead of time), writing actual code, emails with folks, social media, etc. I'm a pretty fast touch typist. I doubt that I'd set any records, but just last week at a client multiple students in my workshop were impressed by my typing speed (and asked me to slow down, which of course I did). If you want to get more done and you work at a computer keyboard all day then for the love of sanity learn to type faster! It's a skill that is relatively easy to learn and will pay off in no time. Is it the only thing that matters? Is writing software just monkey work where the bottleneck is typing? Of course not. But it 100% definitely helps and I've never once thought to myself &quot;Boy, it sure is a useless skill to be able to type quickly. I wish I'd spent those hours learning to type watching TV instead.&quot;</p>
<p>Something else I do that maybe you all don't is google stuff constantly. I was streaming last week and someone new hopped into the chat and was like &quot;Oh, I thought this was someone who knew what they're doing but you keep googling basic stuff.&quot; I was slightly offended, and that's part of what you get when you watch someone streaming live as opposed to a pre-recorded course like on Pluralsight is you see how they actually work. When I'm actually working, I'm looking stuff up. All. The. Time. I'm googling stuff with my own name in the search to see my own things I've done before. I search for stuff in the ASP.NET Core docs all the time <em>that I wrote myself</em> but which I don't keep rattling around in my head forever. Remember there are two kinds of knowledge: things you know and things you know how to find. Knowing stuff is great. Knowing how to find stuff quickly is great, too. Of course the second one is only helpful if you use that skill, so however long you currently wait before breaking down and searching for a solution, think about reducing that and start searching sooner if you want to get more done, faster.</p>
<p>I could go on but I need to wrap this up so we'll end with one last one which is that you need to ship. <a href="https://deviq.com/shipping-is-a-feature/">&quot;Shipping is a feature.&quot;</a> and <a href="https://en.wikipedia.org/wiki/Perfect_is_the_enemy_of_good">&quot;Perfect is the enemy of good.&quot;</a> It looks like I'm productive because I'm constantly producing things. They're not perfect. They usually need work. But they're good enough to get out into the world where others can benefit from them and/or provide feedback that I can use to iterate. Don't feel like you can't start something because you don't have all the details figured out yet. Just get started. And don't wait to publish your 10 page article on your blog because it's not perfect yet. Publish the first 2 pages and call it Part 1.</p>
<p>Hopefully at least some of that is useful to you. I'm not a fitness guru who gets up at 5, works out, never eats anything unhealthy, and only works 2 hours a day. I have 4 kids, including 4-year-old twins, and I choose to spend a lot of my time doing things with or for them. That means I need to make my remaining time count, and these are some of the ways I do that today. I'm constantly learning and trying to find ways to be more effective, though, so if you have a tip you'd like to share please leave a comment on the show at weeklydevtips.com.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://www.typing.com/student/test/1">Take a free 1 minute typing test</a> (Steve scored 81 WPM with 97% accuracy as an example)</li>
<li><a href="https://www.youtube.com/watch?v=cc_FoTuP41M">Recording of Steve Walking and Typing at Different Speeds</a> for science!</li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> now. Thank you for subscribing to Weekly Dev Tips, and we’ll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 4 Feb 2019 07:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 38, in which I'll offer some personal productivity tips.</p>
<p>If you’re enjoying these tips, please leave a comment or rating in your podcast app, tell a friend about the podcast, or follow us on twitter and retweet our episode announcements. All these things help increase the reach of this podcast, so more people can benefit from these tips.</p>
<h1>Getting stuff done</h1>
<p>Occasionally I get asked questions like this one that came from a LinkedIn connection. He wrote, &quot;how in the world do you accomplish so much? Would love to know the strategy.&quot; I'm flattered of course, but it's not the first time someone's claimed to be impressed by how much I get done, so I thought I'd share a bit about my approach.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>If you're not advancing as quickly in your career as you'd like, you may find value in joining a semi-formal career and technical coaching program like devBetter.com. I launched devBetter a few months ago and so far we have a small group of motivated developers meeting every week or two. I answer questions, review code, suggest areas in which to improve, and occasionally assign homework. Interested? Learn more at devBetter.com.</p>
<h2>Show Notes / Transcript</h2>
<p>So, &quot;how do I get so much done?&quot; Let me start out by saying that I try to be pretty modest. I don't have superpowers. I'm not Bill Gates or Elon Musk, either, with billions of dollars. I don't even have online following of Scott Hanselman or Robert Martin or dozens of others. But I do alright, and I'm willing to share how that is a bit here.</p>
<p>First, I made a realization years ago that every day I have 24 hours to utilize. No more and no less (except twice a year because of stupid daylight savings time). I used to say &quot;I don't have time&quot; for this or that. I'm sure I still say that sometimes, but at least in my head I try to remember that what I actually mean is &quot;I choose not to make time&quot; for it. It may be that you're in a position where you literally do not have control over your time, such as if you're in the military or in prison for example. But unless someone is directly controlling your freedom to choose how to spend your time, your use of time is a choice. Embrace that.</p>
<p>Next, decide where your priorities are. What do you want out of your life? What does success look like to you. If you're a gamer, you can approach life like a strategy game. What's your strategy? Are you trying to max out income? Optimize for the best possible family? Slide through with as few commitments as possible? For me I'd say I'm following the fairly common strategy of trying to maximize my family's well-being while achieving success in my career. Within that strategy I'm focusing on entpreneurship and maximizing how many others I can help, as opposed to trying to climb as high up a corporate ladder as possible. Not having a strategy just means you're letting someone else choose your moves. Figure out what your strategy is, then figure out if the moves you're making - i.e. the way you're spending your time - is in line with what you think your strategy is. Remember, &quot;How we spend our days is how we spend our lives.&quot; (<a href="https://www.goodreads.com/author/quotes/5209.Annie_Dillard">Annie Dillard</a>). Be sure you're spending your time wisely - it's the most precious resource you have.</p>
<p>Ok, so that's the high level strategy side of the equation. At the tactical level, there are a few things I do that probably at least make it look like I'm being super productive. First, I minimize my commute. In the past I've had commutes of as long as an hour into work in some city where I then had the privilege of paying an obscene amount of money to park my car every day. Now, I can work from home if I choose or I have about a 10 minute country road drive to my office, which is also just a few minutes from my kids' school so it's often convenient when dropping off or picking up kids (there's no bus so driving them is one of those things my wife and I &quot;get to&quot; make time to do most weekdays). Not having that commute adds up. If I'm spending 10 minutes instead of 60 minutes twice a day driving, that's 100 minutes per day of bonus productivity. Think about that for a few minutes. Now, if we get self-driving cars maybe that commute time can be used productively (or if you're lucky enough to have decent public transportation). But until then I optimize for minimal time wasted on commuting.</p>
<p>Another thing I do is minimize time spent on TV. I watch some, but pretty much only with family members as we enjoy time together, or occasionally when working out. I'm not perfect on this front, and recently I've been spending more time than I used to on video games which can suck up at least as much time as binging Netflix, but the idea is to be mindful of how much time you're spending on this and make sure you're OK with it. If you decide it's more time than you'd like to have invested in that, figure out a way to adjust. Also, if you're spending a ton of money on cable, consider dropping that cost in favor of nothing or a much cheaper Netflix or Amazon Prime subscription, which typically costs as much per year as cable with lots of channels does per month. This saves you time and money.</p>
<p>Here's a simple, crazy idea. Typing speed. I produce a fair bit of content, between blog posts, podcasts (I script them ahead of time), writing actual code, emails with folks, social media, etc. I'm a pretty fast touch typist. I doubt that I'd set any records, but just last week at a client multiple students in my workshop were impressed by my typing speed (and asked me to slow down, which of course I did). If you want to get more done and you work at a computer keyboard all day then for the love of sanity learn to type faster! It's a skill that is relatively easy to learn and will pay off in no time. Is it the only thing that matters? Is writing software just monkey work where the bottleneck is typing? Of course not. But it 100% definitely helps and I've never once thought to myself &quot;Boy, it sure is a useless skill to be able to type quickly. I wish I'd spent those hours learning to type watching TV instead.&quot;</p>
<p>Something else I do that maybe you all don't is google stuff constantly. I was streaming last week and someone new hopped into the chat and was like &quot;Oh, I thought this was someone who knew what they're doing but you keep googling basic stuff.&quot; I was slightly offended, and that's part of what you get when you watch someone streaming live as opposed to a pre-recorded course like on Pluralsight is you see how they actually work. When I'm actually working, I'm looking stuff up. All. The. Time. I'm googling stuff with my own name in the search to see my own things I've done before. I search for stuff in the ASP.NET Core docs all the time <em>that I wrote myself</em> but which I don't keep rattling around in my head forever. Remember there are two kinds of knowledge: things you know and things you know how to find. Knowing stuff is great. Knowing how to find stuff quickly is great, too. Of course the second one is only helpful if you use that skill, so however long you currently wait before breaking down and searching for a solution, think about reducing that and start searching sooner if you want to get more done, faster.</p>
<p>I could go on but I need to wrap this up so we'll end with one last one which is that you need to ship. <a href="https://deviq.com/shipping-is-a-feature/">&quot;Shipping is a feature.&quot;</a> and <a href="https://en.wikipedia.org/wiki/Perfect_is_the_enemy_of_good">&quot;Perfect is the enemy of good.&quot;</a> It looks like I'm productive because I'm constantly producing things. They're not perfect. They usually need work. But they're good enough to get out into the world where others can benefit from them and/or provide feedback that I can use to iterate. Don't feel like you can't start something because you don't have all the details figured out yet. Just get started. And don't wait to publish your 10 page article on your blog because it's not perfect yet. Publish the first 2 pages and call it Part 1.</p>
<p>Hopefully at least some of that is useful to you. I'm not a fitness guru who gets up at 5, works out, never eats anything unhealthy, and only works 2 hours a day. I have 4 kids, including 4-year-old twins, and I choose to spend a lot of my time doing things with or for them. That means I need to make my remaining time count, and these are some of the ways I do that today. I'm constantly learning and trying to find ways to be more effective, though, so if you have a tip you'd like to share please leave a comment on the show at weeklydevtips.com.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://www.typing.com/student/test/1">Take a free 1 minute typing test</a> (Steve scored 81 WPM with 97% accuracy as an example)</li>
<li><a href="https://www.youtube.com/watch?v=cc_FoTuP41M">Recording of Steve Walking and Typing at Different Speeds</a> for science!</li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> now. Thank you for subscribing to Weekly Dev Tips, and we’ll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="8303817" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/770ee18a-9577-48e3-9c6f-304c5304d720/bb3796f1_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>How do you get so much done?</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/770ee18a-9577-48e3-9c6f-304c5304d720/3000x3000/1548620506artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:13:17</itunes:duration>
      <itunes:summary>Occasionally I get asked questions like this one that came from a LinkedIn connection. He wrote, &quot;how in the world do you accomplish so much? Would love to know the strategy.&quot; I&apos;m flattered of course, but it&apos;s not the first time someone&apos;s claimed to be impressed by how much I get done, so I thought I&apos;d share a bit about my approach.</itunes:summary>
      <itunes:subtitle>Occasionally I get asked questions like this one that came from a LinkedIn connection. He wrote, &quot;how in the world do you accomplish so much? Would love to know the strategy.&quot; I&apos;m flattered of course, but it&apos;s not the first time someone&apos;s claimed to be impressed by how much I get done, so I thought I&apos;d share a bit about my approach.</itunes:subtitle>
      <itunes:keywords>productivity, time management</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>38</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">dfa9bf8e-0a66-41b4-a03a-ace0a9356462</guid>
      <title>Debugging Tips</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 37, in which I'll talk a bit about how I debug problems I find in my code.</p>
<p>If you’re enjoying these tips, please leave a comment or rating in your podcast app, tell a friend about the podcast, or follow us on twitter and retweet our episode announcements. All these things help increase the reach of this podcast, so more people can benefit from these tips.</p>
<h1>Debugging Tip</h1>
<p>This week's tip is by request via twitter from Bernard FitzGerald (@bernimfitz) who wrote &quot;How about an episode devoted to effective debugging? I think that would be interesting to hear your methodology of tracking down a bug.&quot; Well, Bernard, this bug's for you. Sorry, lame beer commercial joke. On that note, here's a commercial...</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>If you're not advancing as quickly in your career as you'd like, you may find value in joining a semi-formal career and technical coaching program like devBetter.com. I launched devBetter a few months ago and so far we have a small group of motivated developers meeting every week or two. I answer questions, review code, suggest areas in which to improve, and occasionally assign homework. Interested? Learn more at devBetter.com.</p>
<h2>Show Notes / Transcript</h2>
<p>Let's talk a bit about debugging. Let me start off with a couple of personal observations. First, I think debuggers are amazing. Having the ability to magically stop time in the middle of your application anywhere you want and see exactly what the state of everything is there is like a super power. It far outstrips using console output and checking a log file or terminal window for logged output like &quot;got here&quot; and &quot;got here 2&quot;. Those were dark days.</p>
<p>And second, despite how amazing they are, I almost never use the debugger. One tip I give all the time to students in my workshops is that they learn to use ctrl-F5 instead of F5 to launch their applications because it's so much faster. In my experience, 90% or more of the time you're not actually debugging when you launch your application, and in a recent experiment I ran it took about a second to launch an ASP.NET Core app without the debugger and about 10 seconds to do so with it (running on my somewhat old laptop). Those seconds add up, especially when you remember that after a few seconds you're likely to get distracted and go look at your phone or open a browser and start checking email or twitter or something. Not using the debugger helps keep you in the zone and productive.</p>
<p>So why not use the debugger to, like, actually debug problems? I do sometimes. But more often I'll write tests. If it's my own application, I probably already have a bunch of tests. If there's some weird behavior going on and no existing test is catching it, I'll try to write a new one that fails because of the bug I'm looking for. Going through this exercise forces me to analyze what the program is doing, what classes are collaborating and how, and in general to have a better understanding of what's going on.</p>
<p>If I can't easily write a test to isolate the issue I'm having, then I'll use the debugger. I might even debug from a test, since that's often an easy way to jump right to a particular place in my code that I know is being called with known inputs. From there I'll look at the values of all the relevant variables and arguments and usually that will identify where something isn't set the way I'd thought or assumed it was.</p>
<p>Another approach I take is to use some kind of diagnostic tool within the app framework I'm using to provide me with as much data as possible about how the system is working. That might be using a tool like ELMAH for older ASP.NET apps, or an MVC route debugger middleware that shows me every route and how it's configured. I have some middleware for ASP.NET Core on GitHub that will format and render all of the services the application has registered. Things like this can often help provide additional context and information that can eventually help find the source of a problem.</p>
<p>Tests aren't the only thing that helps avoid the need for a debugger. Using <a href="/007">custom exceptions like I described in episode 7</a> helps make it obvious what went wrong so you don't need to debug in order to figure out that <code>NullReferenceException</code>. Writing short, simple methods with low complexity, perhaps with the help of <a href="/004">Guard Clauses that I described in episode 4</a> is helpful, too. I actually revisited both of these topics in <a href="/036">the previous episode</a>, too. When your code is kept simple and small, problems are generally easily detected. If you're writing 1000 line long methods that require multiple levels of nested regions in them to be comprehensible, I can see how you might need the debugger to sort out what the heck is going on when something doesn't work.</p>
<p>What are some other things I'm doing while troubleshooting? I'm not wasting hours focused on finding the problem mano a mano. I'm harnessing the power of a billion people on the Internet to help me. I can record another entire episode just on how to minimize how much time you waste blocked by some problem, and I've written an article on my ardalis.com site called <a href="https://ardalis.com/working-through-roadblocks-a-guide-for-new-programmers">Working Through Roadblocks - A Guide for New Programmers</a> that goes into this as well.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://elmah.github.io/">ELMAH</a></li>
<li><a href="https://ardalis.com/debugging-aspnet-core-routes">ASP.NET MVC Route Debugger</a></li>
<li><a href="https://ardalis.com/how-to-list-all-services-available-to-an-asp-net-core-app">List all ASP.NET Core Services</a></li>
<li><a href="https://ardalis.com/working-through-roadblocks-a-guide-for-new-programmers">Working Through Roadblocks - A Guide for New Programmers</a></li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> now. Thank you for subscribing to Weekly Dev Tips, and we’ll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 28 Jan 2019 07:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 37, in which I'll talk a bit about how I debug problems I find in my code.</p>
<p>If you’re enjoying these tips, please leave a comment or rating in your podcast app, tell a friend about the podcast, or follow us on twitter and retweet our episode announcements. All these things help increase the reach of this podcast, so more people can benefit from these tips.</p>
<h1>Debugging Tip</h1>
<p>This week's tip is by request via twitter from Bernard FitzGerald (@bernimfitz) who wrote &quot;How about an episode devoted to effective debugging? I think that would be interesting to hear your methodology of tracking down a bug.&quot; Well, Bernard, this bug's for you. Sorry, lame beer commercial joke. On that note, here's a commercial...</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>If you're not advancing as quickly in your career as you'd like, you may find value in joining a semi-formal career and technical coaching program like devBetter.com. I launched devBetter a few months ago and so far we have a small group of motivated developers meeting every week or two. I answer questions, review code, suggest areas in which to improve, and occasionally assign homework. Interested? Learn more at devBetter.com.</p>
<h2>Show Notes / Transcript</h2>
<p>Let's talk a bit about debugging. Let me start off with a couple of personal observations. First, I think debuggers are amazing. Having the ability to magically stop time in the middle of your application anywhere you want and see exactly what the state of everything is there is like a super power. It far outstrips using console output and checking a log file or terminal window for logged output like &quot;got here&quot; and &quot;got here 2&quot;. Those were dark days.</p>
<p>And second, despite how amazing they are, I almost never use the debugger. One tip I give all the time to students in my workshops is that they learn to use ctrl-F5 instead of F5 to launch their applications because it's so much faster. In my experience, 90% or more of the time you're not actually debugging when you launch your application, and in a recent experiment I ran it took about a second to launch an ASP.NET Core app without the debugger and about 10 seconds to do so with it (running on my somewhat old laptop). Those seconds add up, especially when you remember that after a few seconds you're likely to get distracted and go look at your phone or open a browser and start checking email or twitter or something. Not using the debugger helps keep you in the zone and productive.</p>
<p>So why not use the debugger to, like, actually debug problems? I do sometimes. But more often I'll write tests. If it's my own application, I probably already have a bunch of tests. If there's some weird behavior going on and no existing test is catching it, I'll try to write a new one that fails because of the bug I'm looking for. Going through this exercise forces me to analyze what the program is doing, what classes are collaborating and how, and in general to have a better understanding of what's going on.</p>
<p>If I can't easily write a test to isolate the issue I'm having, then I'll use the debugger. I might even debug from a test, since that's often an easy way to jump right to a particular place in my code that I know is being called with known inputs. From there I'll look at the values of all the relevant variables and arguments and usually that will identify where something isn't set the way I'd thought or assumed it was.</p>
<p>Another approach I take is to use some kind of diagnostic tool within the app framework I'm using to provide me with as much data as possible about how the system is working. That might be using a tool like ELMAH for older ASP.NET apps, or an MVC route debugger middleware that shows me every route and how it's configured. I have some middleware for ASP.NET Core on GitHub that will format and render all of the services the application has registered. Things like this can often help provide additional context and information that can eventually help find the source of a problem.</p>
<p>Tests aren't the only thing that helps avoid the need for a debugger. Using <a href="/007">custom exceptions like I described in episode 7</a> helps make it obvious what went wrong so you don't need to debug in order to figure out that <code>NullReferenceException</code>. Writing short, simple methods with low complexity, perhaps with the help of <a href="/004">Guard Clauses that I described in episode 4</a> is helpful, too. I actually revisited both of these topics in <a href="/036">the previous episode</a>, too. When your code is kept simple and small, problems are generally easily detected. If you're writing 1000 line long methods that require multiple levels of nested regions in them to be comprehensible, I can see how you might need the debugger to sort out what the heck is going on when something doesn't work.</p>
<p>What are some other things I'm doing while troubleshooting? I'm not wasting hours focused on finding the problem mano a mano. I'm harnessing the power of a billion people on the Internet to help me. I can record another entire episode just on how to minimize how much time you waste blocked by some problem, and I've written an article on my ardalis.com site called <a href="https://ardalis.com/working-through-roadblocks-a-guide-for-new-programmers">Working Through Roadblocks - A Guide for New Programmers</a> that goes into this as well.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://elmah.github.io/">ELMAH</a></li>
<li><a href="https://ardalis.com/debugging-aspnet-core-routes">ASP.NET MVC Route Debugger</a></li>
<li><a href="https://ardalis.com/how-to-list-all-services-available-to-an-asp-net-core-app">List all ASP.NET Core Services</a></li>
<li><a href="https://ardalis.com/working-through-roadblocks-a-guide-for-new-programmers">Working Through Roadblocks - A Guide for New Programmers</a></li>
</ul>
<p>That’s it for this week. If you want to hear more from me, go to <a href="https://ardalis.com/tips">ardalis.com/tips</a> to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on <a href="https://twitch.tv/ardalis">twitch.tv/ardalis</a> now. Thank you for subscribing to Weekly Dev Tips, and we’ll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="3655435" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/8367b183-b182-429f-81f0-c5a4127aede5/d7f97b48_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Debugging Tips</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/8367b183-b182-429f-81f0-c5a4127aede5/3000x3000/1548424107artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:05:54</itunes:duration>
      <itunes:summary>This week&apos;s tip is by request via twitter from Bernard FitzGerald (@bernimfitz) who wrote &quot;How about an episode devoted to effective debugging? I think that would be interesting to hear your methodology of tracking down a bug.&quot; Well, Bernard, this bug&apos;s for you. Sorry, lame beer commercial joke. </itunes:summary>
      <itunes:subtitle>This week&apos;s tip is by request via twitter from Bernard FitzGerald (@bernimfitz) who wrote &quot;How about an episode devoted to effective debugging? I think that would be interesting to hear your methodology of tracking down a bug.&quot; Well, Bernard, this bug&apos;s for you. Sorry, lame beer commercial joke. </itunes:subtitle>
      <itunes:keywords>software development, coding, clean code, programming, testing, debugging</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>37</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">87823d21-4b35-400f-bc7b-918f071f6d00</guid>
      <title>Exceptions and Guard Clauses</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 36, in which we'll discuss a question I recently received about guard clauses and exceptions.</p>
<p>If you’re enjoying these tips, please leave a comment or rating in your podcast app, tell a friend about the podcast, or follow us on twitter and retweet our episode announcements so we can increase our audience. I really appreciate it.</p>
<h1>Exceptions and Guard Clauses</h1>
<p>This week's tip is on the topic guard clauses and exceptions. Specifically, whether and when it's appropriate to throw an exception in response to certain kinds of inputs.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>If you're not advancing as quickly in your career as you'd like, you may find value in joining a semi-formal career and technical coaching program like devBetter.com. I launched devBetter a few months ago and so far we have a small group of motivated developers meeting every week or two. I answer questions, review code, suggest areas in which to improve, and occasionally assign homework. Interested? Learn more at devBetter.com.</p>
<h2>Show Notes / Transcript</h2>
<p>As a bit of background, I described <a href="/04">Guard Clauses in Episode 4</a>. If you're listening to these shows in most-recent-first order, I suggest you configure your podcast app to let you listen in order and then start back with episode 1. You'll thank me later. In any case, a guard clause is a check you make at the start of a function or method that throws an exception if some input is not valid. For instance, you could have a function that is supposed to send an email to an email address that's provided as a string argument. If the string is null, it might throw an ArgumentNullException or something similar before attempting to create and send the email. If you like the guard clause pattern, I have a nuget package you can use to easily add and extend them in a consistent fashion in your applications - look for the link in the show notes.</p>
<p>Listener Jeremy C. writes:</p>
<p><em>i discovered your podcast recently, and am going through it. I love the Guard class shortcut for happy path.</em></p>
<p><em>What i noticed, is that this behavior relies exclusively on throwing exceptions rather than what I learned (20 years ago) in school that exceptions are for the unexpected, and if you can reliably prevent throwing an exception, like checking for a null and handling it, you should to avoid the execution cost of exception handling.</em></p>
<p><em>Is my information just out-dated? :) Perhaps I'm too old of a coder and too many old habits are stuck.</em></p>
<p>It's true that exceptions should not be used for control flow in your applications. That means if it's a normal condition for a function to get a null as an argument, perhaps because that situation means &quot;create a new thing&quot; instead of &quot;do something with this thing&quot;, then you wouldn't want to write code that depended on an exception being thrown for its behavior. For example, you wouldn't want to have a try block that tried to work with the object, and then a catch block that caught the NullReferenceException when it was null and created a new instance there.</p>
<p>There's plenty of reference material you can find about why this is considered a bad practice. In my opinion there are two main reasons. One is performance - exceptions are far more expensive than if statements so you shouldn't use them where an if statement is more appopriate. This is the main one, and because of it, writing code that leverages try-catch statements for something more than error handling is unexpected. Developers will be surprised to see this approach, which violates the <a href="https://en.wikipedia.org/wiki/Principle_of_least_astonishment">Principle of Least Astonishment</a>. You want readers of your code to be able to immediately understand what it's doing, and surprising them by doing things in odd ways is contrary to that goal.</p>
<p>Coming back to guard clauses, the idea is that you're setting up an expectation that under all normal conditions in your application you expect that these arguments will follow certain constraints. If they don't, the program's simply not going to work the way it should. In this case, an exception is the appropriate response and is more elegant than any other solution like returning a boolean value or magic number or null and the caller having to know to check for that result.</p>
<p>Thanks Jeremy for the great question! After I answered, he summed it up like this:</p>
<p><em>So the Guard Clause is for the situation of, &quot;I told you the expected inputs, and while I'll protect myself from bad data, I'm not going to make a huge mess of if statements to protect myself, I'll pass the mess back to the code giving me crap.&quot;</em></p>
<p>Pretty much.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://github.com/ardalis/GuardClauses">Guard Clauses</a></li>
<li><a href="https://en.wikipedia.org/wiki/Principle_of_least_astonishment">Principle of Least Astonishment</a></li>
</ul>
]]></description>
      <pubDate>Mon, 31 Dec 2018 07:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 36, in which we'll discuss a question I recently received about guard clauses and exceptions.</p>
<p>If you’re enjoying these tips, please leave a comment or rating in your podcast app, tell a friend about the podcast, or follow us on twitter and retweet our episode announcements so we can increase our audience. I really appreciate it.</p>
<h1>Exceptions and Guard Clauses</h1>
<p>This week's tip is on the topic guard clauses and exceptions. Specifically, whether and when it's appropriate to throw an exception in response to certain kinds of inputs.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>If you're not advancing as quickly in your career as you'd like, you may find value in joining a semi-formal career and technical coaching program like devBetter.com. I launched devBetter a few months ago and so far we have a small group of motivated developers meeting every week or two. I answer questions, review code, suggest areas in which to improve, and occasionally assign homework. Interested? Learn more at devBetter.com.</p>
<h2>Show Notes / Transcript</h2>
<p>As a bit of background, I described <a href="/04">Guard Clauses in Episode 4</a>. If you're listening to these shows in most-recent-first order, I suggest you configure your podcast app to let you listen in order and then start back with episode 1. You'll thank me later. In any case, a guard clause is a check you make at the start of a function or method that throws an exception if some input is not valid. For instance, you could have a function that is supposed to send an email to an email address that's provided as a string argument. If the string is null, it might throw an ArgumentNullException or something similar before attempting to create and send the email. If you like the guard clause pattern, I have a nuget package you can use to easily add and extend them in a consistent fashion in your applications - look for the link in the show notes.</p>
<p>Listener Jeremy C. writes:</p>
<p><em>i discovered your podcast recently, and am going through it. I love the Guard class shortcut for happy path.</em></p>
<p><em>What i noticed, is that this behavior relies exclusively on throwing exceptions rather than what I learned (20 years ago) in school that exceptions are for the unexpected, and if you can reliably prevent throwing an exception, like checking for a null and handling it, you should to avoid the execution cost of exception handling.</em></p>
<p><em>Is my information just out-dated? :) Perhaps I'm too old of a coder and too many old habits are stuck.</em></p>
<p>It's true that exceptions should not be used for control flow in your applications. That means if it's a normal condition for a function to get a null as an argument, perhaps because that situation means &quot;create a new thing&quot; instead of &quot;do something with this thing&quot;, then you wouldn't want to write code that depended on an exception being thrown for its behavior. For example, you wouldn't want to have a try block that tried to work with the object, and then a catch block that caught the NullReferenceException when it was null and created a new instance there.</p>
<p>There's plenty of reference material you can find about why this is considered a bad practice. In my opinion there are two main reasons. One is performance - exceptions are far more expensive than if statements so you shouldn't use them where an if statement is more appopriate. This is the main one, and because of it, writing code that leverages try-catch statements for something more than error handling is unexpected. Developers will be surprised to see this approach, which violates the <a href="https://en.wikipedia.org/wiki/Principle_of_least_astonishment">Principle of Least Astonishment</a>. You want readers of your code to be able to immediately understand what it's doing, and surprising them by doing things in odd ways is contrary to that goal.</p>
<p>Coming back to guard clauses, the idea is that you're setting up an expectation that under all normal conditions in your application you expect that these arguments will follow certain constraints. If they don't, the program's simply not going to work the way it should. In this case, an exception is the appropriate response and is more elegant than any other solution like returning a boolean value or magic number or null and the caller having to know to check for that result.</p>
<p>Thanks Jeremy for the great question! After I answered, he summed it up like this:</p>
<p><em>So the Guard Clause is for the situation of, &quot;I told you the expected inputs, and while I'll protect myself from bad data, I'm not going to make a huge mess of if statements to protect myself, I'll pass the mess back to the code giving me crap.&quot;</em></p>
<p>Pretty much.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://github.com/ardalis/GuardClauses">Guard Clauses</a></li>
<li><a href="https://en.wikipedia.org/wiki/Principle_of_least_astonishment">Principle of Least Astonishment</a></li>
</ul>
]]></content:encoded>
      <enclosure length="2933582" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/72009915-4b01-4997-9787-3b26d1ac42d8/822566b0_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Exceptions and Guard Clauses</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/72009915-4b01-4997-9787-3b26d1ac42d8/3000x3000/1546031405artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:04:51</itunes:duration>
      <itunes:summary>This week&apos;s tip is on the topic guard clauses and exceptions. Specifically, whether and when it&apos;s appropriate to throw an exception in response to certain kinds of inputs.</itunes:summary>
      <itunes:subtitle>This week&apos;s tip is on the topic guard clauses and exceptions. Specifically, whether and when it&apos;s appropriate to throw an exception in response to certain kinds of inputs.</itunes:subtitle>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>36</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">3c0365bf-4ff3-474c-ab08-1d445f9c9590</guid>
      <title>Why is Immutability Desirable?</title>
      <description><![CDATA[<h1>Why Immutability is Desirable</h1>
<p>This week's tip is on the topic of <em>immutability</em>, and why it's often considered a good thing for your data structures. I'll share my thoughts on the topic in a moment, but first a quick note from this week's sponsor.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>If you're not advancing as quickly in your career as you'd like, you may find value in joining a semi-formal career and technical coaching program like devBetter.com. I launched devBetter a few months ago and so far we have a small group of motivated developers meeting every week or two. I answer questions, review code, suggest areas in which to improve, and occasionally assign homework. Interested? Learn more at devBetter.com.</p>
<h2>Show Notes / Transcript</h2>
<p>Let's talk about immutability. This topic is on my mind because I just wrote an article about getting language support for immutability and, more broadly, DDD value objects, in C#. Value objects area DDD pattern, and one of their defining characteristics is that they're immutable. I keep using that word, so I should probably define it.</p>
<p>An immutable data structure (an object in C#) is one that, once created, cannot have its state modified. I mention wanting language support for this feature in C# - that's not to imply that you can't create immutable objects today. It's just a lot of manual work, and easy to get wrong or screw up in the future because nothing enforces immutability at the class level. Typically in C# to create an immutable object you create a class with properties that lack setters, and then you assign values to these properties in the class constructor. Short of some reflection trickery, instances of this type cannot have their properties modified once they've been instantiated. Why might we want this?</p>
<p>The biggest advantage I get from immutability in objects is knowledge that instances of these types are always in a valid state. That means any method using such types doesn't have to waste effort trying to verify they're in a valid state. Here's a common example. Imagine your system needs to work with date ranges that include a start and end date. You might have many methods that take in two DateTime types, and in these methods you always expect the end date to be later than the start date. So, being a good programmer, you write a <a href="https://github.com/ardalis/GuardClauses">guard clause</a> to ensure start date precedes end date. This logic ends up scattered all over the place, and maybe sometimes you forget or don't bother with it, so not it's not even enforced consistently, allowing bugs to creep in. What if instead you created an immutable DateRange class, passed the start and end dates into its constructor, and ensured they were valid there? If not, you'd throw an appropriate exception. Now, any method that was accepting a start and end date can just take in a DateRange instead, shortening these methods' parameter lists. And they can remove all of their validation on start date and end date because that's now done in the DateRange class. Why can you trust that it was done? Because of immutability. If it was valid when it was created, it must still be valid now since it couldn't be changed in the meantime. Your validation logic only has to be performed in one place, and immutability gives you guarantees that it will be applied so you don't have to defensively code for it everywhere.</p>
<p>Another advantage immutability offers is thread safety. You don't have to worry about race conditions or synchronization issues between different threads when they work with immutable objects. Why not? Simply because the objects can't change. Operating on immutable objects may produce new instances of objects, but this typically doesn't pose an issue for multi-threaded applications. The issue is more commonly something like an instance that two threads are referencing, and each thread tells the instance to increment a counter at the same time. The end result may be unexpected due to how the calculation may be completed. This is typically overcome through the use of locks, but you can pass around immutable objects between threads all you want and never have to worry about this issue.</p>
<p>Have you ever passed an object to a method, and then found yourself surprised when the method modified the object? I generally dislike this kind of thing, and C# even has a <a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/in-parameter-modifier">new keyword <code>in</code></a> that will ensure this doesn't happen. I'll link to more on the <code>in</code> keyword in the show notes, but it has some restrictions and hasn't seen widespread adoption, yet. Another way to ensure that the state of an instance you pass to a method isn't modified within that method is to use an immutable object. This makes it much easier to reason about and debug your code, and can have performance benefits since objects that won't be modified can always be passed by reference, without copying them to the stack.</p>
<p>Immutable types are much easier to test than other types, and for this as well as the above reasons using them appropriately can lead to better, more maintainable code. Eliminate the <a href="https://www.pluralsight.com/courses/refactoring-fundamentals">primitive obsession code smell</a>, better encapsulate concepts that tie together several values, and force validation (and other business rules) to live with these values instead of in the types that use them. You should find over time that your domain model becomes much cleaner as a result.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://hackernoon.com/5-benefits-of-immutable-objects-worth-considering-for-your-next-project-f98e7e85b6ac">5 Benefits of Immutable Objects</a></li>
<li><a href="https://github.com/ardalis/GuardClauses">Guard Clauses</a></li>
<li><a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/in-parameter-modifier">The C# <code>in</code> parameter modifier</a></li>
<li><a href="https://www.pluralsight.com/courses/refactoring-fundamentals">Refactoring and Code Smells</a></li>
</ul>
]]></description>
      <pubDate>Mon, 24 Dec 2018 07:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h1>Why Immutability is Desirable</h1>
<p>This week's tip is on the topic of <em>immutability</em>, and why it's often considered a good thing for your data structures. I'll share my thoughts on the topic in a moment, but first a quick note from this week's sponsor.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>If you're not advancing as quickly in your career as you'd like, you may find value in joining a semi-formal career and technical coaching program like devBetter.com. I launched devBetter a few months ago and so far we have a small group of motivated developers meeting every week or two. I answer questions, review code, suggest areas in which to improve, and occasionally assign homework. Interested? Learn more at devBetter.com.</p>
<h2>Show Notes / Transcript</h2>
<p>Let's talk about immutability. This topic is on my mind because I just wrote an article about getting language support for immutability and, more broadly, DDD value objects, in C#. Value objects area DDD pattern, and one of their defining characteristics is that they're immutable. I keep using that word, so I should probably define it.</p>
<p>An immutable data structure (an object in C#) is one that, once created, cannot have its state modified. I mention wanting language support for this feature in C# - that's not to imply that you can't create immutable objects today. It's just a lot of manual work, and easy to get wrong or screw up in the future because nothing enforces immutability at the class level. Typically in C# to create an immutable object you create a class with properties that lack setters, and then you assign values to these properties in the class constructor. Short of some reflection trickery, instances of this type cannot have their properties modified once they've been instantiated. Why might we want this?</p>
<p>The biggest advantage I get from immutability in objects is knowledge that instances of these types are always in a valid state. That means any method using such types doesn't have to waste effort trying to verify they're in a valid state. Here's a common example. Imagine your system needs to work with date ranges that include a start and end date. You might have many methods that take in two DateTime types, and in these methods you always expect the end date to be later than the start date. So, being a good programmer, you write a <a href="https://github.com/ardalis/GuardClauses">guard clause</a> to ensure start date precedes end date. This logic ends up scattered all over the place, and maybe sometimes you forget or don't bother with it, so not it's not even enforced consistently, allowing bugs to creep in. What if instead you created an immutable DateRange class, passed the start and end dates into its constructor, and ensured they were valid there? If not, you'd throw an appropriate exception. Now, any method that was accepting a start and end date can just take in a DateRange instead, shortening these methods' parameter lists. And they can remove all of their validation on start date and end date because that's now done in the DateRange class. Why can you trust that it was done? Because of immutability. If it was valid when it was created, it must still be valid now since it couldn't be changed in the meantime. Your validation logic only has to be performed in one place, and immutability gives you guarantees that it will be applied so you don't have to defensively code for it everywhere.</p>
<p>Another advantage immutability offers is thread safety. You don't have to worry about race conditions or synchronization issues between different threads when they work with immutable objects. Why not? Simply because the objects can't change. Operating on immutable objects may produce new instances of objects, but this typically doesn't pose an issue for multi-threaded applications. The issue is more commonly something like an instance that two threads are referencing, and each thread tells the instance to increment a counter at the same time. The end result may be unexpected due to how the calculation may be completed. This is typically overcome through the use of locks, but you can pass around immutable objects between threads all you want and never have to worry about this issue.</p>
<p>Have you ever passed an object to a method, and then found yourself surprised when the method modified the object? I generally dislike this kind of thing, and C# even has a <a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/in-parameter-modifier">new keyword <code>in</code></a> that will ensure this doesn't happen. I'll link to more on the <code>in</code> keyword in the show notes, but it has some restrictions and hasn't seen widespread adoption, yet. Another way to ensure that the state of an instance you pass to a method isn't modified within that method is to use an immutable object. This makes it much easier to reason about and debug your code, and can have performance benefits since objects that won't be modified can always be passed by reference, without copying them to the stack.</p>
<p>Immutable types are much easier to test than other types, and for this as well as the above reasons using them appropriately can lead to better, more maintainable code. Eliminate the <a href="https://www.pluralsight.com/courses/refactoring-fundamentals">primitive obsession code smell</a>, better encapsulate concepts that tie together several values, and force validation (and other business rules) to live with these values instead of in the types that use them. You should find over time that your domain model becomes much cleaner as a result.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://hackernoon.com/5-benefits-of-immutable-objects-worth-considering-for-your-next-project-f98e7e85b6ac">5 Benefits of Immutable Objects</a></li>
<li><a href="https://github.com/ardalis/GuardClauses">Guard Clauses</a></li>
<li><a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/in-parameter-modifier">The C# <code>in</code> parameter modifier</a></li>
<li><a href="https://www.pluralsight.com/courses/refactoring-fundamentals">Refactoring and Code Smells</a></li>
</ul>
]]></content:encoded>
      <enclosure length="3961824" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/21c70b9f-e434-42d7-aa08-75da929ae2a9/57b5253d_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Why is Immutability Desirable?</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/21c70b9f-e434-42d7-aa08-75da929ae2a9/3000x3000/1545421952artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:06:00</itunes:duration>
      <itunes:summary>This week&apos;s tip is on the topic of _immutability_, and why it&apos;s often considered a good thing for your data structures.</itunes:summary>
      <itunes:subtitle>This week&apos;s tip is on the topic of _immutability_, and why it&apos;s often considered a good thing for your data structures.</itunes:subtitle>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>35</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">b7b407a7-4890-45a8-83d5-c5d68bfcd930</guid>
      <title>Avoid Lazy Loading in ASP.NET Apps</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 34, in which we'll talk about lazy loading in ASP.NET and ASP.NET Core apps, and why it's evil.</p>
<p>If you’re enjoying these tips, please leave a comment or rating in your podcast app, tell a friend about the podcast, or follow us on twitter and retweet our episode announcements so we can increase our audience. I really appreciate it.</p>
<h1>Avoid Lazy Loading in ASP.NET (Core) Apps</h1>
<p>This week's tip is on the topic of lazy loading using Entity Framework or EF Core in ASP.NET and ASP.NET Core apps. Spoiler alert: don't do it. Keep listening to hear why.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>Last week I announced my new developer career coaching program, <a href="https://devbetter.com">devBetter</a>. If you're not advancing as quickly in your career as you'd like, and you could use someone in your corner pushing you to succeed and opening up doors to new opportunities, consider joining a handful of like-minded developers at devbetter.com.</p>
<h2>Show Notes / Transcript</h2>
<p>Lazy loading is a feature that EF6 has had for a long time and EF Core only recently added with version 2.1. The way it works is, entities are fetched without their related entities, and these related entities are loaded &quot;just in time&quot; as code references them. This seems to follow the best practice of deferred execution, but unfortunately the downsides far outweigh the benefits the vast majority of the time in this case. I recommend disabling lazy loading in all ASP.NET and ASP.NET Core apps. Let's look at why.</p>
<p>On any given web request, the goal should be to return a response to the client as quickly as possible. The fewer out-of-process calls the request needs to make before it can return a response, the faster it will be, all things being equal. If a round-trip to the database takes 20ms and processing the request requires 10 database calls, then assuming they can't be made in parallel the minimum time for this is 200ms. If the same data could be fetched in a single round-trip to the database, it would cut page load time by 180ms, not counting the time to execute the queries themselves which might also be faster if done in one batch.</p>
<p>When you use lazy loading, your code will make more calls to the database than if you had used eager loading. It's also deceptively easy to write code that will result in lazy loading being done within some kind of loop, resulting in dozens or hundreds of database calls. This can be difficult to detect in development and even in testing, but in production where usually there are more users and larger sets of data in use, the problem can have huge performance implications.</p>
<p>I have a GitHub repo that demonstrates lazy loading using ASP.NET MVC 5 and EF 6 and also ASP.NET Core with EF Core. I encourage you to download it and run it yourself. It demonstrates the problem using a conference web site as its sample data. There are conference sessions. Each session has one or more speakers presenting it. Each session can have one or more tags. For sample data I have 2 sessions with 2 speakers and 3 tags total. Displaying the page shows each session and its speakers, tags, and description, all done with some simple razor code in the view. The initial query just pulls in the sessions - the speakers and tags are lazy loaded. How many queries do you think this page makes to the database?</p>
<p>Let's think about how many it <em>should</em> make. Assuming the site's just loaded and has no cache in place, it should be able to load the data for this page using a single query. At worst a couple of queries. This kind of data is also highly cacheable, so after the first load the page should render with 0 queries. For this reason I like to say &quot;caching hides many sins&quot; because even if you do use lazy loading and have way too many queries, if you add caching it'll be the rare user who has to suffer for it.</p>
<p>Coming back to the sample, with 2 sessions, 2 speakers, and 3 tags, the page makes 22 database queries to render the page using lazy loading. It should be clear that this number is going to grow rapidly as the number of sessions, speakers, and tags increases. Most conferences have more than 2 sessions, after all, but during development maybe only a couple are used and only one user is hitting the page, so the performance impact might not be felt until the worst possible time: the day of the conference. At which point it may be too late to fix and redeploy the code.</p>
<p>Lazy loading is a tool that makes sense in certain situations. It's especially effective when the application and the database are colocated and there's just one user. If you're writing bookkeeping software that runs locally and communicates with a local database, it might make sense to use lazy loading as the user navigates around the system rather than trying to eager load all of the data. But in the context of processing a single web request, when every extra trip to the database slows the page down further, and where it can be easy to inadvertently add dozens or more requests, you should avoid it.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://ardalis.com/avoid-lazy-loading-entities-in-asp-net-applications">Avoid Lazy Loading Entities in ASP.NET Apps</a></li>
<li><a href="https://github.com/ardalis/lazyloading">Lazy Loading GitHub Sample</a></li>
<li><a href="https://ardalis.com/working-with-lazy-loading-in-entity-framework-code-first">How to Disable Lazy Loading in EF</a></li>
</ul>
<p>That’s it for this week. Thank you for subscribing to Weekly Dev Tips, and we’ll see you next week with another great developer tip.</p>
]]></description>
      <pubDate>Mon, 17 Dec 2018 07:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 34, in which we'll talk about lazy loading in ASP.NET and ASP.NET Core apps, and why it's evil.</p>
<p>If you’re enjoying these tips, please leave a comment or rating in your podcast app, tell a friend about the podcast, or follow us on twitter and retweet our episode announcements so we can increase our audience. I really appreciate it.</p>
<h1>Avoid Lazy Loading in ASP.NET (Core) Apps</h1>
<p>This week's tip is on the topic of lazy loading using Entity Framework or EF Core in ASP.NET and ASP.NET Core apps. Spoiler alert: don't do it. Keep listening to hear why.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>Last week I announced my new developer career coaching program, <a href="https://devbetter.com">devBetter</a>. If you're not advancing as quickly in your career as you'd like, and you could use someone in your corner pushing you to succeed and opening up doors to new opportunities, consider joining a handful of like-minded developers at devbetter.com.</p>
<h2>Show Notes / Transcript</h2>
<p>Lazy loading is a feature that EF6 has had for a long time and EF Core only recently added with version 2.1. The way it works is, entities are fetched without their related entities, and these related entities are loaded &quot;just in time&quot; as code references them. This seems to follow the best practice of deferred execution, but unfortunately the downsides far outweigh the benefits the vast majority of the time in this case. I recommend disabling lazy loading in all ASP.NET and ASP.NET Core apps. Let's look at why.</p>
<p>On any given web request, the goal should be to return a response to the client as quickly as possible. The fewer out-of-process calls the request needs to make before it can return a response, the faster it will be, all things being equal. If a round-trip to the database takes 20ms and processing the request requires 10 database calls, then assuming they can't be made in parallel the minimum time for this is 200ms. If the same data could be fetched in a single round-trip to the database, it would cut page load time by 180ms, not counting the time to execute the queries themselves which might also be faster if done in one batch.</p>
<p>When you use lazy loading, your code will make more calls to the database than if you had used eager loading. It's also deceptively easy to write code that will result in lazy loading being done within some kind of loop, resulting in dozens or hundreds of database calls. This can be difficult to detect in development and even in testing, but in production where usually there are more users and larger sets of data in use, the problem can have huge performance implications.</p>
<p>I have a GitHub repo that demonstrates lazy loading using ASP.NET MVC 5 and EF 6 and also ASP.NET Core with EF Core. I encourage you to download it and run it yourself. It demonstrates the problem using a conference web site as its sample data. There are conference sessions. Each session has one or more speakers presenting it. Each session can have one or more tags. For sample data I have 2 sessions with 2 speakers and 3 tags total. Displaying the page shows each session and its speakers, tags, and description, all done with some simple razor code in the view. The initial query just pulls in the sessions - the speakers and tags are lazy loaded. How many queries do you think this page makes to the database?</p>
<p>Let's think about how many it <em>should</em> make. Assuming the site's just loaded and has no cache in place, it should be able to load the data for this page using a single query. At worst a couple of queries. This kind of data is also highly cacheable, so after the first load the page should render with 0 queries. For this reason I like to say &quot;caching hides many sins&quot; because even if you do use lazy loading and have way too many queries, if you add caching it'll be the rare user who has to suffer for it.</p>
<p>Coming back to the sample, with 2 sessions, 2 speakers, and 3 tags, the page makes 22 database queries to render the page using lazy loading. It should be clear that this number is going to grow rapidly as the number of sessions, speakers, and tags increases. Most conferences have more than 2 sessions, after all, but during development maybe only a couple are used and only one user is hitting the page, so the performance impact might not be felt until the worst possible time: the day of the conference. At which point it may be too late to fix and redeploy the code.</p>
<p>Lazy loading is a tool that makes sense in certain situations. It's especially effective when the application and the database are colocated and there's just one user. If you're writing bookkeeping software that runs locally and communicates with a local database, it might make sense to use lazy loading as the user navigates around the system rather than trying to eager load all of the data. But in the context of processing a single web request, when every extra trip to the database slows the page down further, and where it can be easy to inadvertently add dozens or more requests, you should avoid it.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://ardalis.com/avoid-lazy-loading-entities-in-asp-net-applications">Avoid Lazy Loading Entities in ASP.NET Apps</a></li>
<li><a href="https://github.com/ardalis/lazyloading">Lazy Loading GitHub Sample</a></li>
<li><a href="https://ardalis.com/working-with-lazy-loading-in-entity-framework-code-first">How to Disable Lazy Loading in EF</a></li>
</ul>
<p>That’s it for this week. Thank you for subscribing to Weekly Dev Tips, and we’ll see you next week with another great developer tip.</p>
]]></content:encoded>
      <enclosure length="3846187" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/78dac42b-5349-4ce0-86b3-ee93b82d24c9/0704b8eb_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Avoid Lazy Loading in ASP.NET Apps</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/78dac42b-5349-4ce0-86b3-ee93b82d24c9/3000x3000/1544802532artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:05:52</itunes:duration>
      <itunes:summary>This week&apos;s tip is on the topic of lazy loading using Entity Framework or EF Core in ASP.NET and ASP.NET Core apps. Spoiler alert: don&apos;t do it. Keep listening to hear why.</itunes:summary>
      <itunes:subtitle>This week&apos;s tip is on the topic of lazy loading using Entity Framework or EF Core in ASP.NET and ASP.NET Core apps. Spoiler alert: don&apos;t do it. Keep listening to hear why.</itunes:subtitle>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>34</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">d6e6e02d-2a4a-470b-8ca5-76e1181c8087</guid>
      <title>Use the Right Object Lifetime</title>
      <description><![CDATA[<h1>Use the right object lifetime</h1>
<p>This week we talk about object lifetimes, why they matter, and how to choose the right one. We'll focus a little bit on Entity Framework since it's very popular and also very frequently misconfigured.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>This week I'm announcing my new developer career coaching program, <a href="https://devbetter.com">devBetter</a>. If you're not advancing as quickly in your career as you'd like, and you could use someone in your corner pushing you to succeed and opening up doors to new opportunities, check it out at devbetter.com.</p>
<h2>Show Notes / Transcript</h2>
<p>If you're not using <a href="https://deviq.com/dependency-injection/">dependency injection</a> or following the <a href="https://deviq.com/dependency-inversion-principle/">dependency inversion principle</a> in your code, you probably don't care much about object lifetimes. You can probably just instantiate new instances anywhere you need them and then let them be destroyed when they go out of scope. In this case, you probably have no use for an IoC or DI container. However, your code is probably also very tightly coupled, making it more difficult to test and reconfigure in the future. If it's working for you, keep at it, but if you're feeling pain from the coupling, I encourage you to check out my <a href="https://www.pluralsight.com/courses/principles-oo-design">SOLID principles</a> and <a href="https://www.pluralsight.com/courses/refactoring-fundamentals">Refactoring</a> courses on Pluralsight to learn a different way to compose things.</p>
<p>If you are using DI and containers, like most developers using ASP.NET Core where it's built-in, or even ASP.NET MVC, you've probably encountered the concept of object lifetimes before. There's some variety in the nomenclature for some of the options, but using the terminology of ASP.NET Core's container, there are three main kinds of object lifetimes: transient, scoped, and singleton. Let me cover these briefly and apologies if you're already well-versed in this topic.</p>
<p>Transient scope refers to objects that are created any time they're requested. If you request an instance of a type from the container, and that type's scope is transient, you're getting a brand new instance. If you ask for a type and that type has a constructor parameter that's configured to be transient, that constructor parameter is going to be a brand new instance, every time.</p>
<p>Scoped lifetime refers to objects that, once created, live on for the duration of a given HTTP request. If you ask the container for an instance multiple times within an HTTP request, you'll get the same instance every time. Regardless of where the request to the DI container comes from within the web request, the same object instance is returned from the DI container. The first call to get an instance of the type will get a new instance; every subsequent request for that type will get this same instance.</p>
<p>Singleton scope is simple - there's only one instance. The first time an instance is requested, it's created, or you can create it during startup and add it to the container then. After that, the same instance is used everywhere.</p>
<p>So, which one should you use? Well, naturally, it depends. Since we don't have a lot of time, let's just look at a couple of scenarios that involve Entity Framework or EF Core, which I'll refer to collectively as EF. EF should be set up with a scoped lifetime, so that within a given web request, exactly one instance of an EF DbContext is used. In ASP.NET Core when configuring EF Core, the helper methods take care of this for you, so you never have to make a decision about what lifetime to use. In EF 6, you had to figure it out yourself. And either way, if you're using the repository pattern, you have to make the right choice for your repository instances, too.</p>
<p>It's important that the right choice is used for EF DbContexts, specifically because they track the entities they work with. As such, you can't have an entity that is tracked by multiple DbContext instances - that will cause an exception. You also typically don't want to share entity instances between requests - that can cause bugs when two requests are making changes to an entity they both think they have exclusive access to.</p>
<p>So let's say you configure your repository instances to be transient. That means if you have two different classes within a request, like a controller and a service, that both need the same kind of repository, they'll each get a different, newly created instance. And assuming nothing else needs a DbContext, the first instance of the repository will get a new DbContext, and the second instance of the repository will reuse the same DbContext. There's probably no need to have two separate repository instances in this case, but there shouldn't be any bugs.</p>
<p>Now let's say you configure your repository instances to behave as singletons. Consider the same scenario in which a given web request needs the repository first in a controller and later in a service. The very first request to the web server will result in a newly created repository instance (which will be reused) and a newly created dbcontext that's then passed to the controller. Then in that same request, when the service is created, it is passed this same repository instance, which still has the same DbContext associated with it. The request completes just fine. Now a subsequent request comes in. It will once again use the same repository instance, which still has a reference to the same DbContext. But that instance was scoped to a web request that has completed, so it's not going to work for this request. Or consider another scenario, in which two requests are occurring at the same time. Both will share the repository, and its dbcontext, so any entities created and tracked will be shared between the two requests. If one request makes a partial update, and the other request calls SaveChanges, the update will occur immediately, perhaps resulting in an error due to database constraints. This same thing can happen if you configure your dbcontext to be a singleton.</p>
<p>So, in the case of EF DbContexts and Repositories, the key takeaway is that their lifetimes should match, and their lifetimes in web applications should be Scoped.</p>
<p>For other kinds of services, especially other ORMs like NHibernate, it's important you understand exactly how these types should be configured when it comes to their object lifetimes for web scenarios.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://deviq.com/dependency-injection/">Dependency Injection</a></li>
<li><a href="https://deviq.com/dependency-inversion-principle/">Dependency Inversion Principle</a></li>
<li><a href="https://www.pluralsight.com/courses/principles-oo-design">SOLID principles</a></li>
<li><a href="https://www.pluralsight.com/courses/refactoring-fundamentals">Refactoring</a></li>
</ul>
]]></description>
      <pubDate>Mon, 10 Dec 2018 07:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h1>Use the right object lifetime</h1>
<p>This week we talk about object lifetimes, why they matter, and how to choose the right one. We'll focus a little bit on Entity Framework since it's very popular and also very frequently misconfigured.</p>
<h2>Sponsor - devBetter Group Career Coaching for Developers</h2>
<p>This week I'm announcing my new developer career coaching program, <a href="https://devbetter.com">devBetter</a>. If you're not advancing as quickly in your career as you'd like, and you could use someone in your corner pushing you to succeed and opening up doors to new opportunities, check it out at devbetter.com.</p>
<h2>Show Notes / Transcript</h2>
<p>If you're not using <a href="https://deviq.com/dependency-injection/">dependency injection</a> or following the <a href="https://deviq.com/dependency-inversion-principle/">dependency inversion principle</a> in your code, you probably don't care much about object lifetimes. You can probably just instantiate new instances anywhere you need them and then let them be destroyed when they go out of scope. In this case, you probably have no use for an IoC or DI container. However, your code is probably also very tightly coupled, making it more difficult to test and reconfigure in the future. If it's working for you, keep at it, but if you're feeling pain from the coupling, I encourage you to check out my <a href="https://www.pluralsight.com/courses/principles-oo-design">SOLID principles</a> and <a href="https://www.pluralsight.com/courses/refactoring-fundamentals">Refactoring</a> courses on Pluralsight to learn a different way to compose things.</p>
<p>If you are using DI and containers, like most developers using ASP.NET Core where it's built-in, or even ASP.NET MVC, you've probably encountered the concept of object lifetimes before. There's some variety in the nomenclature for some of the options, but using the terminology of ASP.NET Core's container, there are three main kinds of object lifetimes: transient, scoped, and singleton. Let me cover these briefly and apologies if you're already well-versed in this topic.</p>
<p>Transient scope refers to objects that are created any time they're requested. If you request an instance of a type from the container, and that type's scope is transient, you're getting a brand new instance. If you ask for a type and that type has a constructor parameter that's configured to be transient, that constructor parameter is going to be a brand new instance, every time.</p>
<p>Scoped lifetime refers to objects that, once created, live on for the duration of a given HTTP request. If you ask the container for an instance multiple times within an HTTP request, you'll get the same instance every time. Regardless of where the request to the DI container comes from within the web request, the same object instance is returned from the DI container. The first call to get an instance of the type will get a new instance; every subsequent request for that type will get this same instance.</p>
<p>Singleton scope is simple - there's only one instance. The first time an instance is requested, it's created, or you can create it during startup and add it to the container then. After that, the same instance is used everywhere.</p>
<p>So, which one should you use? Well, naturally, it depends. Since we don't have a lot of time, let's just look at a couple of scenarios that involve Entity Framework or EF Core, which I'll refer to collectively as EF. EF should be set up with a scoped lifetime, so that within a given web request, exactly one instance of an EF DbContext is used. In ASP.NET Core when configuring EF Core, the helper methods take care of this for you, so you never have to make a decision about what lifetime to use. In EF 6, you had to figure it out yourself. And either way, if you're using the repository pattern, you have to make the right choice for your repository instances, too.</p>
<p>It's important that the right choice is used for EF DbContexts, specifically because they track the entities they work with. As such, you can't have an entity that is tracked by multiple DbContext instances - that will cause an exception. You also typically don't want to share entity instances between requests - that can cause bugs when two requests are making changes to an entity they both think they have exclusive access to.</p>
<p>So let's say you configure your repository instances to be transient. That means if you have two different classes within a request, like a controller and a service, that both need the same kind of repository, they'll each get a different, newly created instance. And assuming nothing else needs a DbContext, the first instance of the repository will get a new DbContext, and the second instance of the repository will reuse the same DbContext. There's probably no need to have two separate repository instances in this case, but there shouldn't be any bugs.</p>
<p>Now let's say you configure your repository instances to behave as singletons. Consider the same scenario in which a given web request needs the repository first in a controller and later in a service. The very first request to the web server will result in a newly created repository instance (which will be reused) and a newly created dbcontext that's then passed to the controller. Then in that same request, when the service is created, it is passed this same repository instance, which still has the same DbContext associated with it. The request completes just fine. Now a subsequent request comes in. It will once again use the same repository instance, which still has a reference to the same DbContext. But that instance was scoped to a web request that has completed, so it's not going to work for this request. Or consider another scenario, in which two requests are occurring at the same time. Both will share the repository, and its dbcontext, so any entities created and tracked will be shared between the two requests. If one request makes a partial update, and the other request calls SaveChanges, the update will occur immediately, perhaps resulting in an error due to database constraints. This same thing can happen if you configure your dbcontext to be a singleton.</p>
<p>So, in the case of EF DbContexts and Repositories, the key takeaway is that their lifetimes should match, and their lifetimes in web applications should be Scoped.</p>
<p>For other kinds of services, especially other ORMs like NHibernate, it's important you understand exactly how these types should be configured when it comes to their object lifetimes for web scenarios.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://devbetter.com">devBetter</a></li>
<li><a href="https://deviq.com/dependency-injection/">Dependency Injection</a></li>
<li><a href="https://deviq.com/dependency-inversion-principle/">Dependency Inversion Principle</a></li>
<li><a href="https://www.pluralsight.com/courses/principles-oo-design">SOLID principles</a></li>
<li><a href="https://www.pluralsight.com/courses/refactoring-fundamentals">Refactoring</a></li>
</ul>
]]></content:encoded>
      <enclosure length="5865624" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/4703a769-3409-42e9-abd2-5ba37464a842/00a1bd4e_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Use the Right Object Lifetime</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/4703a769-3409-42e9-abd2-5ba37464a842/3000x3000/1544411358artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:08:56</itunes:duration>
      <itunes:summary>This week we talk about object lifetimes, why they matter, and how to choose the right one. We&apos;ll focus a little bit on Entity Framework since it&apos;s very popular and also very frequently misconfigured.</itunes:summary>
      <itunes:subtitle>This week we talk about object lifetimes, why they matter, and how to choose the right one. We&apos;ll focus a little bit on Entity Framework since it&apos;s very popular and also very frequently misconfigured.</itunes:subtitle>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>33</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">58b87ede-dd3c-45b3-b0c9-bccdcd4d1580</guid>
      <title>How much do you make?</title>
      <description><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 32, in which we'll talk a little about money, salaries, and workplace taboos on sharing details about such things.</p>
<p>If you’re enjoying these tips, please leave a comment or rating in your podcast app, tell a friend about the podcast, or follow us on twitter and retweet our episode announcements so we can increase our audience. I really appreciate it.</p>
<h1>How much do you make?</h1>
<p>This week we talk about money. Specifically, how do you feel about discussing your salary with your coworkers and peers? Why do you feel the way you do?</p>
<h2>Sponsor - Ardalis Services</h2>
<p>Does your development team need a force multiplier to level up their quality? Contact Ardalis Services to see how we can help.</p>
<h2>Show Notes / Transcript</h2>
<p>I suspect this episode will be both interesting and perhaps somewhat uncomfortable for many listeners. A lot of people have an innate aversion to discussing salary numbers, money, etc. Let's start by examining this, and then move on to look at ways you can maximize what you get in exchange for the value you provide to your employer or customer.</p>
<p>Let's talk salary. I'll start, though since I've been self-employed for a while now, I'm going to cheat a bit and provide a quick story from early on in m career. When I got my first job in the late 90s, when the dot-com bubble was still expanding, I took an offer with a salary of $37,000. The consulting company I was working for was expanding rapidly. I was hired in August; another batch of new hires started in January. In speaking with them, I learned that they had been given offers of$42,000! I was understandably annoyed by this. Here I was, with six months' more experience and already providing value at a billable client and I was making 88% of what these new hires were making on day one.</p>
<p>Let's stop here for a moment. What are you thinking as I relate this story? Did I break some unwritten rules by discussing salary with these new associates of mine? Was it my fault that I was annoyed by this perceived inequality? Maybe you're thinking, &quot;Sure, you just demonstrated why it's a bad idea to talk salary with your coworkers, Steve. All it does is create bad blood and drama.&quot; If this is where you're coming from, I'm warning you now that I simply don't understand this position. I'll try to empathize, but at the end of the day I just don't get it, as will become clear in just a moment. If, after hearing the rest of the story, you want to help me understand why you still think keeping salary a secret is better for you, please leave me a note in the comments.</p>
<p>So, why did I want to discuss salary with my coworkers? The answer is simple: I wanted data. I wanted intel. I wanted to be able to make informed decisions about my career. I had aggregate data at my fingertips in the form of annual surveys conducted by my school's career placement office, but I wanted to know what someone in the exact same position at the exact same company was making, and I was able to easily acquire this information by simply striking up a friendly conversation.</p>
<p>Now, given this situation, what would you do? Regardless of whether you would ever actively inquire about salary, let's say your new team member volunteers their salary to you over lunch before you're able to stop them. The cat's out of the bag. You have the information. They're making a significant amount more than you, despite having less experience and having been hired into the same role. I imagine the following options are available:</p>
<ol>
<li>Do nothing. Forget about it. It's none of your business.</li>
<li>Hold onto the information. Maybe consider it when you next get a pay raise or promotion, and use it to consider whether to ask for more.</li>
<li>Start sending out resumes to other companies who might pay the same or more than what your company is now paying. If you get an offer, maybe your company will match it to keep you.</li>
<li>Go to your manager and demand an increase.</li>
</ol>
<p>I'm probably leaving out some other options - feel free to add them in the show comments. Back to my story.</p>
<p>After learning I was making $5k/year less than the batch of new hires, I went to my manager. I explained, respectfully, that I didn't think it was equitable for me to be making significantly less than the folks they'd just hired. My manager very quickly agreed to immediately adjust my salary to match, but asked me not to advertise that he was doing so to my coworkers. I agreed. In hindsight, perhaps I shouldn't have been so quick to agree to this, but at the time it seemed a small price to pay to get the immediate pay increase, and in any case it was just a verbal request, not a legal document I was asked to sign.</p>
<p>So, who won and who lost in this story, if there were in fact any winners or losers? I'm happy with the outcome, since it meant I was able to keep up with the rapidly rising salaries of the time without having to change companies. I really liked where I worked and wasn't contemplating looking elsewhere. If I'd been ambivalent or hostile toward my current employer, I'd likely have taken a different approach. Did the new hires lose anything by sharing information with me? Not that I can tell. Some companies try to enact gag order policies that may go so far as to threaten employees with termination if they share compensation details, but most of these clauses are unenforceable in my experience. I am not a lawyer so do your own research before acting on this opinion, though. In any case, I wasn't asked how I knew what I knew, so no individual was called out as a result my acting on the information I acquired. That leaves my employer. They &quot;lost&quot; in that they now had to pay one more of their employees the same rate they were paying others in the same position. Their profit margin shrunk slightly. But they also won in that they retained a valuable employee who was almost always billing, even while the market grew even tighter for software developers. I stayed there for another 4 years because they continued to grow my compensation and I continued to enjoy working there. If after a year or two I'd found myself underpaid by 20% or more there, I'd very likely have jumped to another position, costing them a highly billable consultant which is how they earned all their revenue.</p>
<p>Could this have gone badly? Perhaps. It's easy to say in hindsight that it was a good move, but what if instead of bumping my pay my manager had fired me for breaking the company's rules about discussing compensation (we didn't have any, but say we did). This was a risk, but I had risk tolerance and I felt the risk likelihood was small. I hadn't yet really expanded my lifestyle and expenses from that of a college student, Iso my expenses were small relative to my income, and I didn't yet have children. The market was also great, and I'm sure if I'd been let go I'd have gotten another offer within a few weeks. Like today in 2018, everybody seemed to be hiring. Would I have made the same choices if unemployment were high, layoffs were going on everywhere, and I didn't know how I'd make ends meet if I lost my job? Maybe not. But I'd still want as much accurate intel as I could get so that I could make the best decision for me given whatever the circumstances.</p>
<p>Let's wrap up by considering who stands to gain from keeping salary details secret. For many listeners I suspect you can't imagine working somewhere that had transparent compensation details, but as a former Army officer I can tell you it's not a big deal. Everybody in the military, and in government service, knows exactly how much everybody else is making. You can check out the pay scale any time you want. It's not an issue. So, it shouldn't be assumed that secret compensation is somehow the only way to do things. It should by now be obvious that the ones who stand to gain the most from keeping salaries secret from one another are the company's owners. By paying different amounts for potentially the same work, they're able to increase profit margins. Pay differences can be warranted, and whether they are or not, they can seed discontent and hurt morale. Or they can empower employees to ask for what they think they're worth, as in my case, which can end up costing the company more in payroll. If companies pay different amounts to different individuals, and this is transparent, they need a way to justify this decision. This can require more communication. Just as it gives the employee more information and freedom to make decisions, it limits the company's freedom to negotiate from a position of having more information than the other party. In negotiations and economics in general, when one party has a better information than another, they can use this to their advantage and get themselves a better deal. By sharing information, employees aren't gaining an unfair advantage, they're merely eliminating an unfair advantage their employer previously held.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://amzn.to/2DzohZV">What Color is Your Parachute (book)</a> Great tips on job hunting and career - I read an earlier edition many years ago</li>
<li><a href="https://militarybenefits.info/2018-military-pay-charts/">2018 US Military Pay Scale</a></li>
</ul>
]]></description>
      <pubDate>Mon, 12 Nov 2018 07:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis.</p>
<p>This is episode 32, in which we'll talk a little about money, salaries, and workplace taboos on sharing details about such things.</p>
<p>If you’re enjoying these tips, please leave a comment or rating in your podcast app, tell a friend about the podcast, or follow us on twitter and retweet our episode announcements so we can increase our audience. I really appreciate it.</p>
<h1>How much do you make?</h1>
<p>This week we talk about money. Specifically, how do you feel about discussing your salary with your coworkers and peers? Why do you feel the way you do?</p>
<h2>Sponsor - Ardalis Services</h2>
<p>Does your development team need a force multiplier to level up their quality? Contact Ardalis Services to see how we can help.</p>
<h2>Show Notes / Transcript</h2>
<p>I suspect this episode will be both interesting and perhaps somewhat uncomfortable for many listeners. A lot of people have an innate aversion to discussing salary numbers, money, etc. Let's start by examining this, and then move on to look at ways you can maximize what you get in exchange for the value you provide to your employer or customer.</p>
<p>Let's talk salary. I'll start, though since I've been self-employed for a while now, I'm going to cheat a bit and provide a quick story from early on in m career. When I got my first job in the late 90s, when the dot-com bubble was still expanding, I took an offer with a salary of $37,000. The consulting company I was working for was expanding rapidly. I was hired in August; another batch of new hires started in January. In speaking with them, I learned that they had been given offers of$42,000! I was understandably annoyed by this. Here I was, with six months' more experience and already providing value at a billable client and I was making 88% of what these new hires were making on day one.</p>
<p>Let's stop here for a moment. What are you thinking as I relate this story? Did I break some unwritten rules by discussing salary with these new associates of mine? Was it my fault that I was annoyed by this perceived inequality? Maybe you're thinking, &quot;Sure, you just demonstrated why it's a bad idea to talk salary with your coworkers, Steve. All it does is create bad blood and drama.&quot; If this is where you're coming from, I'm warning you now that I simply don't understand this position. I'll try to empathize, but at the end of the day I just don't get it, as will become clear in just a moment. If, after hearing the rest of the story, you want to help me understand why you still think keeping salary a secret is better for you, please leave me a note in the comments.</p>
<p>So, why did I want to discuss salary with my coworkers? The answer is simple: I wanted data. I wanted intel. I wanted to be able to make informed decisions about my career. I had aggregate data at my fingertips in the form of annual surveys conducted by my school's career placement office, but I wanted to know what someone in the exact same position at the exact same company was making, and I was able to easily acquire this information by simply striking up a friendly conversation.</p>
<p>Now, given this situation, what would you do? Regardless of whether you would ever actively inquire about salary, let's say your new team member volunteers their salary to you over lunch before you're able to stop them. The cat's out of the bag. You have the information. They're making a significant amount more than you, despite having less experience and having been hired into the same role. I imagine the following options are available:</p>
<ol>
<li>Do nothing. Forget about it. It's none of your business.</li>
<li>Hold onto the information. Maybe consider it when you next get a pay raise or promotion, and use it to consider whether to ask for more.</li>
<li>Start sending out resumes to other companies who might pay the same or more than what your company is now paying. If you get an offer, maybe your company will match it to keep you.</li>
<li>Go to your manager and demand an increase.</li>
</ol>
<p>I'm probably leaving out some other options - feel free to add them in the show comments. Back to my story.</p>
<p>After learning I was making $5k/year less than the batch of new hires, I went to my manager. I explained, respectfully, that I didn't think it was equitable for me to be making significantly less than the folks they'd just hired. My manager very quickly agreed to immediately adjust my salary to match, but asked me not to advertise that he was doing so to my coworkers. I agreed. In hindsight, perhaps I shouldn't have been so quick to agree to this, but at the time it seemed a small price to pay to get the immediate pay increase, and in any case it was just a verbal request, not a legal document I was asked to sign.</p>
<p>So, who won and who lost in this story, if there were in fact any winners or losers? I'm happy with the outcome, since it meant I was able to keep up with the rapidly rising salaries of the time without having to change companies. I really liked where I worked and wasn't contemplating looking elsewhere. If I'd been ambivalent or hostile toward my current employer, I'd likely have taken a different approach. Did the new hires lose anything by sharing information with me? Not that I can tell. Some companies try to enact gag order policies that may go so far as to threaten employees with termination if they share compensation details, but most of these clauses are unenforceable in my experience. I am not a lawyer so do your own research before acting on this opinion, though. In any case, I wasn't asked how I knew what I knew, so no individual was called out as a result my acting on the information I acquired. That leaves my employer. They &quot;lost&quot; in that they now had to pay one more of their employees the same rate they were paying others in the same position. Their profit margin shrunk slightly. But they also won in that they retained a valuable employee who was almost always billing, even while the market grew even tighter for software developers. I stayed there for another 4 years because they continued to grow my compensation and I continued to enjoy working there. If after a year or two I'd found myself underpaid by 20% or more there, I'd very likely have jumped to another position, costing them a highly billable consultant which is how they earned all their revenue.</p>
<p>Could this have gone badly? Perhaps. It's easy to say in hindsight that it was a good move, but what if instead of bumping my pay my manager had fired me for breaking the company's rules about discussing compensation (we didn't have any, but say we did). This was a risk, but I had risk tolerance and I felt the risk likelihood was small. I hadn't yet really expanded my lifestyle and expenses from that of a college student, Iso my expenses were small relative to my income, and I didn't yet have children. The market was also great, and I'm sure if I'd been let go I'd have gotten another offer within a few weeks. Like today in 2018, everybody seemed to be hiring. Would I have made the same choices if unemployment were high, layoffs were going on everywhere, and I didn't know how I'd make ends meet if I lost my job? Maybe not. But I'd still want as much accurate intel as I could get so that I could make the best decision for me given whatever the circumstances.</p>
<p>Let's wrap up by considering who stands to gain from keeping salary details secret. For many listeners I suspect you can't imagine working somewhere that had transparent compensation details, but as a former Army officer I can tell you it's not a big deal. Everybody in the military, and in government service, knows exactly how much everybody else is making. You can check out the pay scale any time you want. It's not an issue. So, it shouldn't be assumed that secret compensation is somehow the only way to do things. It should by now be obvious that the ones who stand to gain the most from keeping salaries secret from one another are the company's owners. By paying different amounts for potentially the same work, they're able to increase profit margins. Pay differences can be warranted, and whether they are or not, they can seed discontent and hurt morale. Or they can empower employees to ask for what they think they're worth, as in my case, which can end up costing the company more in payroll. If companies pay different amounts to different individuals, and this is transparent, they need a way to justify this decision. This can require more communication. Just as it gives the employee more information and freedom to make decisions, it limits the company's freedom to negotiate from a position of having more information than the other party. In negotiations and economics in general, when one party has a better information than another, they can use this to their advantage and get themselves a better deal. By sharing information, employees aren't gaining an unfair advantage, they're merely eliminating an unfair advantage their employer previously held.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://amzn.to/2DzohZV">What Color is Your Parachute (book)</a> Great tips on job hunting and career - I read an earlier edition many years ago</li>
<li><a href="https://militarybenefits.info/2018-military-pay-charts/">2018 US Military Pay Scale</a></li>
</ul>
]]></content:encoded>
      <enclosure length="6107030" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/ee7d3f3a-f248-4fbb-8424-f41a00c91610/465a83a2_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>How much do you make?</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/ee7d3f3a-f248-4fbb-8424-f41a00c91610/3000x3000/1542045019artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:09:22</itunes:duration>
      <itunes:summary>This week we talk about money. Specifically, how do you feel about discussing your salary with your coworkers and peers? Why do you feel the way you do?</itunes:summary>
      <itunes:subtitle>This week we talk about money. Specifically, how do you feel about discussing your salary with your coworkers and peers? Why do you feel the way you do?</itunes:subtitle>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>32</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">8249a74d-2b5b-4433-ba24-56b2b9dc748c</guid>
      <title>Breaking Bad Coding Habits</title>
      <description><![CDATA[<h1>Breaking Bad Coding Habits</h1>
<p>This week guest Joe Zack talks about how to apply the power of habit to break bad coding habits. Joe is a software developer based in Central Florida. He is a host of the Coding Blocks podcast and is particularly excited about Search Engines and the JAMStack these days.</p>
<h2>Sponsor - Ardalis Services</h2>
<p>Does your development team need a force multiplier to level up their quality? Contact Ardalis Services to see how we can help.</p>
<h2>Show Notes / Transcript</h2>
<p>Hello my name is Joe Zack, and I’m a long time developer and podcaster over at <a href="https://www.codingblocks.net/">Coding Blocks</a>. I’m also a huge sucker for the Business-y PopSci Self-Help kind of books that you see on Top Seller lists. I like to take the lessons from those books and try apply them to my programming.</p>
<p>One book I particularly enjoyed was <a href="https://amzn.to/2q0GXsT">&quot;The Power of Habit&quot;</a> by Charles Duhigg, check the show notes for a link. This book describes the building of habits as the process of taking explicit procedural actions, and turning them into implicit declarative actions.</p>
<p>And hey, that sounds kinda like programming to me! We programmers figure out precisely what operations need to occur to fulfill our requirements, and we write programs to automate those operations so that we can deal things at a higher level of abstraction. That enables us to combine and compose these programs to solve even bigger problems without getting tripped up on tiny little details.</p>
<p><a href="https://amzn.to/2q0GXsT">&quot;The Power of Habit&quot;</a> book promises that building good habits is much like building a SOLID API. You spend the time up front building good habits, and then you get a multiple of that time back with reduced maintenance costs over time.</p>
<p>But what if your API isn’t so SOLID? What if you’ve developed some bad habits that you would like to change?</p>
<p>Well then, you’re in luck - because the book spends a lot of time looking at how habits can be changed and I’m here to share some of that with you.</p>
<p>An example of a bad programming habit that I have is only considering the &quot;happy path” operations that need to happen to meet a requirement. I tend to focus too much on how to make something work, and not enough on how to handle problems that might arise in the real-world.</p>
<p>In writing about changing habits, author Charles Duhigg encourages me to determine the cue, routine, reward, and craving in this bad habit. If I can determine those 4 aspects of the habit, then I can figure out how best to change it.</p>
<p>In this example, I can look back and see that my undesirable behavior most often occurs when I’m estimating tickets, so that is my “cue”.</p>
<p>The “routine” is my act of imagining the work that needs to happen to fulfill the requirements of the ticket and then estimating how long that will take.</p>
<p>My “reward” is that I can get back to programming, which is an activity that I enjoy a lot more than estimating. In fact, the consequences for my bad estimates are typically deferred until I actually start working on those tickets.</p>
<p>The final aspect of a habit is the “craving”. This is the anticipation of the reward. Knowing that I can get back to “real work” once I complete my estimates provides an incentive for working quickly, rather than accurately.</p>
<p>According to the book, the trick to changing habits is to recognize the cue, craving and reward - and to replace the routine.</p>
<p>In my example, a good tactic would be to replace my current imaginative process with a more disciplined approach. Perhaps adding together a separate estimate for the happy path and one for dealing with exceptions would encourage me to look at the bigger picture and would lead to a more accurate result.</p>
<p>I’m going to give this a shot, and see how it goes. In the meantime I hope that you take a moment to consider how healthy your programming habits are. If there are any habits that you are unhappy with, then remember that you can change them by recognizing the cue, craving and reward - and changing the routine that you perform in response to those stimuli.</p>
<p>Keep doing the right thing, and eventually you’ll codify that habit into your mental muscle memory so that the good behaviors flow without you having to think explicitly about it and you can operate efficiently at a higher level of abstraction.</p>
<p>Thanks for having me on the show Steve!</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://amzn.to/2q0GXsT">The Power of Habit: Why We Do What We Do in Life and Business</a> <a href="https://www.audible.com/pd/The-Power-of-Habit-Audiobook/B007C64916">On Audible</a></li>
<li><a href="https://www.allencheng.com/power-of-habit-summary-duhigg/">Power of Habit Summary</a></li>
</ul>
]]></description>
      <pubDate>Mon, 22 Oct 2018 06:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h1>Breaking Bad Coding Habits</h1>
<p>This week guest Joe Zack talks about how to apply the power of habit to break bad coding habits. Joe is a software developer based in Central Florida. He is a host of the Coding Blocks podcast and is particularly excited about Search Engines and the JAMStack these days.</p>
<h2>Sponsor - Ardalis Services</h2>
<p>Does your development team need a force multiplier to level up their quality? Contact Ardalis Services to see how we can help.</p>
<h2>Show Notes / Transcript</h2>
<p>Hello my name is Joe Zack, and I’m a long time developer and podcaster over at <a href="https://www.codingblocks.net/">Coding Blocks</a>. I’m also a huge sucker for the Business-y PopSci Self-Help kind of books that you see on Top Seller lists. I like to take the lessons from those books and try apply them to my programming.</p>
<p>One book I particularly enjoyed was <a href="https://amzn.to/2q0GXsT">&quot;The Power of Habit&quot;</a> by Charles Duhigg, check the show notes for a link. This book describes the building of habits as the process of taking explicit procedural actions, and turning them into implicit declarative actions.</p>
<p>And hey, that sounds kinda like programming to me! We programmers figure out precisely what operations need to occur to fulfill our requirements, and we write programs to automate those operations so that we can deal things at a higher level of abstraction. That enables us to combine and compose these programs to solve even bigger problems without getting tripped up on tiny little details.</p>
<p><a href="https://amzn.to/2q0GXsT">&quot;The Power of Habit&quot;</a> book promises that building good habits is much like building a SOLID API. You spend the time up front building good habits, and then you get a multiple of that time back with reduced maintenance costs over time.</p>
<p>But what if your API isn’t so SOLID? What if you’ve developed some bad habits that you would like to change?</p>
<p>Well then, you’re in luck - because the book spends a lot of time looking at how habits can be changed and I’m here to share some of that with you.</p>
<p>An example of a bad programming habit that I have is only considering the &quot;happy path” operations that need to happen to meet a requirement. I tend to focus too much on how to make something work, and not enough on how to handle problems that might arise in the real-world.</p>
<p>In writing about changing habits, author Charles Duhigg encourages me to determine the cue, routine, reward, and craving in this bad habit. If I can determine those 4 aspects of the habit, then I can figure out how best to change it.</p>
<p>In this example, I can look back and see that my undesirable behavior most often occurs when I’m estimating tickets, so that is my “cue”.</p>
<p>The “routine” is my act of imagining the work that needs to happen to fulfill the requirements of the ticket and then estimating how long that will take.</p>
<p>My “reward” is that I can get back to programming, which is an activity that I enjoy a lot more than estimating. In fact, the consequences for my bad estimates are typically deferred until I actually start working on those tickets.</p>
<p>The final aspect of a habit is the “craving”. This is the anticipation of the reward. Knowing that I can get back to “real work” once I complete my estimates provides an incentive for working quickly, rather than accurately.</p>
<p>According to the book, the trick to changing habits is to recognize the cue, craving and reward - and to replace the routine.</p>
<p>In my example, a good tactic would be to replace my current imaginative process with a more disciplined approach. Perhaps adding together a separate estimate for the happy path and one for dealing with exceptions would encourage me to look at the bigger picture and would lead to a more accurate result.</p>
<p>I’m going to give this a shot, and see how it goes. In the meantime I hope that you take a moment to consider how healthy your programming habits are. If there are any habits that you are unhappy with, then remember that you can change them by recognizing the cue, craving and reward - and changing the routine that you perform in response to those stimuli.</p>
<p>Keep doing the right thing, and eventually you’ll codify that habit into your mental muscle memory so that the good behaviors flow without you having to think explicitly about it and you can operate efficiently at a higher level of abstraction.</p>
<p>Thanks for having me on the show Steve!</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://amzn.to/2q0GXsT">The Power of Habit: Why We Do What We Do in Life and Business</a> <a href="https://www.audible.com/pd/The-Power-of-Habit-Audiobook/B007C64916">On Audible</a></li>
<li><a href="https://www.allencheng.com/power-of-habit-summary-duhigg/">Power of Habit Summary</a></li>
</ul>
]]></content:encoded>
      <enclosure length="3553824" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/45a1cb12-a494-41f0-9e3b-5764e17e913c/6557f8b7_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Breaking Bad Coding Habits</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/45a1cb12-a494-41f0-9e3b-5764e17e913c/3000x3000/1540174942artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:05:03</itunes:duration>
      <itunes:summary>This week guest Joe Zack talks about how to apply the power of habit to break bad coding habits.</itunes:summary>
      <itunes:subtitle>This week guest Joe Zack talks about how to apply the power of habit to break bad coding habits.</itunes:subtitle>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>31</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">11137f3f-4785-42f3-a10e-234b38000c70</guid>
      <title>On Code Smells</title>
      <description><![CDATA[<p>I've talked quite a bit about <a href="https://deviq.com/code-smells/">code smells</a> over the course of my career. My <a href="https://www.pluralsight.com/courses/refactoring-fundamentals">Refactoring Fundamentals</a> and <a href="https://www.pluralsight.com/courses/microsoft-azure-code-refactoring">Azure Refactoring</a> courses on Pluralsight both discuss the topic, with the former going into great depth and covering literally dozens of code smells. The course is over 8 hours long, but it not only demonstrates tons of code smells but also shows how to refactor to improve your code in response to them.</p>
<p>It's important to note that code smells represent things in your code that are potentially bad. They should catch your attention, and you should think about whether, in context, the smell in question is acceptable or not. Sometimes, it's perfectly fine, or it's not worth the effort to refactor to a different design.</p>
<p>If you've never heard of the term code smell, I encourage you to look into it. There are some links in the show notes for this episode. One benefit of learning about code smells mirrors a benefit of learning about design patterns, which is that these named smells allow you to identify and communicate concepts quickly with other developers. For example, if you're discussing some code and mention it seems to have 'primitive obsession', that term refers to a specific code smell which is well-documented and which has certain known refactoring approaches. By using this term, you convey a lot of information in just two words that otherwise might have required a great deal more explanation.</p>
<p>It can be useful as well to learn about different categories of code smells. These categories include things like Bloaters, Obfuscators, and Couplers, as well as smells specific to kinds of code, like testing smells. These categories help as you're learning about code smells because they let you see a variety of smells that all have similar impacts on the code. Bloaters tend to result in code becoming larger than necessary. Couplers introduce unnecessary coupling into the application. Obfuscators make it more difficult to quickly understand how some part of your application works. And test smells make tests more difficult to write and maintain, or less reliable when run.</p>
<p>Some code smells you can identify with static code analysis tools, like <a href="https://www.ndepend.com/">NDepend</a>. For instance, you can easily write a query in NDepend to return all methods over a certain number of lines of code. These kinds of tools can help you identify potential problem areas in your code so you can better direct your refactoring efforts.</p>
<p>I may dive into some different code smells, and how to correct them, in future tips. In the meantime, if you want to get up to speed the best resource I can recommend is my Refactoring Fundamentals course, on Pluralsight.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://www.pluralsight.com/courses/refactoring-fundamentals">Refactoring Fundamentals</a></li>
<li><a href="https://www.pluralsight.com/courses/microsoft-azure-code-refactoring">Azure Developer: Refactoring Code</a></li>
<li><a href="https://deviq.com/code-smells/">Code Smells</a></li>
<li><a href="https://amzn.to/2A709uN">Refactoring Book (classic 1999)</a></li>
<li><a href="https://amzn.to/2yaYyTt">Refactoring Book (2nd Ed.)</a> (Available 31 Dec 2018)</li>
</ul>
]]></description>
      <pubDate>Mon, 15 Oct 2018 06:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>I've talked quite a bit about <a href="https://deviq.com/code-smells/">code smells</a> over the course of my career. My <a href="https://www.pluralsight.com/courses/refactoring-fundamentals">Refactoring Fundamentals</a> and <a href="https://www.pluralsight.com/courses/microsoft-azure-code-refactoring">Azure Refactoring</a> courses on Pluralsight both discuss the topic, with the former going into great depth and covering literally dozens of code smells. The course is over 8 hours long, but it not only demonstrates tons of code smells but also shows how to refactor to improve your code in response to them.</p>
<p>It's important to note that code smells represent things in your code that are potentially bad. They should catch your attention, and you should think about whether, in context, the smell in question is acceptable or not. Sometimes, it's perfectly fine, or it's not worth the effort to refactor to a different design.</p>
<p>If you've never heard of the term code smell, I encourage you to look into it. There are some links in the show notes for this episode. One benefit of learning about code smells mirrors a benefit of learning about design patterns, which is that these named smells allow you to identify and communicate concepts quickly with other developers. For example, if you're discussing some code and mention it seems to have 'primitive obsession', that term refers to a specific code smell which is well-documented and which has certain known refactoring approaches. By using this term, you convey a lot of information in just two words that otherwise might have required a great deal more explanation.</p>
<p>It can be useful as well to learn about different categories of code smells. These categories include things like Bloaters, Obfuscators, and Couplers, as well as smells specific to kinds of code, like testing smells. These categories help as you're learning about code smells because they let you see a variety of smells that all have similar impacts on the code. Bloaters tend to result in code becoming larger than necessary. Couplers introduce unnecessary coupling into the application. Obfuscators make it more difficult to quickly understand how some part of your application works. And test smells make tests more difficult to write and maintain, or less reliable when run.</p>
<p>Some code smells you can identify with static code analysis tools, like <a href="https://www.ndepend.com/">NDepend</a>. For instance, you can easily write a query in NDepend to return all methods over a certain number of lines of code. These kinds of tools can help you identify potential problem areas in your code so you can better direct your refactoring efforts.</p>
<p>I may dive into some different code smells, and how to correct them, in future tips. In the meantime, if you want to get up to speed the best resource I can recommend is my Refactoring Fundamentals course, on Pluralsight.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://www.pluralsight.com/courses/refactoring-fundamentals">Refactoring Fundamentals</a></li>
<li><a href="https://www.pluralsight.com/courses/microsoft-azure-code-refactoring">Azure Developer: Refactoring Code</a></li>
<li><a href="https://deviq.com/code-smells/">Code Smells</a></li>
<li><a href="https://amzn.to/2A709uN">Refactoring Book (classic 1999)</a></li>
<li><a href="https://amzn.to/2yaYyTt">Refactoring Book (2nd Ed.)</a> (Available 31 Dec 2018)</li>
</ul>
]]></content:encoded>
      <enclosure length="2514938" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/1d8d4039-ab73-4ede-8350-ff9765367161/ab7a7c5a_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>On Code Smells</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/1d8d4039-ab73-4ede-8350-ff9765367161/3000x3000/1539362475artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:03:55</itunes:duration>
      <itunes:summary>Code Smells, or bad smells in code, are discussed in the book, Refactoring. Martin Fowler and Kent Beck discuss them and how they can be used to identify potential places to refactor in your code.</itunes:summary>
      <itunes:subtitle>Code Smells, or bad smells in code, are discussed in the book, Refactoring. Martin Fowler and Kent Beck discuss them and how they can be used to identify potential places to refactor in your code.</itunes:subtitle>
      <itunes:keywords>code smell, refactoring</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>30</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">bf99477e-a459-4d00-9858-3e420e89ab04</guid>
      <title>Shared Kernel as a Package</title>
      <description><![CDATA[<h1>Shared Kernel as a Package</h1>
<p>Code shared between applications within an organization is typically referred to as a shared kernel in domain-driven design. This week's tip discusses this approach and how best to do the sharing.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>If you've written more than one application, or worked for a company that has more than one, you've probably shared code between the applications. There are a variety of approaches to this, one of the most awful being the One Solution To Rule Them All approach, in which every bit of code ever written is added to a single code repository and a single solution file. One or more projects in this solution become the shared projects used by many different applications. The benefit of this approach is that developers can easily view and even debug all of the code possibly used by anything. Changes that might break dependent projects are often discovered quickly. However, if a single project requires an update to shared code, it's not easy to have one project depend on a different version of the shared library than another. Even if you use more than one solution, if you're sharing code between multiple solutions at the file system level, you're probably in this boat.</p>
<p>In <a href="https://www.pluralsight.com/courses/domain-driven-design-fundamentals">Domain-Driven Design</a>, the Shared Kernel is code that more than one bounded context depends on. The contract between the shared kernel code and its dependents is that the shared kernel code doesn't change unless all downstream dependencies agree with the change. Often it's one team maintaining the shared kernel and its dependent projects, in which case this is pretty easy, but in larger organizations there may be an approval process involving several teams. When updates do occur, they should be decoupled from dependencies such that they can pull in the update when they're ready. This enables updating the shared kernel code without having to test and update every downstream dependency immediately.</p>
<p>In .NET, one way to gain the ability to have dependent projects pull in the latest updates to the shared kernel whenever they're ready is to use a Nuget package. Any time an update is made to the shared kernel, its package should be updated and its version updated. For example, you might initially have Acme.SharedKernel version 1.0.0, which two projects reference. Project A needs additional functionality, and it's agreed to place it in the shared kernel. A new package is published, with version 1.0.1. Project A updates its version of the package to require 1.0.1 and is able to be deployed. Project B continues to depend on version 1.0.0 and can continue with development and/or remain deployed using this version. Project B can choose when and how often to update which version of the shared kernel package it uses.</p>
<p>If you follow this approach, there are a few things that you may find helpful. First, use continuous integration for your shared kernel library. When you make updates to it, the automated build should compile it, run tests (yes, it should have tests), update its version number, and publish it. This ensures you have a consistent process, which is important especially when we're talking about deploying versioned packages. Next, you'll want to have a way to share the package between your developers and build machines. One nice thing about Nuget is that any file share can serve as a Nuget server, so at a minimum you can simply drop versioned nupkg files into a particular file share. Alternately, you can use an actual Nuget server, such as one built into Jetbrains TeamCity or VSTS/Azure DevOps. You can use a cloud-based solution like myget, if you prefer. In any case, you simply need a way to distibute your shared, versioned packages.</p>
<p>With these fairly small pieces in place, you should find that you're able to decoupled your shared kernel package from its dependents such that you can make updates to it as required and pull in those updates only as needed by each dependency. You should also find that, being a separate solution with a separate automated build, it's less likely that developers will make cavalier changes to the shared kernel, so it should become more stable by default and should only be updated when truly needed by its downstream dependencies. And of course, you should do whatever you can to minimize the things your shared kernel code depends on, since it's going to be depended on by most of your applications. Keep it lightweight and don't depend on anything from it that you can avoid.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://www.pluralsight.com/courses/domain-driven-design-fundamentals">Domain-Driven Design</a></li>
</ul>
]]></description>
      <pubDate>Mon, 8 Oct 2018 06:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h1>Shared Kernel as a Package</h1>
<p>Code shared between applications within an organization is typically referred to as a shared kernel in domain-driven design. This week's tip discusses this approach and how best to do the sharing.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>If you've written more than one application, or worked for a company that has more than one, you've probably shared code between the applications. There are a variety of approaches to this, one of the most awful being the One Solution To Rule Them All approach, in which every bit of code ever written is added to a single code repository and a single solution file. One or more projects in this solution become the shared projects used by many different applications. The benefit of this approach is that developers can easily view and even debug all of the code possibly used by anything. Changes that might break dependent projects are often discovered quickly. However, if a single project requires an update to shared code, it's not easy to have one project depend on a different version of the shared library than another. Even if you use more than one solution, if you're sharing code between multiple solutions at the file system level, you're probably in this boat.</p>
<p>In <a href="https://www.pluralsight.com/courses/domain-driven-design-fundamentals">Domain-Driven Design</a>, the Shared Kernel is code that more than one bounded context depends on. The contract between the shared kernel code and its dependents is that the shared kernel code doesn't change unless all downstream dependencies agree with the change. Often it's one team maintaining the shared kernel and its dependent projects, in which case this is pretty easy, but in larger organizations there may be an approval process involving several teams. When updates do occur, they should be decoupled from dependencies such that they can pull in the update when they're ready. This enables updating the shared kernel code without having to test and update every downstream dependency immediately.</p>
<p>In .NET, one way to gain the ability to have dependent projects pull in the latest updates to the shared kernel whenever they're ready is to use a Nuget package. Any time an update is made to the shared kernel, its package should be updated and its version updated. For example, you might initially have Acme.SharedKernel version 1.0.0, which two projects reference. Project A needs additional functionality, and it's agreed to place it in the shared kernel. A new package is published, with version 1.0.1. Project A updates its version of the package to require 1.0.1 and is able to be deployed. Project B continues to depend on version 1.0.0 and can continue with development and/or remain deployed using this version. Project B can choose when and how often to update which version of the shared kernel package it uses.</p>
<p>If you follow this approach, there are a few things that you may find helpful. First, use continuous integration for your shared kernel library. When you make updates to it, the automated build should compile it, run tests (yes, it should have tests), update its version number, and publish it. This ensures you have a consistent process, which is important especially when we're talking about deploying versioned packages. Next, you'll want to have a way to share the package between your developers and build machines. One nice thing about Nuget is that any file share can serve as a Nuget server, so at a minimum you can simply drop versioned nupkg files into a particular file share. Alternately, you can use an actual Nuget server, such as one built into Jetbrains TeamCity or VSTS/Azure DevOps. You can use a cloud-based solution like myget, if you prefer. In any case, you simply need a way to distibute your shared, versioned packages.</p>
<p>With these fairly small pieces in place, you should find that you're able to decoupled your shared kernel package from its dependents such that you can make updates to it as required and pull in those updates only as needed by each dependency. You should also find that, being a separate solution with a separate automated build, it's less likely that developers will make cavalier changes to the shared kernel, so it should become more stable by default and should only be updated when truly needed by its downstream dependencies. And of course, you should do whatever you can to minimize the things your shared kernel code depends on, since it's going to be depended on by most of your applications. Keep it lightweight and don't depend on anything from it that you can avoid.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://www.pluralsight.com/courses/domain-driven-design-fundamentals">Domain-Driven Design</a></li>
</ul>
]]></content:encoded>
      <enclosure length="3312435" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/8a48a616-ea23-4910-a29c-472deb2e10f0/718a5d8f_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Shared Kernel as a Package</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/8a48a616-ea23-4910-a29c-472deb2e10f0/3000x3000/1538950813artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:05:11</itunes:duration>
      <itunes:summary>Code shared between applications within an organization is typically referred to as a shared kernel in domain-driven design. This week&apos;s tip discusses this approach and how best to do the sharing.</itunes:summary>
      <itunes:subtitle>Code shared between applications within an organization is typically referred to as a shared kernel in domain-driven design. This week&apos;s tip discusses this approach and how best to do the sharing.</itunes:subtitle>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>29</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">a1a4ddd8-72a6-49e7-8a59-eec92cf1eeaf</guid>
      <title>Applying Pain Driven Development to Patterns</title>
      <description><![CDATA[<h1>Applying Pain Driven Development to Patterns</h1>
<p>This week we talk about specific ways you can apply my strategy of Pain Driven Development to the use of design patterns. This is an excerpt from my Design Pattern Mastery presentation that goes into more detail on design patterns.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>I talked about <a href="/010">Pain Driven Development, or PDD, in episode 10</a> - check out that episode first if you're not familiar with the practice. I've recently been focusing a bit on some design patterns. An easy trap to fall into with design patterns is trying to apply them too frequently or too soon. PDD suggests waiting to experience pain while trying to work with the application's current design before you attempt to <a href="https://www.pluralsight.com/courses/refactoring-fundamentals">refactor</a> to improve its design by applying a design pattern. In this tip, I'll walk through a few common steps where applying a specific pattern may be helpful.</p>
<p>To begin, let's assume we have a very simple web application. Let's say it's using MVC, and there's a controller that needs to be used to return some data fetched from a database. It could be an API endpoint or a view-based page - the UI format isn't important in this case. The absolute simplest thing you can do in this situation is hard code your data access code into your controller. So, assuming you're using ASP.NET Core and Entity Framework Core, you could instantiate an <code>DbContext</code> in the controller and use that to fetch the data. This works and meets the immediate requirement, so you ship this version.</p>
<p>A little bit later, your application has grown more complex. You have some filters that also use data, along with other services. You start to notice occasional bugs from EF and realize that you've introduced a bug. By instantiating a new <code>DbContext</code> in each controller, but occasionally passing around entities between parts of the application, EF gets in a state where entities are tracked by one instance but you're trying to operate on them with another instance of <code>DbContext</code>. You need to use a single EF Core <code>DbContext</code> per web request, which is to say it should have a &quot;Scoped&quot; lifetime. Fortunately, ASP.NET Core makes it very easy to achieve this by configuring your <code>DbContext</code> inside of <code>ConfigureServices</code>. In fact, if you don't read the docs, you probably don't even know what lifetime EF Core is using, because it's hidden within an extension method. In any case, once you configure <code>DbContext</code> in ConfigureServices, you need a way to get it into your Controller(s). To do this requires the <a href="/019">Strategy pattern, covered in episode 19</a>. If you're familiar with dependency injection, you've used the Strategy pattern. Add a constructor to your Controller, pass in the <code>DbContext</code>, and set a private local field with the value passed into the constructor. Do this anywhere you're otherwise newing up the <code>DbContext</code>. Remind yourself <a href="/005">'new is glue'</a>. You just fixed an issue with too tight of coupling to the instantiation process by using the service collection built into ASP.NET Core, an IOC container, essentially a factory on steroids. Your EF Core lifetime bug is now fixed, so you ship the code.</p>
<p>Some more time passes, the application has grown, and now there are a bunch of controllers and other places that all have <code>DbContext</code> injected into them. You've noticed some duplication in how code works with the <code>DbContext</code>. You've also found that it's tough to unit test your classes that have a real DbContext injected, except by configuring EF Core to use its In Memory data store. This works, but you'd prefer it if your unit tests truly had no dependencies so you could just test behavior, not low-level data access libraries. You decide that you can solve both of these problems by introducing the Repository pattern, which is just a fancy name for an abstraction used to encapsulate the low level details of your data access. You create a few such interfaces, implement them with <code>DbContext</code>, and make sure your Controllers and other classes that were directly using <code>DbContext</code> now have an interface injected instead. Along the way you fix a couple of bugs you discovered that had grown due to duplicate code that had evolved differently, but which should have remained consistent. When you're done, the only types that know about <code>DbContext</code> directly are your concrete Repository implementations.</p>
<p>Your application is growing more popular now, and some of the pages are really hammering the database. Their data doesn't change very often, so you decide to add some caching. Initially you start putting the caching logic directly in your data access code in your repository implementations that use EF Core, but you quickly find that there is a lot of duplication and your once-simple repositories are now growing cluttered with a lot of caching logic. What's more changing the details of what is cached how is requiring you to touch and re-touch the repository types again and again. Your current approach is obviously violating both the Single Responsibility and Open-Closed principles, two of the <a href="https://www.pluralsight.com/courses/principles-oo-design">SOLID principles</a>. You recognize that you can apply the Decorator (or Proxy) pattern by moving the caching logic into a CachedRepository type, which you can choose when and where to use on a per-entity basis simply by adjusting the type mapping in your application's <code>ConfigureServices</code> method. With this in place, you're able to quickly apply caching where appropriate, and ship a better performing version of your application.</p>
<p>Over time, as you built out your repositories, you kept basic methods for creating, reading, updating, and deleting entities in one place. Maybe you implemented a generic repository, or used a base class. You were careful not to expose <code>IQueryable</code> interfaces from your Repositories, so their query details didn't leak throughout your application. However, to support many different kinds of queries, with different filters and including different amounts of data from related types, you found that you needed to add many additional methods and overloads. In addition to a simple List method on your Order repository, you needed ListByCustomer, ListByProduct, ListByCompany, not to mention ListWithOrderDetails and other variations. Some of your repositories were growing quite large, and included quite a bit of complex query logic, which wasn't always easy to reuse even between methods in the same repository. To address this pain, you applied the Specification pattern, which treats each unique query as its own type. Using this approach, you were able to create specifications like OrdersByCustomer, OrdersByProduct, and OrdersByCompany which included the appropriate OrderDetails if desired, or included an option to specify whether to include it. Your Repository implementations dropped down to just simple CRUD methods, with the List method now taking in a Specification as a parameter.</p>
<p>Hopefully this helps you see how you can recognize a certain kind of pain, and respond to that pain by refactoring to use a specific design pattern. If you keep your code clean and simple, it's fairly easy to do this kind of refactoring as you need it, so there's no need to try and use every pattern you know speculatively as you begin a project.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://www.pluralsight.com/courses/patterns-library">Design Pattern Library</a></li>
<li><a href="https://www.pluralsight.com/courses/refactoring-fundamentals">Refactoring Fundamentals</a></li>
<li><a href="https://deviq.com/pain-driven-development/">Pain Driven Development</a></li>
<li><a href="https://www.pluralsight.com/courses/principles-oo-design">SOLID Principles</a></li>
</ul>
]]></description>
      <pubDate>Mon, 1 Oct 2018 06:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h1>Applying Pain Driven Development to Patterns</h1>
<p>This week we talk about specific ways you can apply my strategy of Pain Driven Development to the use of design patterns. This is an excerpt from my Design Pattern Mastery presentation that goes into more detail on design patterns.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>I talked about <a href="/010">Pain Driven Development, or PDD, in episode 10</a> - check out that episode first if you're not familiar with the practice. I've recently been focusing a bit on some design patterns. An easy trap to fall into with design patterns is trying to apply them too frequently or too soon. PDD suggests waiting to experience pain while trying to work with the application's current design before you attempt to <a href="https://www.pluralsight.com/courses/refactoring-fundamentals">refactor</a> to improve its design by applying a design pattern. In this tip, I'll walk through a few common steps where applying a specific pattern may be helpful.</p>
<p>To begin, let's assume we have a very simple web application. Let's say it's using MVC, and there's a controller that needs to be used to return some data fetched from a database. It could be an API endpoint or a view-based page - the UI format isn't important in this case. The absolute simplest thing you can do in this situation is hard code your data access code into your controller. So, assuming you're using ASP.NET Core and Entity Framework Core, you could instantiate an <code>DbContext</code> in the controller and use that to fetch the data. This works and meets the immediate requirement, so you ship this version.</p>
<p>A little bit later, your application has grown more complex. You have some filters that also use data, along with other services. You start to notice occasional bugs from EF and realize that you've introduced a bug. By instantiating a new <code>DbContext</code> in each controller, but occasionally passing around entities between parts of the application, EF gets in a state where entities are tracked by one instance but you're trying to operate on them with another instance of <code>DbContext</code>. You need to use a single EF Core <code>DbContext</code> per web request, which is to say it should have a &quot;Scoped&quot; lifetime. Fortunately, ASP.NET Core makes it very easy to achieve this by configuring your <code>DbContext</code> inside of <code>ConfigureServices</code>. In fact, if you don't read the docs, you probably don't even know what lifetime EF Core is using, because it's hidden within an extension method. In any case, once you configure <code>DbContext</code> in ConfigureServices, you need a way to get it into your Controller(s). To do this requires the <a href="/019">Strategy pattern, covered in episode 19</a>. If you're familiar with dependency injection, you've used the Strategy pattern. Add a constructor to your Controller, pass in the <code>DbContext</code>, and set a private local field with the value passed into the constructor. Do this anywhere you're otherwise newing up the <code>DbContext</code>. Remind yourself <a href="/005">'new is glue'</a>. You just fixed an issue with too tight of coupling to the instantiation process by using the service collection built into ASP.NET Core, an IOC container, essentially a factory on steroids. Your EF Core lifetime bug is now fixed, so you ship the code.</p>
<p>Some more time passes, the application has grown, and now there are a bunch of controllers and other places that all have <code>DbContext</code> injected into them. You've noticed some duplication in how code works with the <code>DbContext</code>. You've also found that it's tough to unit test your classes that have a real DbContext injected, except by configuring EF Core to use its In Memory data store. This works, but you'd prefer it if your unit tests truly had no dependencies so you could just test behavior, not low-level data access libraries. You decide that you can solve both of these problems by introducing the Repository pattern, which is just a fancy name for an abstraction used to encapsulate the low level details of your data access. You create a few such interfaces, implement them with <code>DbContext</code>, and make sure your Controllers and other classes that were directly using <code>DbContext</code> now have an interface injected instead. Along the way you fix a couple of bugs you discovered that had grown due to duplicate code that had evolved differently, but which should have remained consistent. When you're done, the only types that know about <code>DbContext</code> directly are your concrete Repository implementations.</p>
<p>Your application is growing more popular now, and some of the pages are really hammering the database. Their data doesn't change very often, so you decide to add some caching. Initially you start putting the caching logic directly in your data access code in your repository implementations that use EF Core, but you quickly find that there is a lot of duplication and your once-simple repositories are now growing cluttered with a lot of caching logic. What's more changing the details of what is cached how is requiring you to touch and re-touch the repository types again and again. Your current approach is obviously violating both the Single Responsibility and Open-Closed principles, two of the <a href="https://www.pluralsight.com/courses/principles-oo-design">SOLID principles</a>. You recognize that you can apply the Decorator (or Proxy) pattern by moving the caching logic into a CachedRepository type, which you can choose when and where to use on a per-entity basis simply by adjusting the type mapping in your application's <code>ConfigureServices</code> method. With this in place, you're able to quickly apply caching where appropriate, and ship a better performing version of your application.</p>
<p>Over time, as you built out your repositories, you kept basic methods for creating, reading, updating, and deleting entities in one place. Maybe you implemented a generic repository, or used a base class. You were careful not to expose <code>IQueryable</code> interfaces from your Repositories, so their query details didn't leak throughout your application. However, to support many different kinds of queries, with different filters and including different amounts of data from related types, you found that you needed to add many additional methods and overloads. In addition to a simple List method on your Order repository, you needed ListByCustomer, ListByProduct, ListByCompany, not to mention ListWithOrderDetails and other variations. Some of your repositories were growing quite large, and included quite a bit of complex query logic, which wasn't always easy to reuse even between methods in the same repository. To address this pain, you applied the Specification pattern, which treats each unique query as its own type. Using this approach, you were able to create specifications like OrdersByCustomer, OrdersByProduct, and OrdersByCompany which included the appropriate OrderDetails if desired, or included an option to specify whether to include it. Your Repository implementations dropped down to just simple CRUD methods, with the List method now taking in a Specification as a parameter.</p>
<p>Hopefully this helps you see how you can recognize a certain kind of pain, and respond to that pain by refactoring to use a specific design pattern. If you keep your code clean and simple, it's fairly easy to do this kind of refactoring as you need it, so there's no need to try and use every pattern you know speculatively as you begin a project.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://www.pluralsight.com/courses/patterns-library">Design Pattern Library</a></li>
<li><a href="https://www.pluralsight.com/courses/refactoring-fundamentals">Refactoring Fundamentals</a></li>
<li><a href="https://deviq.com/pain-driven-development/">Pain Driven Development</a></li>
<li><a href="https://www.pluralsight.com/courses/principles-oo-design">SOLID Principles</a></li>
</ul>
]]></content:encoded>
      <enclosure length="5138134" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/d082f095-5775-4734-9b42-d288f4ae064a/69b83f35_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Applying Pain Driven Development to Patterns</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/d082f095-5775-4734-9b42-d288f4ae064a/3000x3000/1538356914artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:08:40</itunes:duration>
      <itunes:summary>This week we talk about specific ways you can apply my strategy of Pain Driven Development to the use of design patterns. This is an excerpt from my Design Pattern Mastery presentation that goes into more detail on design patterns.</itunes:summary>
      <itunes:subtitle>This week we talk about specific ways you can apply my strategy of Pain Driven Development to the use of design patterns. This is an excerpt from my Design Pattern Mastery presentation that goes into more detail on design patterns.</itunes:subtitle>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>28</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">a9e13ec4-6722-4e20-a4a9-3121e6c33637</guid>
      <title>How Do You Even Know This Crap?</title>
      <description><![CDATA[<h1>How Do You Even Know This Crap?</h1>
<p>This week we have a special guest offering a dev tip - please welcome Scott Hanselman who blogs at Hanselman.com and has a great long-running podcast, Hanselminutes. Scott's going to share with us some tips on how you can leverage your experience to know when a problem you're facing <em>should</em> already have a solution somewhere. Here's Scott.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>You can view Scott's article on this topic called <a href="https://www.hanselman.com/blog/HowDoYouEvenKnowThisCrap.aspx">How Do You Even Know This Crap</a> on his site.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://www.hanselman.com/blog/HowDoYouEvenKnowThisCrap.aspx">How Do You Even Know This Crap</a></li>
<li><a href="https://www.hanselman.com/">Scott's Blog</a></li>
<li><a href="https://www.hanselminutes.com/">Hanselminutes Podcast</a></li>
</ul>
]]></description>
      <pubDate>Mon, 10 Sep 2018 06:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h1>How Do You Even Know This Crap?</h1>
<p>This week we have a special guest offering a dev tip - please welcome Scott Hanselman who blogs at Hanselman.com and has a great long-running podcast, Hanselminutes. Scott's going to share with us some tips on how you can leverage your experience to know when a problem you're facing <em>should</em> already have a solution somewhere. Here's Scott.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>You can view Scott's article on this topic called <a href="https://www.hanselman.com/blog/HowDoYouEvenKnowThisCrap.aspx">How Do You Even Know This Crap</a> on his site.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://www.hanselman.com/blog/HowDoYouEvenKnowThisCrap.aspx">How Do You Even Know This Crap</a></li>
<li><a href="https://www.hanselman.com/">Scott's Blog</a></li>
<li><a href="https://www.hanselminutes.com/">Hanselminutes Podcast</a></li>
</ul>
]]></content:encoded>
      <enclosure length="3826271" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/89671373-8f0d-4622-8c09-f024caaf5935/1e0e7193_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>How Do You Even Know This Crap?</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/89671373-8f0d-4622-8c09-f024caaf5935/3000x3000/1536597143artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:05:37</itunes:duration>
      <itunes:summary>This week we have a special guest offering a dev tip - please welcome Scott Hanselman who blogs at Hanselman.com and has a great long-running podcast, Hanselminutes. Scott&apos;s going to share with us some tips on how you can leverage your experience to know when a problem you&apos;re facing _should_ already have a solution somewhere. </itunes:summary>
      <itunes:subtitle>This week we have a special guest offering a dev tip - please welcome Scott Hanselman who blogs at Hanselman.com and has a great long-running podcast, Hanselminutes. Scott&apos;s going to share with us some tips on how you can leverage your experience to know when a problem you&apos;re facing _should_ already have a solution somewhere. </itunes:subtitle>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>27</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">bc49aac9-da52-4134-8c0f-d8651d6d7849</guid>
      <title>Layering Patterns on Repositories</title>
      <description><![CDATA[<h1>Layering Patterns on Repositories</h1>
<p>This week we're sticking to the patterns and repositories theme. I started down the design patterns path with <a href="/017">Episode 17</a> so start at least from there if you want to listen to the sequence more-or-less in order. In this episode, we'll look at some combinations with other patterns that make using the Repository pattern even more attractive.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>Last week I mentioned how the Repository pattern works well with the Strategy pattern, so that you can use dependency injection with it. This is the first of many ways in which you can combine Repository with other patterns, and is probably the most powerful of them all (though probably taken for granted by many). I described the strategy pattern in <a href="/019">episode 19</a>. Let's look at two other patterns now that we can combine with Repository.</p>
<p>First, let's talk about a common pain point with repositories: custom queries. I talked about the need to encapsulate query logic so it doesn't leak out of your repository in <a href="/018">episode 18</a>. However, I saved a powerful technique for doing so until this tip. (Sorry, there's only so much I can put into each of these and keep them short.) If you follow my earlier advice and you don't leak query logic outside of your repositories, it's likely your repository implementations have a bunch of custom query methods. Maybe you have standard GetById and List methods, but then you also have ListByState, ListByModel, ListByOwner, etc. Maybe you have methods that correlate directly to business use cases or even UI concerns, like ListPremiumCustomers or ListForSearchScreen. The point is, you may find yourself with the code smell of too many one-off custom query methods on your repositories. This is pretty common, and the worse it gets the more cumbsersome it becomes to work with the repositories.</p>
<p>The solution to this problem is to introduce another pattern. The <a href="https://deviq.com/specification-pattern/">Specification pattern</a> is designed to encapsulate a query within an object. I mentioned it briefly in <a href="/024">episode 24</a>. It's especially useful when you're using an ORM tool like EF or EF Core because not only can you encapsulate filter expressions, but you can also specify which properties to eager load. Thus, you can create a specification for a shopping basket type that might be called <code>BasketWithItemsByCustomerId</code> or something similar. A typical specification I use will include the filter expression (to be used with a Where LINQ expression) and will let me specify which properties and subproperties I want the query to return with it.</p>
<p>What are the benefits of using this pattern? First, you eliminate duplication of query logic if you were previously letting client code create queries on the fly. Second, you establish a library of known queries that your development team can review, reuse, and discuss. These should be organized so they're extremely discoverable so there's minimal need to try and reinvent the wheel when someone needs a particular query that already exists. They also help clean up your repositories, eliminating most of the scenarios where you would need non-generic repository methods, and thus dramatically reducing how many repository implementations you need to write and maintain. Your repository code will better follow the Single Responsibility Principle and the Open/Closed Principle, and you won't need a bunch of custom IWhateverRepository interfaces. Finally, you can easily unit test your specifications' filter logic to ensure it's correct and provide examples for the team.</p>
<p>Another useful pattern you can use with repository is the proxy or decorator pattern to add caching. I call this the <a href="https://ardalis.com/building-a-cachedrepository-in-aspnet-core">CachedRepository pattern</a> and I've written a number of articles about it. I mention both patterns because they're functionally the same, but differ based on intent. A proxy controls access to something. A decorator adds behavior to something. A CachedRepository controls access to the real, underlying repository, exposing it only when the result isn't in the cache. In this way, it's a proxy. But it also is responsible for adding caching behavior to any repository. In this way, it's a decorator. Either way, it's an extremely useful pattern.</p>
<p>Most applications make a lot of queries to their database for results that don't change frequently. A lot of applications use a database to define some or all of their navigation, or the contents of common dropdownlists on forms. These and other common results are great candidates for caching, but often this behavior isn't added because of the work and complexity involved. Adding caching to a method in a data access repository isn't ideal, since it couples two unrelated concerns and breaks the single responsibility principle. It's also not very reusable. A better approach is to create a generic <code>CachedRepository</code> that can be used for any type that would benefit from caching. Determining whether or not to use this caching functionality can be controlled centrally for the application wherever its services are configured.</p>
<p>Circling back around to the specification pattern, you can combine it with the CachedRepository to help with key generation. Every cache entry needs to have a unique key, and you need to take care when constructing keys that you take into account any variables or parameters that were used for a particular query. Your specification objects know exactly which parameters they require, and can easily expose a cache key property that can be used by your CachedRepository. You can also add a property to toggle whether certain specifications should be cached at all, if that's helpful.</p>
<p>If you'd like to see what this looks like in a simple sample application, check out the <a href="https://github.com/dotnet-architecture/eShopOnWeb">eShopOnWeb</a> sample on GitHub. I have a link in the show notes. There's also a free 110-page eBook that goes along with the sample that I encourage you to check out. I developed both the book and the sample for Microsoft as a free resource and they're both up-to-date with .NET Core 2.1 as of July 2018.</p>
<p><em>Do you think your team or application could be improved by better use of design patterns? I offer remote and onsite workshops guaranteed to improve your coding skills and application code quality. Contact me at <a href="https://ardalis.com/contact-us">ardalis.com</a> and let's see how I can help.</em></p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://deviq.com/repository-pattern/">Repository Pattern</a></li>
<li><a href="https://deviq.com/solid/">SOLID Principles</a></li>
<li><a href="https://deviq.com/specification-pattern/">Specification Pattern</a></li>
<li><a href="https://ardalis.com/building-a-cachedrepository-in-aspnet-core">Building a CachedRepository in ASP.NET Core</a></li>
<li><a href="https://ardalis.com/introducing-the-cachedrepository-pattern">Introducing the CachedRepository Pattern</a></li>
<li><a href="https://ardalis.com/building-a-cachedrepository-via-strategy-pattern">Building a CachedRepository via Strategy Pattern</a></li>
</ul>
]]></description>
      <pubDate>Mon, 27 Aug 2018 06:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h1>Layering Patterns on Repositories</h1>
<p>This week we're sticking to the patterns and repositories theme. I started down the design patterns path with <a href="/017">Episode 17</a> so start at least from there if you want to listen to the sequence more-or-less in order. In this episode, we'll look at some combinations with other patterns that make using the Repository pattern even more attractive.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>Last week I mentioned how the Repository pattern works well with the Strategy pattern, so that you can use dependency injection with it. This is the first of many ways in which you can combine Repository with other patterns, and is probably the most powerful of them all (though probably taken for granted by many). I described the strategy pattern in <a href="/019">episode 19</a>. Let's look at two other patterns now that we can combine with Repository.</p>
<p>First, let's talk about a common pain point with repositories: custom queries. I talked about the need to encapsulate query logic so it doesn't leak out of your repository in <a href="/018">episode 18</a>. However, I saved a powerful technique for doing so until this tip. (Sorry, there's only so much I can put into each of these and keep them short.) If you follow my earlier advice and you don't leak query logic outside of your repositories, it's likely your repository implementations have a bunch of custom query methods. Maybe you have standard GetById and List methods, but then you also have ListByState, ListByModel, ListByOwner, etc. Maybe you have methods that correlate directly to business use cases or even UI concerns, like ListPremiumCustomers or ListForSearchScreen. The point is, you may find yourself with the code smell of too many one-off custom query methods on your repositories. This is pretty common, and the worse it gets the more cumbsersome it becomes to work with the repositories.</p>
<p>The solution to this problem is to introduce another pattern. The <a href="https://deviq.com/specification-pattern/">Specification pattern</a> is designed to encapsulate a query within an object. I mentioned it briefly in <a href="/024">episode 24</a>. It's especially useful when you're using an ORM tool like EF or EF Core because not only can you encapsulate filter expressions, but you can also specify which properties to eager load. Thus, you can create a specification for a shopping basket type that might be called <code>BasketWithItemsByCustomerId</code> or something similar. A typical specification I use will include the filter expression (to be used with a Where LINQ expression) and will let me specify which properties and subproperties I want the query to return with it.</p>
<p>What are the benefits of using this pattern? First, you eliminate duplication of query logic if you were previously letting client code create queries on the fly. Second, you establish a library of known queries that your development team can review, reuse, and discuss. These should be organized so they're extremely discoverable so there's minimal need to try and reinvent the wheel when someone needs a particular query that already exists. They also help clean up your repositories, eliminating most of the scenarios where you would need non-generic repository methods, and thus dramatically reducing how many repository implementations you need to write and maintain. Your repository code will better follow the Single Responsibility Principle and the Open/Closed Principle, and you won't need a bunch of custom IWhateverRepository interfaces. Finally, you can easily unit test your specifications' filter logic to ensure it's correct and provide examples for the team.</p>
<p>Another useful pattern you can use with repository is the proxy or decorator pattern to add caching. I call this the <a href="https://ardalis.com/building-a-cachedrepository-in-aspnet-core">CachedRepository pattern</a> and I've written a number of articles about it. I mention both patterns because they're functionally the same, but differ based on intent. A proxy controls access to something. A decorator adds behavior to something. A CachedRepository controls access to the real, underlying repository, exposing it only when the result isn't in the cache. In this way, it's a proxy. But it also is responsible for adding caching behavior to any repository. In this way, it's a decorator. Either way, it's an extremely useful pattern.</p>
<p>Most applications make a lot of queries to their database for results that don't change frequently. A lot of applications use a database to define some or all of their navigation, or the contents of common dropdownlists on forms. These and other common results are great candidates for caching, but often this behavior isn't added because of the work and complexity involved. Adding caching to a method in a data access repository isn't ideal, since it couples two unrelated concerns and breaks the single responsibility principle. It's also not very reusable. A better approach is to create a generic <code>CachedRepository</code> that can be used for any type that would benefit from caching. Determining whether or not to use this caching functionality can be controlled centrally for the application wherever its services are configured.</p>
<p>Circling back around to the specification pattern, you can combine it with the CachedRepository to help with key generation. Every cache entry needs to have a unique key, and you need to take care when constructing keys that you take into account any variables or parameters that were used for a particular query. Your specification objects know exactly which parameters they require, and can easily expose a cache key property that can be used by your CachedRepository. You can also add a property to toggle whether certain specifications should be cached at all, if that's helpful.</p>
<p>If you'd like to see what this looks like in a simple sample application, check out the <a href="https://github.com/dotnet-architecture/eShopOnWeb">eShopOnWeb</a> sample on GitHub. I have a link in the show notes. There's also a free 110-page eBook that goes along with the sample that I encourage you to check out. I developed both the book and the sample for Microsoft as a free resource and they're both up-to-date with .NET Core 2.1 as of July 2018.</p>
<p><em>Do you think your team or application could be improved by better use of design patterns? I offer remote and onsite workshops guaranteed to improve your coding skills and application code quality. Contact me at <a href="https://ardalis.com/contact-us">ardalis.com</a> and let's see how I can help.</em></p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://deviq.com/repository-pattern/">Repository Pattern</a></li>
<li><a href="https://deviq.com/solid/">SOLID Principles</a></li>
<li><a href="https://deviq.com/specification-pattern/">Specification Pattern</a></li>
<li><a href="https://ardalis.com/building-a-cachedrepository-in-aspnet-core">Building a CachedRepository in ASP.NET Core</a></li>
<li><a href="https://ardalis.com/introducing-the-cachedrepository-pattern">Introducing the CachedRepository Pattern</a></li>
<li><a href="https://ardalis.com/building-a-cachedrepository-via-strategy-pattern">Building a CachedRepository via Strategy Pattern</a></li>
</ul>
]]></content:encoded>
      <enclosure length="4710644" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/05d54fcf-c03c-41f7-bc1a-dde54a858bad/a01f142d_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Layering Patterns on Repositories</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/05d54fcf-c03c-41f7-bc1a-dde54a858bad/3000x3000/1535337267artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:07:28</itunes:duration>
      <itunes:summary>This week we&apos;re sticking to the patterns and repositories theme. I started down the design patterns path with [Episode 17](/017) so start at least from there if you want to listen to the sequence more-or-less in order. In this episode, we&apos;ll look at some combinations with other patterns that make using the Repository pattern even more attractive.</itunes:summary>
      <itunes:subtitle>This week we&apos;re sticking to the patterns and repositories theme. I started down the design patterns path with [Episode 17](/017) so start at least from there if you want to listen to the sequence more-or-less in order. In this episode, we&apos;ll look at some combinations with other patterns that make using the Repository pattern even more attractive.</itunes:subtitle>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>26</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">d51a5635-b1e7-4383-a950-22a746838edd</guid>
      <title>What Good is a Repository</title>
      <description><![CDATA[<h1>What good is a repository?</h1>
<p>This week I'm following up on last week's tip about the Repository pattern. A listener pointed out to me that I never directly answered the question posed in the last episode of &quot;Do I need a repository?&quot; I'll be sure to do so here.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p><a href="/024">Last episode</a> I addressed a fairly common online argument against the use of repositories. I suggest you listen to that episode and then jump back into this one, but hey, you do what you want. I addressed the usual arguments against using a repository by using a particular article as an example, but I want to be clear that that article was by no means the direct cause of my response. In fact, I hadn't even seen that particular article until I sat down to record the episode and it happened to be pretty high up in my search results and made a good example of the kinds of arguments folks like to throw out when arguing against the pattern. So, now that we've heard and perhaps refuted some of the arguments against using the repository pattern, let's talk about why you might use it.</p>
<p>What good is a Repository in your application?</p>
<p>The <a href="https://deviq.com/repository-pattern/">Repository pattern</a> is simply an abstraction of your persistence strategy for your application. In fact, the repository pattern is most frequently used along with the strategy design pattern as a way to pull low level knowledge of persistence details out of your application's other classes. I've heard the repository pattern also described as an example of the facade design pattern, since it hides away much of the detail of this or that persistence technology and exposes a much simpler interface for getting and storing entities. I can get behind that definition, too. You can think of the repository pattern as essentially a particular use case of the facade pattern in which the complex underlying implementation is related to persistence. There's one more pattern we can consider in relation to the repository, though, and that's the adapter. The main difference between a facade and an adapter is in the intent. A facade's intent is to simplify, while an adapter's intent is to allow multiple implementations to be accessed through a common interface. A repository typically does both of these things, providing a simple interface that hides unneeded complexity and allows multiple implementations, like relational, non-relational, in-memory, or even file- or API-based approaches. So, the repository pattern is all about providing an intention-revealing name to a facade or adapter that can be used as a strategy to reduce coupling in your application. Let's drill into these other patterns a little more.</p>
<p>The strategy pattern lets you change how a class does something without having to change the class itself. If you're familiar with <a href="https://deviq.com/dependency-injection/">dependency injection</a>, you already know this pattern. It works by passing in as a parameter a particular implementation to be used, allowing this implementation to vary without the class that uses it having to change. It's one of the most powerful design patterns for writing loosely-coupled code that follows the <a href="https://deviq.com/solid/">SOLID principles</a>. It's very challenging to write unit-testable code in strongly typed languages without using this pattern.</p>
<p>The facade pattern is helpful when you want to make a complex API easier to use. This might be because the complexity is unnecessary, or because there are certain &quot;right ways&quot; to do things in your particular application and you want to make it easier for your team to follow the right path and avoid the wrong ones. Creating a facade to expose simple persistence operations like creating, updating, and deleting records, as well as some mechanism for fetching and querying, is a pretty common technique and can allow teams to focus on business logic moreso than data access logic in many cases. That said, keep in mind that the facade can hide useful features and sometimes necessary complexity that client software should otherwise be able to access. Care must be taken in how the facade is designed to ensure it doesn't cripple the use of the libraries it wraps.</p>
<p>The adapter pattern is helpful for testing, since it allows tests to easily substitute in implementations that behave however the particular test requires. Using adapters can also allow an application to work more flexibly with different actual providers, plugging in the appropriate one as necessary.</p>
<p>You can see that the Repository pattern is really a particular implementation of one or more other, more generic patterns. Next week I'll talk a little bit more about the pattern, and how it can be further extended by layering additional patterns on top of it. Let's wrap up this episode by answering an important question.</p>
<h2>Do I need a repository?</h2>
<p>No, you don't <strong>need</strong> a repository. However, if any of the benefits I've described in the last two episodes sounds like something you might want in your application, you might consider it. If you want unit testability, an abstraction over data access will save you a lot of pain. If you want flexible, modular code, the same is true. If you want low-level access to all the features of your data access technology everywhere you use it, then you might not want an abstraction over it. If your application isn't set up to make use of dependency injection, it may not be worthwhile, since newing up repositories everywhere you need them will still tightly couple you to implementation details.</p>
<p><em>Do you think your team or application could be improved by better use of design patterns? I offer remote and onsite workshops guaranteed to improve your coding skills and application code quality. Contact me at <a href="https://ardalis.com/contact-us">ardalis.com</a> and let's see how I can help.</em></p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://deviq.com/repository-pattern/">Repository Pattern</a></li>
<li><a href="https://deviq.com/solid/">SOLID Principles</a></li>
<li><a href="https://ardalis.com/new-is-glue">New is Glue</a> (why you don't want to new up repositories everywhere - seel also <a href="https://www.weeklydevtips.com/005">Ep 5</a>)</li>
</ul>
]]></description>
      <pubDate>Mon, 2 Jul 2018 06:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h1>What good is a repository?</h1>
<p>This week I'm following up on last week's tip about the Repository pattern. A listener pointed out to me that I never directly answered the question posed in the last episode of &quot;Do I need a repository?&quot; I'll be sure to do so here.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p><a href="/024">Last episode</a> I addressed a fairly common online argument against the use of repositories. I suggest you listen to that episode and then jump back into this one, but hey, you do what you want. I addressed the usual arguments against using a repository by using a particular article as an example, but I want to be clear that that article was by no means the direct cause of my response. In fact, I hadn't even seen that particular article until I sat down to record the episode and it happened to be pretty high up in my search results and made a good example of the kinds of arguments folks like to throw out when arguing against the pattern. So, now that we've heard and perhaps refuted some of the arguments against using the repository pattern, let's talk about why you might use it.</p>
<p>What good is a Repository in your application?</p>
<p>The <a href="https://deviq.com/repository-pattern/">Repository pattern</a> is simply an abstraction of your persistence strategy for your application. In fact, the repository pattern is most frequently used along with the strategy design pattern as a way to pull low level knowledge of persistence details out of your application's other classes. I've heard the repository pattern also described as an example of the facade design pattern, since it hides away much of the detail of this or that persistence technology and exposes a much simpler interface for getting and storing entities. I can get behind that definition, too. You can think of the repository pattern as essentially a particular use case of the facade pattern in which the complex underlying implementation is related to persistence. There's one more pattern we can consider in relation to the repository, though, and that's the adapter. The main difference between a facade and an adapter is in the intent. A facade's intent is to simplify, while an adapter's intent is to allow multiple implementations to be accessed through a common interface. A repository typically does both of these things, providing a simple interface that hides unneeded complexity and allows multiple implementations, like relational, non-relational, in-memory, or even file- or API-based approaches. So, the repository pattern is all about providing an intention-revealing name to a facade or adapter that can be used as a strategy to reduce coupling in your application. Let's drill into these other patterns a little more.</p>
<p>The strategy pattern lets you change how a class does something without having to change the class itself. If you're familiar with <a href="https://deviq.com/dependency-injection/">dependency injection</a>, you already know this pattern. It works by passing in as a parameter a particular implementation to be used, allowing this implementation to vary without the class that uses it having to change. It's one of the most powerful design patterns for writing loosely-coupled code that follows the <a href="https://deviq.com/solid/">SOLID principles</a>. It's very challenging to write unit-testable code in strongly typed languages without using this pattern.</p>
<p>The facade pattern is helpful when you want to make a complex API easier to use. This might be because the complexity is unnecessary, or because there are certain &quot;right ways&quot; to do things in your particular application and you want to make it easier for your team to follow the right path and avoid the wrong ones. Creating a facade to expose simple persistence operations like creating, updating, and deleting records, as well as some mechanism for fetching and querying, is a pretty common technique and can allow teams to focus on business logic moreso than data access logic in many cases. That said, keep in mind that the facade can hide useful features and sometimes necessary complexity that client software should otherwise be able to access. Care must be taken in how the facade is designed to ensure it doesn't cripple the use of the libraries it wraps.</p>
<p>The adapter pattern is helpful for testing, since it allows tests to easily substitute in implementations that behave however the particular test requires. Using adapters can also allow an application to work more flexibly with different actual providers, plugging in the appropriate one as necessary.</p>
<p>You can see that the Repository pattern is really a particular implementation of one or more other, more generic patterns. Next week I'll talk a little bit more about the pattern, and how it can be further extended by layering additional patterns on top of it. Let's wrap up this episode by answering an important question.</p>
<h2>Do I need a repository?</h2>
<p>No, you don't <strong>need</strong> a repository. However, if any of the benefits I've described in the last two episodes sounds like something you might want in your application, you might consider it. If you want unit testability, an abstraction over data access will save you a lot of pain. If you want flexible, modular code, the same is true. If you want low-level access to all the features of your data access technology everywhere you use it, then you might not want an abstraction over it. If your application isn't set up to make use of dependency injection, it may not be worthwhile, since newing up repositories everywhere you need them will still tightly couple you to implementation details.</p>
<p><em>Do you think your team or application could be improved by better use of design patterns? I offer remote and onsite workshops guaranteed to improve your coding skills and application code quality. Contact me at <a href="https://ardalis.com/contact-us">ardalis.com</a> and let's see how I can help.</em></p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://deviq.com/repository-pattern/">Repository Pattern</a></li>
<li><a href="https://deviq.com/solid/">SOLID Principles</a></li>
<li><a href="https://ardalis.com/new-is-glue">New is Glue</a> (why you don't want to new up repositories everywhere - seel also <a href="https://www.weeklydevtips.com/005">Ep 5</a>)</li>
</ul>
]]></content:encoded>
      <enclosure length="4156144" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/0bd7fa37-a06c-4f8a-8d87-2b89ad101632/8443d4f2_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>What Good is a Repository</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/0bd7fa37-a06c-4f8a-8d87-2b89ad101632/3000x3000/1530060179artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:06:33</itunes:duration>
      <itunes:summary>This week I&apos;m following up on last week&apos;s tip about the Repository pattern. A listener pointed out to me that I never directly answered the question posed in the last episode of &quot;Do I need a repository?&quot; I&apos;ll be sure to do so here.</itunes:summary>
      <itunes:subtitle>This week I&apos;m following up on last week&apos;s tip about the Repository pattern. A listener pointed out to me that I never directly answered the question posed in the last episode of &quot;Do I need a repository?&quot; I&apos;ll be sure to do so here.</itunes:subtitle>
      <itunes:keywords>software development, design patterns, repository</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>25</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">96972cf2-94d6-427c-ad98-6bd447b88ccf</guid>
      <title>Do I Need a Repository?</title>
      <description><![CDATA[<h1>Do I Need a Repository?</h1>
<p>This week we'll answer this extremely common question about the Repository pattern, and when you should think about using it.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>This week we're going to return to the Repository design pattern to answer a very common question: when should you use it? This question appears very frequently in discussions about Entity Framework or EF Core, usually with someone saying &quot;Since EF already acts like a repository, why would you create your own repository pattern on top of it?&quot;</p>
<p>Before we get into the answer to this question, though, let me point out that if you're interested in the repository pattern in general I have a link to a very useful EF Core implementation in the show notes for this episode that should help get you started or perhaps give you some ideas you can use with your existing implementation. Also, just a reminder that we talked about the pattern in <a href="/018">episode 18 on query logic encapsulation</a>, but otherwise I haven't spent a lot of time on repository tips here, yet.</p>
<p>Ok, so on to this week's topic. Should you bother using the repository pattern when you're working with EF or EF Core, since these already act like a repository? If you Google for this, you're likely to discover <a href="https://www.thereformedprogrammer.net/is-the-repository-pattern-useful-with-entity-framework-core/">an article discussing this topic that suggests repository isn't useful</a>. In setting the scene, the author discusses an app he inherited that had performance issues caused by lazy loading, which he says &quot;was needed because the application used the repository/unit of work pattern.&quot;</p>
<p>Before going further, let's point out two things. One, <a href="https://ardalis.com/avoid-lazy-loading-entities-in-asp-net-applications">lazy loading in web applications is evil</a>. Just don't do it except maybe for internal apps that have very few users and very small data sets. Read my article on why, linked from the show notes. Second, no, you don't need lazy loading if you're using repository. You just need to know how to pass query and loading information into the repository.</p>
<p>The author later goes on to say &quot;one of the ideas behind repository is that you might replace EF Core with another database access library but my view it's a misconception because a) it's very hard to replace a database access library, and b) are you really going to?&quot; I agree that it's very hard to replace your data access library, <strong>unless you put it behind a good abstraction.</strong> As to whether you're going to, that's a tougher one to answer. I've personally seen organizations change data access between raw ADO.NET, Enterprise Application Block, Typed Datasets, LINQ-to-SQL, LLBLGen, NHibernate, EF, and EF Core. I've probably forgotten a couple. Oh yeah, and Dapper and other &quot;micro-ORMs&quot;, too. If you're using an abstraction layer, you can swap out these implementation details quickly and easily. You just <a href="/015">write a new class</a> that is essentially an adapter of your repository to that particular tool. If you're hardcoded to any one of them, it's going to be a much bigger job (and so, yeah, you're less likely to do it because of the pain involved.)</p>
<p>Next, the author lists some of the bad parts of using repository. First, sorting and filtering, because a particular implementation he found from 2013 only returned an IEnumerable and didn't provide a way to allow filtering and sorting to be done in the database. Yes, poor implementations of a pattern can result in poor performance. Don't do that if performance is important. Next, he hits on lazy loading again. Ironically, at the time this article was published, EF Core didn't even support lazy loading, so this couldn't be a problem with it. Unfortunately, now it does, but as I mentioned, you shouldn't use it in web apps anyway. It has nothing to do with repository, despite the author thinking they're linked somehow. His third perf-related issue is with updates, claiming that a repository around EF Core would require saving every property, not just those that have changed. This is also untrue. You can use EF Core's change tracking capability with and through a repository just fine.</p>
<p>His fourth and final &quot;bad part&quot; of repositories when used with EF Core is that they're too generic. You can write one generic repository and then use that or subtype from it. He notes that it should minimize the code you need to write, but in his experience as things grow in complexity you end up writing more and more code in the individual repositories. Having less code to write and maintain really is a good thing. The issue with complexity resulting in more and more code in repositories is a symptom of not using another pattern, the specification. In fact, the <a href="https://deviq.com/specification-pattern/">specification pattern</a> addresses pretty much all of the issues described in his post that I haven't already debunked. The author knows about this pattern, which he describes as 'query objects', but doesn't see how they can be used together with repositories just as effectively as he uses them <em>instead of</em> repositories.</p>
<p>One last thing I want to point out that many folks (including the author of this article) misunderstand is the idea of being able to unit test code that works with data. This might just come down to the definition of a unit test, so I'll start with that. A unit test is a test that only tests your code at the unit level. That typically means a single method, or at most a class since to access a single method you may need to create an instance of a class and thus also execute its constructor, etc. <a href="https://ardalis.com/unit-test-or-integration-test-and-why-you-should-care">If you have a test that tests more than one class working together, or that depends on code that isn't yours (like, say, an ORM), it's not a unit test. It's an integration test.</a></p>
<p>The author goes on to suggest that since EF Core supports an in-memory database, you can use that for unit-testing your application. You can't. You can use it for integration testing, which is great. But it's not unit testing. The distinction is important because clean code should be unit testable. If it isn't, it's a code smell, suggesting that you may have too much coupling. You might be OK with that, but you should at least be aware of the issue so you can decide for yourself whether you're OK with it, rather than having a false sense of complacency because your integration tests work well enough.</p>
<p><em>Would your team or application benefit from an application assessment, highlighting potential problem areas and identifying a path toward better maintainability? Contact me at <a href="https://ardalis.com/contact-us">ardalis.com</a> and let's see how I can help.</em></p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://deviq.com/repository-pattern/">Repository Pattern</a></li>
<li><a href="https://www.thereformedprogrammer.net/is-the-repository-pattern-useful-with-entity-framework-core/">Is the repository pattern useful with EF Core?</a></li>
<li><a href="https://ardalis.com/avoid-lazy-loading-entities-in-asp-net-applications">Avoid Lazy Loading Entities in ASP.NET Applications</a></li>
<li><a href="https://deviq.com/specification-pattern/">Specification Pattern</a></li>
<li><a href="https://ardalis.com/unit-test-or-integration-test-and-why-you-should-care">Unit Test or Integration Test (and why you should care)</a></li>
<li><a href="https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-2.1">Integration Tests in ASP.NET Core</a></li>
</ul>
]]></description>
      <pubDate>Mon, 11 Jun 2018 06:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h1>Do I Need a Repository?</h1>
<p>This week we'll answer this extremely common question about the Repository pattern, and when you should think about using it.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>This week we're going to return to the Repository design pattern to answer a very common question: when should you use it? This question appears very frequently in discussions about Entity Framework or EF Core, usually with someone saying &quot;Since EF already acts like a repository, why would you create your own repository pattern on top of it?&quot;</p>
<p>Before we get into the answer to this question, though, let me point out that if you're interested in the repository pattern in general I have a link to a very useful EF Core implementation in the show notes for this episode that should help get you started or perhaps give you some ideas you can use with your existing implementation. Also, just a reminder that we talked about the pattern in <a href="/018">episode 18 on query logic encapsulation</a>, but otherwise I haven't spent a lot of time on repository tips here, yet.</p>
<p>Ok, so on to this week's topic. Should you bother using the repository pattern when you're working with EF or EF Core, since these already act like a repository? If you Google for this, you're likely to discover <a href="https://www.thereformedprogrammer.net/is-the-repository-pattern-useful-with-entity-framework-core/">an article discussing this topic that suggests repository isn't useful</a>. In setting the scene, the author discusses an app he inherited that had performance issues caused by lazy loading, which he says &quot;was needed because the application used the repository/unit of work pattern.&quot;</p>
<p>Before going further, let's point out two things. One, <a href="https://ardalis.com/avoid-lazy-loading-entities-in-asp-net-applications">lazy loading in web applications is evil</a>. Just don't do it except maybe for internal apps that have very few users and very small data sets. Read my article on why, linked from the show notes. Second, no, you don't need lazy loading if you're using repository. You just need to know how to pass query and loading information into the repository.</p>
<p>The author later goes on to say &quot;one of the ideas behind repository is that you might replace EF Core with another database access library but my view it's a misconception because a) it's very hard to replace a database access library, and b) are you really going to?&quot; I agree that it's very hard to replace your data access library, <strong>unless you put it behind a good abstraction.</strong> As to whether you're going to, that's a tougher one to answer. I've personally seen organizations change data access between raw ADO.NET, Enterprise Application Block, Typed Datasets, LINQ-to-SQL, LLBLGen, NHibernate, EF, and EF Core. I've probably forgotten a couple. Oh yeah, and Dapper and other &quot;micro-ORMs&quot;, too. If you're using an abstraction layer, you can swap out these implementation details quickly and easily. You just <a href="/015">write a new class</a> that is essentially an adapter of your repository to that particular tool. If you're hardcoded to any one of them, it's going to be a much bigger job (and so, yeah, you're less likely to do it because of the pain involved.)</p>
<p>Next, the author lists some of the bad parts of using repository. First, sorting and filtering, because a particular implementation he found from 2013 only returned an IEnumerable and didn't provide a way to allow filtering and sorting to be done in the database. Yes, poor implementations of a pattern can result in poor performance. Don't do that if performance is important. Next, he hits on lazy loading again. Ironically, at the time this article was published, EF Core didn't even support lazy loading, so this couldn't be a problem with it. Unfortunately, now it does, but as I mentioned, you shouldn't use it in web apps anyway. It has nothing to do with repository, despite the author thinking they're linked somehow. His third perf-related issue is with updates, claiming that a repository around EF Core would require saving every property, not just those that have changed. This is also untrue. You can use EF Core's change tracking capability with and through a repository just fine.</p>
<p>His fourth and final &quot;bad part&quot; of repositories when used with EF Core is that they're too generic. You can write one generic repository and then use that or subtype from it. He notes that it should minimize the code you need to write, but in his experience as things grow in complexity you end up writing more and more code in the individual repositories. Having less code to write and maintain really is a good thing. The issue with complexity resulting in more and more code in repositories is a symptom of not using another pattern, the specification. In fact, the <a href="https://deviq.com/specification-pattern/">specification pattern</a> addresses pretty much all of the issues described in his post that I haven't already debunked. The author knows about this pattern, which he describes as 'query objects', but doesn't see how they can be used together with repositories just as effectively as he uses them <em>instead of</em> repositories.</p>
<p>One last thing I want to point out that many folks (including the author of this article) misunderstand is the idea of being able to unit test code that works with data. This might just come down to the definition of a unit test, so I'll start with that. A unit test is a test that only tests your code at the unit level. That typically means a single method, or at most a class since to access a single method you may need to create an instance of a class and thus also execute its constructor, etc. <a href="https://ardalis.com/unit-test-or-integration-test-and-why-you-should-care">If you have a test that tests more than one class working together, or that depends on code that isn't yours (like, say, an ORM), it's not a unit test. It's an integration test.</a></p>
<p>The author goes on to suggest that since EF Core supports an in-memory database, you can use that for unit-testing your application. You can't. You can use it for integration testing, which is great. But it's not unit testing. The distinction is important because clean code should be unit testable. If it isn't, it's a code smell, suggesting that you may have too much coupling. You might be OK with that, but you should at least be aware of the issue so you can decide for yourself whether you're OK with it, rather than having a false sense of complacency because your integration tests work well enough.</p>
<p><em>Would your team or application benefit from an application assessment, highlighting potential problem areas and identifying a path toward better maintainability? Contact me at <a href="https://ardalis.com/contact-us">ardalis.com</a> and let's see how I can help.</em></p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://deviq.com/repository-pattern/">Repository Pattern</a></li>
<li><a href="https://www.thereformedprogrammer.net/is-the-repository-pattern-useful-with-entity-framework-core/">Is the repository pattern useful with EF Core?</a></li>
<li><a href="https://ardalis.com/avoid-lazy-loading-entities-in-asp-net-applications">Avoid Lazy Loading Entities in ASP.NET Applications</a></li>
<li><a href="https://deviq.com/specification-pattern/">Specification Pattern</a></li>
<li><a href="https://ardalis.com/unit-test-or-integration-test-and-why-you-should-care">Unit Test or Integration Test (and why you should care)</a></li>
<li><a href="https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-2.1">Integration Tests in ASP.NET Core</a></li>
</ul>
]]></content:encoded>
      <enclosure length="4863081" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/1d995220-1223-47a0-869a-ffaa538a478d/47780ce4_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Do I Need a Repository?</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/1d995220-1223-47a0-869a-ffaa538a478d/3000x3000/1528744576artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:07:45</itunes:duration>
      <itunes:summary>This week we&apos;ll answer this extremely common question about the Repository pattern, and when you should think about using it.</itunes:summary>
      <itunes:subtitle>This week we&apos;ll answer this extremely common question about the Repository pattern, and when you should think about using it.</itunes:subtitle>
      <itunes:keywords>ef core, repository, ef</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>24</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">9f30d12d-d429-4f55-bf68-e22a68d32210</guid>
      <title>Domain Events - After Persistence</title>
      <description><![CDATA[<h1>Domain Events - After Persistence</h1>
<p>The previous tip talked about domain events that fire before persistence. This week we'll look at another kind of domain event that should typically only fire after persistence.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>If you're new to the domain events pattern, I recommend you listen to <a href="http://www.weeklydevtips.com/022">episode 22</a> before this one. In general, I recommend listening to this podcast in order, but I can't force that on you...</p>
<p>When you have a scenario in your application where a requirement is phrased &quot;when X happens, then Y should happen,&quot; that's often an indication that using a domain event might be appropriate. If the follow-on behavior has side effects that extend beyond your application, that's often an indication that the event shouldn't occur unless persistence is successful. Let's consider a contrived real-world example.</p>
<p>Imagine you have a simple ecommerce application. People can browse products, add them to a virtual cart or basket, and checkout by providing payment and shipping details. Everything is working fine when you get a new requirement: when the customer checks out, they should get an email confirming their purchase. Sounds like a good candidate for a domain event, right? Ok, so your first pass at this is to simply go into the Checkout method and raise a CartCheckedOut event, which you then handle with a NotifyCustomerOnCheckoutHandler class. You're using a simple in-proc approach to domain events so when you raise an event, all handlers fire immediately before execution resumes. You roll out the change with the next deployment. Unfortunately, another change to the codebase resulted in an undetected error related to saving new orders. Meaning, they're not being saved in the database. Now the result is that customers are checking out, being redirected to a friendly error screen, but also getting an email now confirming their order was placed. They're mostly assuming everything is fine on account of the pleasant email confirmation, but in fact your system has no record of the order they just placed because it didn't save. In this kind of situation, you'd really rather not send that confirmation email until you've successfully saved the new order.</p>
<p>While in-proc domain events are often implemented using simple static method calls to raise or register for events, post-persistence events need to be stored somewhere and only dispatched once persistence has been successful. One approach you can use for this in .NET applications is to store the events in a collection on the entity or aggregate root, and then override the behavior of the Entity Framework DbContext so that it dispatches these events once it has successfully saved the entity or aggregate. My <a href="https://github.com/ardalis/cleanarchitecture">CleanArchitecture sample on GitHub</a> demonstrates how to put this approach into action using <a href="https://lostechies.com/jimmybogard/2014/05/13/a-better-domain-events-pattern/">a technique Jimmy Bogard wrote about a few years ago</a>. It involves overriding the SaveChanges method on the DbContext, finding all tracked entities with events in their collection, and then dispatching these events. His original approach fires the events before actually saving the entity, but I much prefer persisting first and using a different kind of domain event for immediate, no side effect events.</p>
<p>In the Clean Architecture sample, I have a simple ToDo entity that raises an event when it is marked complete. This event is only fired once the entity's state is saved. At that point, a handler tasked with notifying anybody subscribed to that entity's status could safely send out notifications. The pattern is very effective as a lightweight way to decouple follow-on behavior from actions that trigger them within the domain model, and it doesn't require adding additional architecture in the form of message queues or buses to achieve it.</p>
<p><em>Would your team or application benefit from an application assessment, highlighting potential problem areas and identifying a path toward better maintainability? Contact me at <a href="https://ardalis.com/contact-us">ardalis.com</a> and let's see how I can help.</em></p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://github.com/ardalis/cleanarchitecture">Clean Architecture Sample (GitHub)</a></li>
<li><a href="https://www.pluralsight.com/courses/domain-driven-design-fundamentals">Domain-Driven Design Fundamentals</a> - includes Domain Events</li>
</ul>
]]></description>
      <pubDate>Mon, 4 Jun 2018 06:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h1>Domain Events - After Persistence</h1>
<p>The previous tip talked about domain events that fire before persistence. This week we'll look at another kind of domain event that should typically only fire after persistence.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>If you're new to the domain events pattern, I recommend you listen to <a href="http://www.weeklydevtips.com/022">episode 22</a> before this one. In general, I recommend listening to this podcast in order, but I can't force that on you...</p>
<p>When you have a scenario in your application where a requirement is phrased &quot;when X happens, then Y should happen,&quot; that's often an indication that using a domain event might be appropriate. If the follow-on behavior has side effects that extend beyond your application, that's often an indication that the event shouldn't occur unless persistence is successful. Let's consider a contrived real-world example.</p>
<p>Imagine you have a simple ecommerce application. People can browse products, add them to a virtual cart or basket, and checkout by providing payment and shipping details. Everything is working fine when you get a new requirement: when the customer checks out, they should get an email confirming their purchase. Sounds like a good candidate for a domain event, right? Ok, so your first pass at this is to simply go into the Checkout method and raise a CartCheckedOut event, which you then handle with a NotifyCustomerOnCheckoutHandler class. You're using a simple in-proc approach to domain events so when you raise an event, all handlers fire immediately before execution resumes. You roll out the change with the next deployment. Unfortunately, another change to the codebase resulted in an undetected error related to saving new orders. Meaning, they're not being saved in the database. Now the result is that customers are checking out, being redirected to a friendly error screen, but also getting an email now confirming their order was placed. They're mostly assuming everything is fine on account of the pleasant email confirmation, but in fact your system has no record of the order they just placed because it didn't save. In this kind of situation, you'd really rather not send that confirmation email until you've successfully saved the new order.</p>
<p>While in-proc domain events are often implemented using simple static method calls to raise or register for events, post-persistence events need to be stored somewhere and only dispatched once persistence has been successful. One approach you can use for this in .NET applications is to store the events in a collection on the entity or aggregate root, and then override the behavior of the Entity Framework DbContext so that it dispatches these events once it has successfully saved the entity or aggregate. My <a href="https://github.com/ardalis/cleanarchitecture">CleanArchitecture sample on GitHub</a> demonstrates how to put this approach into action using <a href="https://lostechies.com/jimmybogard/2014/05/13/a-better-domain-events-pattern/">a technique Jimmy Bogard wrote about a few years ago</a>. It involves overriding the SaveChanges method on the DbContext, finding all tracked entities with events in their collection, and then dispatching these events. His original approach fires the events before actually saving the entity, but I much prefer persisting first and using a different kind of domain event for immediate, no side effect events.</p>
<p>In the Clean Architecture sample, I have a simple ToDo entity that raises an event when it is marked complete. This event is only fired once the entity's state is saved. At that point, a handler tasked with notifying anybody subscribed to that entity's status could safely send out notifications. The pattern is very effective as a lightweight way to decouple follow-on behavior from actions that trigger them within the domain model, and it doesn't require adding additional architecture in the form of message queues or buses to achieve it.</p>
<p><em>Would your team or application benefit from an application assessment, highlighting potential problem areas and identifying a path toward better maintainability? Contact me at <a href="https://ardalis.com/contact-us">ardalis.com</a> and let's see how I can help.</em></p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://github.com/ardalis/cleanarchitecture">Clean Architecture Sample (GitHub)</a></li>
<li><a href="https://www.pluralsight.com/courses/domain-driven-design-fundamentals">Domain-Driven Design Fundamentals</a> - includes Domain Events</li>
</ul>
]]></content:encoded>
      <enclosure length="3336649" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/90f48762-d752-4ead-ae65-65630f78021d/f8eec63c_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Domain Events - After Persistence</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/90f48762-d752-4ead-ae65-65630f78021d/3000x3000/1527862776artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:05:23</itunes:duration>
      <itunes:summary>The previous tip talked about domain events that fire before persistence. This week we&apos;ll look at another kind of domain event that should typically only fire after persistence.</itunes:summary>
      <itunes:subtitle>The previous tip talked about domain events that fire before persistence. This week we&apos;ll look at another kind of domain event that should typically only fire after persistence.</itunes:subtitle>
      <itunes:keywords>ardalis, ddd, domain-driven design, domain events</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>23</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">374e8069-2b22-4a65-b80e-948b53b573f7</guid>
      <title>Domain Events - Before Persistence</title>
      <description><![CDATA[<h1>Domain Events - Before Peristence</h1>
<p>Domain Events are a DDD design pattern that in my experience can really improve the design of complex applications. In this episode I describe specifically how you would benefit from raising and handling these events prior to persisting the state of your entities.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>So before we get started, let's describe what a domain event is. A domain event is something that happens in your system that a domain expert cares about. Domain events are part of your domain model. They belong in the Core of your <a href="https://github.com/ardalis/cleanarchitecture">Clean Architecture</a>. They should be designed at the abstraction level of your domain model, and shouldn't reference UI or infrastructure concerns.</p>
<p>Domain events are a pattern, and one with several difference implementation approaches. I generally segment these approaches into two camps: before persistence and after persistence. For this tip, we're going to focus on events that occur and are handled prior to persistence. In future tips, I'll talk about domain events that should only be dispatched once persistence has been successful.</p>
<p>So, as a pattern, what problem are domain events designed to solve? Just as with other event-driven programming models, such as user interface events, domain events provide a way to decouple things that occur in your system from things such occurrences trigger. A common example I use is checking out a shopping cart from an ecommerce site. When the user checks out, a variety of other things generally should take place. The order should be saved. Payment should be processed. Inventory should be checked. Notifications should be sent. Now, you could put all of this logic into a Checkout method, but then that method is going to be pretty large and all-knowing. It's probably going to violate the <a href="http://deviq.com/single-responsibility-principle/">Single Responsibility</a> and <a href="http://deviq.com/open-closed-principle/">Open/Closed</a> Principles. Another approach would be to raise an event when the user checks out, and then to have separate handlers responsible for payment processing, inventory monitoring, notifications, etc.</p>
<p>Looking specifically at events that make sense to handle before persistence, the primary rule is that such events shouldn't have any side effects external to the application. A common scenario is to perform some kind of validation. Imagine you have a Purchase Order domain object, which includes a collection of Line Item objects. The Purchase Order has a maximum amount associated with it, and the total of all the Line Item object amounts must not exceed this amount. For the sake of simplicity let's say the Purchase Order object includes the logic to check whether its child Line Item objects exceeds its maximum. When a Line Item object is updated, how can we run this code?</p>
<p>One option would be to provide a reference from each Line Item to its parent Purchase Order. This is fairly common but results in circular dependencies since Purchase Order also has a reference to a collection of its Line Item objects. These objects together can be considered an <a href="http://deviq.com/aggregate-pattern/">Aggregate</a>, and ideally dependencies should flow from the Aggregate Root (in this case Purchase Order) to its children, and not the other way around. So, let's assume we follow this practice, which means we can simply call a method on Purchase Order from Line Item directly.</p>
<p>Another common approach I see developers use instead of domain events is to pull all of the logic up from child objects into the aggregate root object. So instead of having a property setter or property on Line Item to update its amount, there might be a method on Purchase Order called UpdateLineItemAmount that would do the work. This breaks encapsulation and will cause the root object to become bloated while the child objects become mere DTOs. It can work, but it's not very good from an object-oriented design standpoint.</p>
<p>So how would domain events apply here? First, you'd put the logic to modify Line Item on the Line Item class where it belongs. Then, in the UpdateAmount method, you would raise an appropriate domain event, like LineItemAmountUpdated. The aggregate root would subscribe to this event and would handled the event in process (not asynchronously or in another thread). If necessary, the handler could raise an exception. In any case, it could update properties of the root object to indicate whether it was currently in a valid state, which could easily be reflected in the UI. This is one particular use case for domain events that I've found very helpful, and which I typically refer to as <em>aggregate events</em> since there isn't a separate event handler type in this case. I have a small sample showing them in action on GitHub you can check out in the show notes. With aggregate events in place, you can check all the blocks for your object design. Your aggregate's dependencies flow from root to children. Your aggregate's child objects are responsible for their own behavior. Changes to child objects are communicated to the aggregate root which is responsible for ensuring the validity of the entire aggregate. Many scenarios have rules where the root object has to perform validation checks that are based on the aggregate of several child objects, and this pattern provides an elegant solution to this problem.</p>
<p><em>Would your team or application benefit from an application assessment, highlighting potential problem areas and identifying a path toward better maintainability? Contact me at <a href="https://ardalis.com/contact-us">ardalis.com</a> and let's see how I can help.</em></p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://github.com/ardalis/cleanarchitecture">Clean Architecture Sample (GitHub)</a></li>
<li><a href="http://deviq.com/aggregate-pattern/">Aggregate Design Pattern</a></li>
<li><a href="https://github.com/ardalis/AggregateEvents">Aggregate Events Sample (GitHub)</a></li>
</ul>
]]></description>
      <pubDate>Mon, 30 Apr 2018 06:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h1>Domain Events - Before Peristence</h1>
<p>Domain Events are a DDD design pattern that in my experience can really improve the design of complex applications. In this episode I describe specifically how you would benefit from raising and handling these events prior to persisting the state of your entities.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>So before we get started, let's describe what a domain event is. A domain event is something that happens in your system that a domain expert cares about. Domain events are part of your domain model. They belong in the Core of your <a href="https://github.com/ardalis/cleanarchitecture">Clean Architecture</a>. They should be designed at the abstraction level of your domain model, and shouldn't reference UI or infrastructure concerns.</p>
<p>Domain events are a pattern, and one with several difference implementation approaches. I generally segment these approaches into two camps: before persistence and after persistence. For this tip, we're going to focus on events that occur and are handled prior to persistence. In future tips, I'll talk about domain events that should only be dispatched once persistence has been successful.</p>
<p>So, as a pattern, what problem are domain events designed to solve? Just as with other event-driven programming models, such as user interface events, domain events provide a way to decouple things that occur in your system from things such occurrences trigger. A common example I use is checking out a shopping cart from an ecommerce site. When the user checks out, a variety of other things generally should take place. The order should be saved. Payment should be processed. Inventory should be checked. Notifications should be sent. Now, you could put all of this logic into a Checkout method, but then that method is going to be pretty large and all-knowing. It's probably going to violate the <a href="http://deviq.com/single-responsibility-principle/">Single Responsibility</a> and <a href="http://deviq.com/open-closed-principle/">Open/Closed</a> Principles. Another approach would be to raise an event when the user checks out, and then to have separate handlers responsible for payment processing, inventory monitoring, notifications, etc.</p>
<p>Looking specifically at events that make sense to handle before persistence, the primary rule is that such events shouldn't have any side effects external to the application. A common scenario is to perform some kind of validation. Imagine you have a Purchase Order domain object, which includes a collection of Line Item objects. The Purchase Order has a maximum amount associated with it, and the total of all the Line Item object amounts must not exceed this amount. For the sake of simplicity let's say the Purchase Order object includes the logic to check whether its child Line Item objects exceeds its maximum. When a Line Item object is updated, how can we run this code?</p>
<p>One option would be to provide a reference from each Line Item to its parent Purchase Order. This is fairly common but results in circular dependencies since Purchase Order also has a reference to a collection of its Line Item objects. These objects together can be considered an <a href="http://deviq.com/aggregate-pattern/">Aggregate</a>, and ideally dependencies should flow from the Aggregate Root (in this case Purchase Order) to its children, and not the other way around. So, let's assume we follow this practice, which means we can simply call a method on Purchase Order from Line Item directly.</p>
<p>Another common approach I see developers use instead of domain events is to pull all of the logic up from child objects into the aggregate root object. So instead of having a property setter or property on Line Item to update its amount, there might be a method on Purchase Order called UpdateLineItemAmount that would do the work. This breaks encapsulation and will cause the root object to become bloated while the child objects become mere DTOs. It can work, but it's not very good from an object-oriented design standpoint.</p>
<p>So how would domain events apply here? First, you'd put the logic to modify Line Item on the Line Item class where it belongs. Then, in the UpdateAmount method, you would raise an appropriate domain event, like LineItemAmountUpdated. The aggregate root would subscribe to this event and would handled the event in process (not asynchronously or in another thread). If necessary, the handler could raise an exception. In any case, it could update properties of the root object to indicate whether it was currently in a valid state, which could easily be reflected in the UI. This is one particular use case for domain events that I've found very helpful, and which I typically refer to as <em>aggregate events</em> since there isn't a separate event handler type in this case. I have a small sample showing them in action on GitHub you can check out in the show notes. With aggregate events in place, you can check all the blocks for your object design. Your aggregate's dependencies flow from root to children. Your aggregate's child objects are responsible for their own behavior. Changes to child objects are communicated to the aggregate root which is responsible for ensuring the validity of the entire aggregate. Many scenarios have rules where the root object has to perform validation checks that are based on the aggregate of several child objects, and this pattern provides an elegant solution to this problem.</p>
<p><em>Would your team or application benefit from an application assessment, highlighting potential problem areas and identifying a path toward better maintainability? Contact me at <a href="https://ardalis.com/contact-us">ardalis.com</a> and let's see how I can help.</em></p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://github.com/ardalis/cleanarchitecture">Clean Architecture Sample (GitHub)</a></li>
<li><a href="http://deviq.com/aggregate-pattern/">Aggregate Design Pattern</a></li>
<li><a href="https://github.com/ardalis/AggregateEvents">Aggregate Events Sample (GitHub)</a></li>
</ul>
]]></content:encoded>
      <enclosure length="4296896" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/03c98a17-f2fb-46a9-a4d5-1aa12a0f6f86/d8227140_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Domain Events - Before Persistence</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/03c98a17-f2fb-46a9-a4d5-1aa12a0f6f86/3000x3000/1524749002artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:06:53</itunes:duration>
      <itunes:summary>Domain Events are a DDD design pattern that in my experience can really improve the design of complex applications. In this episode I describe specifically how you would benefit from raising and handling these events prior to persisting the state of your entities.
</itunes:summary>
      <itunes:subtitle>Domain Events are a DDD design pattern that in my experience can really improve the design of complex applications. In this episode I describe specifically how you would benefit from raising and handling these events prior to persisting the state of your entities.
</itunes:subtitle>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>22</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">7bf411b3-81d0-40e5-ae52-4b3f328238cd</guid>
      <title>Breadcrumbs and Troubleshooting</title>
      <description><![CDATA[<h1>Breadcrumbs and Troubleshooting</h1>
<p>This week I'm taking a break from design patterns to talk about a useful skill to prevent you and your team having to reinvent the wheel when it comes to troubleshooting problems or working through new tools or frameworks.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>Have you ever spent a few hours working through getting a new tool, library, package, or framework working? Along the way, did you run into things that didn't quite go as easily as the documentation, video, or presentation on the subject made it out to be? Did you end up spending time on Google, StackOverflow, etc. trying to figure out how to really get things to work in your real world environment? If you answered yes to these questions, you're in good company. I've certainly been there countless times.</p>
<p>Now, follow-up question. Have you ever done all of the above, but with a sense of deja vu, because you'd had to do the exact same thing some time previously? And when you found the blog post or sample that reminded you of the issue, you were like &quot;Oh yeah, I had to do this last time, too!&quot; I find these to be some of the most frustrating hours of my work. I want to be building things, making progress, seeing things grow in functionality, not banging my head against the same walls I've left dents and bloodstains on in the past. I also want to make sure my coworkers, my teammates, and my clients benefit from the cuts and bruises I acquire as I blaze a trail through unknown territories. So, what can you do to limit the amount of retreading through through the same painful terrain you (and often your team) have to do?</p>
<p>Obviously the first thing you could do is take notes. This is natural for some developers, but others find it distracting. When they're in the zone, figuring things out and getting things done, they don't want to stop to document things along the way. Breaking their flow might mean the difference between getting things working and giving up and walking away. If you can take notes, do so. I suggest keeping track of the URLs you found useful, along with screenshots of things like property settings or other configurations that you needed to modify to get things working.</p>
<p>Sometimes, you can document things after you got things working. This is often true for fairly simple problems. However, for something that's taken hours rather than minutes, it's likely that by the time you're done, you've forgotten a few steps along the way. Here are a few things you can do to leave yourself a trail of breadcrumbs as you work. And of course, by <em>breadcrumbs</em>, I actually mean something better than breadcrumbs that you'll actually find later, since the whole origin of breadcrumbs is from a story in which breadcrumbs are a decidedly poor choice to leave behind you in order to find your way.</p>
<p>One approach I use is to use a particular browser instance while I'm working on a specific problem, and to open all links related to the problem at hand in their own tabs. If they're useless, I close them, but if they're at all helpful, I leave them open. Once I've figured out whatever it is I've been working on, I can look at my tab history and add the links as references wherever is appropriate. Sometimes that's a link in a source code file. Sometimes it's in a README file. Sometimes it's in a blog post (or a Trello card for a blog post I want to write). In any case, I associate the links to the resources that helped me along the way with the problem I just solved while everything is still fresh in my mind and the links are literally stil open in my browser.</p>
<p>Another tool you can use is screen recording. If you don't like actually writing/typing notes, you can record conference calls with clients using tools like Zoom or GoToMeeting. You can also record your own screen using tools like <a href="https://www.techsmith.com/video-editor.html">Camtasia</a>, which I highly recommend. Then you can quickly jump around in the video to see yourself tackling problems, and retroactively make notes or write up a postmortem or checklist. Occasionaly the video itself might even be worth editing into something, perhaps for internal consumption by your team.</p>
<p>Yet another tool I've used in the past is <a href="http://www.timesnapper.com/">TimeSnapper</a>, which would take and store screenshots every so many seconds on your machine. Then it would let you play them back later to see what you'd been spending your time on. I haven't used it in a while but it appears to still be active. You could do something similar by just taking a screenshot periodically as you progress through a problem, but you're much more likely to forget without a tool like this.</p>
<p>The most important thing to take away from this episode is that you don't want to fight through the same problem more than once. Ideally you want to prevent your team from having to fight through problems you've already solved. The key is to share the necessary information in a way that doesn't slow you down while you're solving the problem, but which ultimately is discoverable by you and your team the next time you encounter the same problem. An approach I've used for years is to blog about things once I find a solution. I can't tell you how many times I've googled for something only to find the answer <em>on my own blog</em>. If you have your own techniques you use to rediscover solutions to problems you've previously solved, please leave them in the comments for the show.</p>
<p>Oh, and I wrote an article last year on <a href="https://hackernoon.com/working-through-roadblocks-a-guide-for-new-programmers-826c2aa455a2">Working Through Roadblocks - A Guide for New Programmers</a>. I'll leave a link in the show notes for that as well.</p>
<p><em>Would your team or application benefit from an application assessment, highlighting potential problem areas and identifying a path toward better maintainability? Contact me at <a href="https://ardalis.com/contact-us">ardalis.com</a> and let's see how I can help.</em></p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://www.techsmith.com/video-editor.html">Camtasia</a></li>
<li><a href="http://www.timesnapper.com/">TimeSnapper</a></li>
<li><a href="https://hackernoon.com/working-through-roadblocks-a-guide-for-new-programmers-826c2aa455a2">Working Through Roadblocks - A Guide for New Programmers</a></li>
</ul>
]]></description>
      <pubDate>Mon, 23 Apr 2018 06:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h1>Breadcrumbs and Troubleshooting</h1>
<p>This week I'm taking a break from design patterns to talk about a useful skill to prevent you and your team having to reinvent the wheel when it comes to troubleshooting problems or working through new tools or frameworks.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>Have you ever spent a few hours working through getting a new tool, library, package, or framework working? Along the way, did you run into things that didn't quite go as easily as the documentation, video, or presentation on the subject made it out to be? Did you end up spending time on Google, StackOverflow, etc. trying to figure out how to really get things to work in your real world environment? If you answered yes to these questions, you're in good company. I've certainly been there countless times.</p>
<p>Now, follow-up question. Have you ever done all of the above, but with a sense of deja vu, because you'd had to do the exact same thing some time previously? And when you found the blog post or sample that reminded you of the issue, you were like &quot;Oh yeah, I had to do this last time, too!&quot; I find these to be some of the most frustrating hours of my work. I want to be building things, making progress, seeing things grow in functionality, not banging my head against the same walls I've left dents and bloodstains on in the past. I also want to make sure my coworkers, my teammates, and my clients benefit from the cuts and bruises I acquire as I blaze a trail through unknown territories. So, what can you do to limit the amount of retreading through through the same painful terrain you (and often your team) have to do?</p>
<p>Obviously the first thing you could do is take notes. This is natural for some developers, but others find it distracting. When they're in the zone, figuring things out and getting things done, they don't want to stop to document things along the way. Breaking their flow might mean the difference between getting things working and giving up and walking away. If you can take notes, do so. I suggest keeping track of the URLs you found useful, along with screenshots of things like property settings or other configurations that you needed to modify to get things working.</p>
<p>Sometimes, you can document things after you got things working. This is often true for fairly simple problems. However, for something that's taken hours rather than minutes, it's likely that by the time you're done, you've forgotten a few steps along the way. Here are a few things you can do to leave yourself a trail of breadcrumbs as you work. And of course, by <em>breadcrumbs</em>, I actually mean something better than breadcrumbs that you'll actually find later, since the whole origin of breadcrumbs is from a story in which breadcrumbs are a decidedly poor choice to leave behind you in order to find your way.</p>
<p>One approach I use is to use a particular browser instance while I'm working on a specific problem, and to open all links related to the problem at hand in their own tabs. If they're useless, I close them, but if they're at all helpful, I leave them open. Once I've figured out whatever it is I've been working on, I can look at my tab history and add the links as references wherever is appropriate. Sometimes that's a link in a source code file. Sometimes it's in a README file. Sometimes it's in a blog post (or a Trello card for a blog post I want to write). In any case, I associate the links to the resources that helped me along the way with the problem I just solved while everything is still fresh in my mind and the links are literally stil open in my browser.</p>
<p>Another tool you can use is screen recording. If you don't like actually writing/typing notes, you can record conference calls with clients using tools like Zoom or GoToMeeting. You can also record your own screen using tools like <a href="https://www.techsmith.com/video-editor.html">Camtasia</a>, which I highly recommend. Then you can quickly jump around in the video to see yourself tackling problems, and retroactively make notes or write up a postmortem or checklist. Occasionaly the video itself might even be worth editing into something, perhaps for internal consumption by your team.</p>
<p>Yet another tool I've used in the past is <a href="http://www.timesnapper.com/">TimeSnapper</a>, which would take and store screenshots every so many seconds on your machine. Then it would let you play them back later to see what you'd been spending your time on. I haven't used it in a while but it appears to still be active. You could do something similar by just taking a screenshot periodically as you progress through a problem, but you're much more likely to forget without a tool like this.</p>
<p>The most important thing to take away from this episode is that you don't want to fight through the same problem more than once. Ideally you want to prevent your team from having to fight through problems you've already solved. The key is to share the necessary information in a way that doesn't slow you down while you're solving the problem, but which ultimately is discoverable by you and your team the next time you encounter the same problem. An approach I've used for years is to blog about things once I find a solution. I can't tell you how many times I've googled for something only to find the answer <em>on my own blog</em>. If you have your own techniques you use to rediscover solutions to problems you've previously solved, please leave them in the comments for the show.</p>
<p>Oh, and I wrote an article last year on <a href="https://hackernoon.com/working-through-roadblocks-a-guide-for-new-programmers-826c2aa455a2">Working Through Roadblocks - A Guide for New Programmers</a>. I'll leave a link in the show notes for that as well.</p>
<p><em>Would your team or application benefit from an application assessment, highlighting potential problem areas and identifying a path toward better maintainability? Contact me at <a href="https://ardalis.com/contact-us">ardalis.com</a> and let's see how I can help.</em></p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://www.techsmith.com/video-editor.html">Camtasia</a></li>
<li><a href="http://www.timesnapper.com/">TimeSnapper</a></li>
<li><a href="https://hackernoon.com/working-through-roadblocks-a-guide-for-new-programmers-826c2aa455a2">Working Through Roadblocks - A Guide for New Programmers</a></li>
</ul>
]]></content:encoded>
      <enclosure length="3992594" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/0c382c1a-c73e-47c7-906a-52897a3bf617/824155f5_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Breadcrumbs and Troubleshooting</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/0c382c1a-c73e-47c7-906a-52897a3bf617/3000x3000/1524071568artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:06:22</itunes:duration>
      <itunes:summary>This week I&apos;m taking a break from design patterns to talk about a useful skill to prevent you and your team having to reinvent the wheel when it comes to troubleshooting problems or working through new tools or frameworks.</itunes:summary>
      <itunes:subtitle>This week I&apos;m taking a break from design patterns to talk about a useful skill to prevent you and your team having to reinvent the wheel when it comes to troubleshooting problems or working through new tools or frameworks.</itunes:subtitle>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>21</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">0fa50686-97a7-4d58-b1c6-fe9b20aef36b</guid>
      <title>Abstraction Levels and Authorization</title>
      <description><![CDATA[<h1>Abstraction Levels and Authorization</h1>
<p>Working at too low of an abstraction level is a common source of duplication and technical debt. A very common culprit in this area is authorization.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>Let's take a quick break from the more commonplace design patterns and talk a little bit about abstraction levels and how they impact duplication and technical debt in our software designs. You can think of high levels of abstraction as being at the level of the real world concept your software is modeling. For an ecommerce application, it might be buying something, or adding an item to a cart. The whole notion of a cart or basket is a metaphor explicitly pulled into ecommerce applications from the real world. There's certainly no literal cart or basket involved in most online shopping experiences. Low levels of abstraction refer to implementation details used by the actual software (and sometimes hardware) used by the system. When developing software, it's a good design decision to encapsulate low levels of abstraction separately from higher levels, and thus to avoid mixing abstraction layers more than necessary within any given module. The more you mix abstraction levels, the more you add tight coupling to your design, making it harder to change in response to future requirements.</p>
<p>A common requirement in many applications is <em>authorization</em>. Authorization is often conflated with the other auth word, <em>authentication</em>. Authentication is the process of determining who the user is. Authorization is the process of determining whether a particular user should be allowed to perform a certain operation. It can include default rules for anonymous users, but aside from that authorization only makes sense once authentication has taken place and you know who the user is.</p>
<p>Authorization rules can take many forms, and can be as granular as specifying that a specific user has access to a specific resource. However, most applications that need authorization will leverage roles or claims to specify how groups of users should or should not have access to certain sets of resources. This makes it much easier to manage collections of users and collections of resources, since otherwise a huge number of specific user-to-resource rights would need to be maintained. However, even this is often prone to duplication that results from too low of an abstraction level.</p>
<p>It's common in platforms like .NET to use roles as at least one part of determining authorization, and to use conditional logic like <code>if (user.IsInRole(&quot;Admins&quot;))</code> any time authorization logic needs to be performed. In any non-trivial system that uses this pattern, you'll probably find quite a few lines of code that match this expression, meaning there is a great deal of duplication. Duplication isn't always bad, but in this case the implementation detail of performing a role check as one part of checking whether a user is authorized to access a particular resource is adding to the system's technical debt.</p>
<p>Frequently, authorization rules will change over time. What happens when a new role or set of claims is created that should have access to some resources? Every one of the <code>if</code> statements related to access to that resource will need to be modified. What happens if you switch from using roles to claims? Every <code>if</code> statement will need to be modified. Of course, when these modifications take place, there's also the chance that bugs will be introduced, and these will manifest in many cases as security breaches.</p>
<p>There are many patterns you can use to improve this design. You can use a more declarative approach, such that adding certain attributes will protect certain endpoints in your application. This can remove conditional logic and can eliminate some duplication since these attributes can be applied at class or even base class levels. However, if your authorization logic is more complex than simple role membership, it may not be sufficient or at the least you'll need to write your own attributes or filters.</p>
<p>Another approach I've found useful is to create a first-class abstraction that describes whether a given user should have access to a given resource. I typically call such types <em>privileges</em> but you can refer to them as AuthorizationPolicies or whatever makes sense to you and your team if you prefer. A privilege takes in who the user is and what resource they're attempting to work with, and specifies what operations that user can perform on that resource. Since it's a design pattern, not a specific solution, how you implement the details is up to you. A common approach is to implement methods for things <code>CanRead</code>, <code>CanCreate</code>, and <code>CanModify</code>. You can also further modify it to work for collections or types of resources, so that for example if the user should be able to manage product definitions, you could check whether the user has rights to type <code>Product</code> and if so, include a link to manage products in the application's menu.</p>
<p>I have an article describing <a href="https://ardalis.com/favor-privileges-over-role-checks">how to use privileges instead of repetitive role checks</a> that I'll link to in the show notes that may help you get started if you're interested in learning more.</p>
<p><em>Would your team or application benefit from an application assessment, highlighting potential problem areas and identifying a path toward better maintainability? Contact me at <a href="https://ardalis.com/contact-us">ardalis.com</a> and let's see how I can help.</em></p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://ardalis.com/favor-privileges-over-role-checks">Favor Privileges over Role Checks</a></li>
<li><a href="http://deviq.com/technical-debt/">Technical Debt</a></li>
</ul>
]]></description>
      <pubDate>Mon, 12 Mar 2018 06:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h1>Abstraction Levels and Authorization</h1>
<p>Working at too low of an abstraction level is a common source of duplication and technical debt. A very common culprit in this area is authorization.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>Let's take a quick break from the more commonplace design patterns and talk a little bit about abstraction levels and how they impact duplication and technical debt in our software designs. You can think of high levels of abstraction as being at the level of the real world concept your software is modeling. For an ecommerce application, it might be buying something, or adding an item to a cart. The whole notion of a cart or basket is a metaphor explicitly pulled into ecommerce applications from the real world. There's certainly no literal cart or basket involved in most online shopping experiences. Low levels of abstraction refer to implementation details used by the actual software (and sometimes hardware) used by the system. When developing software, it's a good design decision to encapsulate low levels of abstraction separately from higher levels, and thus to avoid mixing abstraction layers more than necessary within any given module. The more you mix abstraction levels, the more you add tight coupling to your design, making it harder to change in response to future requirements.</p>
<p>A common requirement in many applications is <em>authorization</em>. Authorization is often conflated with the other auth word, <em>authentication</em>. Authentication is the process of determining who the user is. Authorization is the process of determining whether a particular user should be allowed to perform a certain operation. It can include default rules for anonymous users, but aside from that authorization only makes sense once authentication has taken place and you know who the user is.</p>
<p>Authorization rules can take many forms, and can be as granular as specifying that a specific user has access to a specific resource. However, most applications that need authorization will leverage roles or claims to specify how groups of users should or should not have access to certain sets of resources. This makes it much easier to manage collections of users and collections of resources, since otherwise a huge number of specific user-to-resource rights would need to be maintained. However, even this is often prone to duplication that results from too low of an abstraction level.</p>
<p>It's common in platforms like .NET to use roles as at least one part of determining authorization, and to use conditional logic like <code>if (user.IsInRole(&quot;Admins&quot;))</code> any time authorization logic needs to be performed. In any non-trivial system that uses this pattern, you'll probably find quite a few lines of code that match this expression, meaning there is a great deal of duplication. Duplication isn't always bad, but in this case the implementation detail of performing a role check as one part of checking whether a user is authorized to access a particular resource is adding to the system's technical debt.</p>
<p>Frequently, authorization rules will change over time. What happens when a new role or set of claims is created that should have access to some resources? Every one of the <code>if</code> statements related to access to that resource will need to be modified. What happens if you switch from using roles to claims? Every <code>if</code> statement will need to be modified. Of course, when these modifications take place, there's also the chance that bugs will be introduced, and these will manifest in many cases as security breaches.</p>
<p>There are many patterns you can use to improve this design. You can use a more declarative approach, such that adding certain attributes will protect certain endpoints in your application. This can remove conditional logic and can eliminate some duplication since these attributes can be applied at class or even base class levels. However, if your authorization logic is more complex than simple role membership, it may not be sufficient or at the least you'll need to write your own attributes or filters.</p>
<p>Another approach I've found useful is to create a first-class abstraction that describes whether a given user should have access to a given resource. I typically call such types <em>privileges</em> but you can refer to them as AuthorizationPolicies or whatever makes sense to you and your team if you prefer. A privilege takes in who the user is and what resource they're attempting to work with, and specifies what operations that user can perform on that resource. Since it's a design pattern, not a specific solution, how you implement the details is up to you. A common approach is to implement methods for things <code>CanRead</code>, <code>CanCreate</code>, and <code>CanModify</code>. You can also further modify it to work for collections or types of resources, so that for example if the user should be able to manage product definitions, you could check whether the user has rights to type <code>Product</code> and if so, include a link to manage products in the application's menu.</p>
<p>I have an article describing <a href="https://ardalis.com/favor-privileges-over-role-checks">how to use privileges instead of repetitive role checks</a> that I'll link to in the show notes that may help you get started if you're interested in learning more.</p>
<p><em>Would your team or application benefit from an application assessment, highlighting potential problem areas and identifying a path toward better maintainability? Contact me at <a href="https://ardalis.com/contact-us">ardalis.com</a> and let's see how I can help.</em></p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://ardalis.com/favor-privileges-over-role-checks">Favor Privileges over Role Checks</a></li>
<li><a href="http://deviq.com/technical-debt/">Technical Debt</a></li>
</ul>
]]></content:encoded>
      <enclosure length="4265618" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/b8b94a99-ecb8-4985-aa96-38c1e0c32c70/222132e7_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Abstraction Levels and Authorization</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/b8b94a99-ecb8-4985-aa96-38c1e0c32c70/3000x3000/1520630690artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:06:22</itunes:duration>
      <itunes:summary>Working at too low of an abstraction level is a common source of duplication and technical debt. A very common culprit in this area is authorization.</itunes:summary>
      <itunes:subtitle>Working at too low of an abstraction level is a common source of duplication and technical debt. A very common culprit in this area is authorization.</itunes:subtitle>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>20</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">0b71ae25-369e-4792-8763-f466e23effc0</guid>
      <title>Learn the Strategy Pattern</title>
      <description><![CDATA[<h1>Learn the Strategy Pattern</h1>
<p>The Strategy design pattern is one of the most fundamental and commonly-used patterns in modern object-oriented design. Take some time to make sure you're proficient with it.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>I'm continuing a small series of tips on <a href="(http://amzn.to/2DXVSJT)">design patterns</a> that I started with <a href="/017">episode 17</a>. I encourage you to listen to these tips in order, since in many cases they'll build on one another. This week I want to briefly describe the strategy pattern, and more importantly, why I think it's a pattern every object-oriented software developer should know.</p>
<p>The <a href="http://deviq.com/strategy-design-pattern/">strategy design pattern</a> is often applied as a refactoring technique to improve the design of some existing code. The original code likely has some tightly-coupled and/or complex logic in it that would be better off separated from the current implementation. I think one reason why I'm so fond of the strategy pattern is that it literally helps with every one of the SOLID principles of object-oriented design. In my <a href="http://bit.ly/SOLID-OOP">SOLID course on Pluralsight</a>, I also discuss the <a href="http://deviq.com/don-t-repeat-yourself/">Don't Repeat Yourself, or DRY, principle</a>, which strategy can help with as well. Let's look at how.</p>
<p>First, if you have a class that's doing too much (therefore breaking SRP - Single Responsibility Principle), common refactorings like extract method and move method can be used to pull logic out of one big method. However, if you then call this method from the big method, either statically or by directly instantiating a class to which you've moved the logic, you're not helping the coupling aspect of the problem. We'll get to that when we get to the 'D' in SOLID. Applying the strategy design pattern in this case is really just a slight twist on the usual extract and move method refactorings. You're still doing that, but you also typically create a new interface and pass in the interface to the original code. After moving the original implementation code to a new class that implements the new interface, you should have a new class that follows SRP and your original class should at least have fewer responsibilities.</p>
<p>Considering this refactoring I just described, it's easy to see how it can help with the Open/Closed principle, or OCP, too. Whereas the original code's complex logic would have needed modified and recompiled any time a change was requested, the new design can accommodate changes in the implementation of extracted method by writing new code that implements the same interface. Then, an instance of the new class that has this new implementation can be passed into the existing code without touching the existing code. I talked about how important this is with legacy code in episode 15.</p>
<p>Of course, if you do have multiple implementations of your abstract types, it's important that they all behave as advertised, otherwise you may encounter runtime exceptions. Ensuring that any implementation you write that inherits from another type, whether an interface or a class, means following the Liskov Substitution Principle, or LSP.</p>
<p>Following LSP is much easier when the base type's behavior is fairly small. Large interfaces require much more effort to fully implement that smaller ones. The Interface Segregation Principle, or ISP, suggests keeping interfaces small and cohesive, so that client code doesn't need to depend on behavior it doesn't use. Done properly, the interfaces you create while implementing the strategy design pattern should be tightly focused.</p>
<p>That brings us to the Dependency Inversion Principle, or DIP. This is really what the strategy pattern is all about. Whereas the initial code was tightly coupled to a specific implementation, the refactored version of the original method now depends on an abstraction. Instead of the original method deciding how to do the work, the code that calls the method makes that decision by deciding which implementation of the interface to provide. If you're familiar with dependency injection, then the strategy pattern should already be familiar to you. Make sure you're comfortable with pulling out dependencies when you discover them, though. The method extract and interface creation aspects of the strategy pattern aren't always emphasized when dependency injection is discussed.</p>
<p>We're out of time for this week but I'll mention that the strategy pattern also helps with the DRY principle by creating a single place for a particular implementation to live, as well as the <a href="http://deviq.com/explicit-dependencies-principle/">Explicit Dependencies Principle</a>, by ensuring classes request their dependencies rather than hiding them in their methods. You can learn more about these principles from the show notes at <a href="weeklydevtips.com/019">weeklydevtips.com/019</a>.</p>
<p><em>Would your team or application benefit from an application assessment, highlighting potential problem areas and identifying a path toward better maintainability? Contact me at <a href="https://ardalis.com/contact-us">ardalis.com</a> and let's see how I can help.</em></p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="http://deviq.com/strategy-design-pattern/">Strategy Pattern</a></li>
<li><a href="http://bit.ly/SOLID-OOP">SOLID Principles of OO Design</a> (Pluralsight)</li>
<li><a href="http://bit.ly/PS-Refactoring">Refactoring Fundamentals</a> (Pluralsight)</li>
<li><a href="http://deviq.com/don-t-repeat-yourself/">Don't Repeat Yourself (DRY)</a></li>
<li><a href="http://deviq.com/explicit-dependencies-principle/">Explicit Dependencies Principle</a></li>
<li><a href="http://amzn.to/2DXVSJT">Design Patterns</a> by Gamma, Helm, Johnson, Vlissides (Gang of Four)</li>
<li><a href="https://www.pluralsight.com/courses/patterns-library">Design Patterns Library</a> (Pluralsight)</li>
</ul>
]]></description>
      <pubDate>Mon, 26 Feb 2018 07:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h1>Learn the Strategy Pattern</h1>
<p>The Strategy design pattern is one of the most fundamental and commonly-used patterns in modern object-oriented design. Take some time to make sure you're proficient with it.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>I'm continuing a small series of tips on <a href="(http://amzn.to/2DXVSJT)">design patterns</a> that I started with <a href="/017">episode 17</a>. I encourage you to listen to these tips in order, since in many cases they'll build on one another. This week I want to briefly describe the strategy pattern, and more importantly, why I think it's a pattern every object-oriented software developer should know.</p>
<p>The <a href="http://deviq.com/strategy-design-pattern/">strategy design pattern</a> is often applied as a refactoring technique to improve the design of some existing code. The original code likely has some tightly-coupled and/or complex logic in it that would be better off separated from the current implementation. I think one reason why I'm so fond of the strategy pattern is that it literally helps with every one of the SOLID principles of object-oriented design. In my <a href="http://bit.ly/SOLID-OOP">SOLID course on Pluralsight</a>, I also discuss the <a href="http://deviq.com/don-t-repeat-yourself/">Don't Repeat Yourself, or DRY, principle</a>, which strategy can help with as well. Let's look at how.</p>
<p>First, if you have a class that's doing too much (therefore breaking SRP - Single Responsibility Principle), common refactorings like extract method and move method can be used to pull logic out of one big method. However, if you then call this method from the big method, either statically or by directly instantiating a class to which you've moved the logic, you're not helping the coupling aspect of the problem. We'll get to that when we get to the 'D' in SOLID. Applying the strategy design pattern in this case is really just a slight twist on the usual extract and move method refactorings. You're still doing that, but you also typically create a new interface and pass in the interface to the original code. After moving the original implementation code to a new class that implements the new interface, you should have a new class that follows SRP and your original class should at least have fewer responsibilities.</p>
<p>Considering this refactoring I just described, it's easy to see how it can help with the Open/Closed principle, or OCP, too. Whereas the original code's complex logic would have needed modified and recompiled any time a change was requested, the new design can accommodate changes in the implementation of extracted method by writing new code that implements the same interface. Then, an instance of the new class that has this new implementation can be passed into the existing code without touching the existing code. I talked about how important this is with legacy code in episode 15.</p>
<p>Of course, if you do have multiple implementations of your abstract types, it's important that they all behave as advertised, otherwise you may encounter runtime exceptions. Ensuring that any implementation you write that inherits from another type, whether an interface or a class, means following the Liskov Substitution Principle, or LSP.</p>
<p>Following LSP is much easier when the base type's behavior is fairly small. Large interfaces require much more effort to fully implement that smaller ones. The Interface Segregation Principle, or ISP, suggests keeping interfaces small and cohesive, so that client code doesn't need to depend on behavior it doesn't use. Done properly, the interfaces you create while implementing the strategy design pattern should be tightly focused.</p>
<p>That brings us to the Dependency Inversion Principle, or DIP. This is really what the strategy pattern is all about. Whereas the initial code was tightly coupled to a specific implementation, the refactored version of the original method now depends on an abstraction. Instead of the original method deciding how to do the work, the code that calls the method makes that decision by deciding which implementation of the interface to provide. If you're familiar with dependency injection, then the strategy pattern should already be familiar to you. Make sure you're comfortable with pulling out dependencies when you discover them, though. The method extract and interface creation aspects of the strategy pattern aren't always emphasized when dependency injection is discussed.</p>
<p>We're out of time for this week but I'll mention that the strategy pattern also helps with the DRY principle by creating a single place for a particular implementation to live, as well as the <a href="http://deviq.com/explicit-dependencies-principle/">Explicit Dependencies Principle</a>, by ensuring classes request their dependencies rather than hiding them in their methods. You can learn more about these principles from the show notes at <a href="weeklydevtips.com/019">weeklydevtips.com/019</a>.</p>
<p><em>Would your team or application benefit from an application assessment, highlighting potential problem areas and identifying a path toward better maintainability? Contact me at <a href="https://ardalis.com/contact-us">ardalis.com</a> and let's see how I can help.</em></p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="http://deviq.com/strategy-design-pattern/">Strategy Pattern</a></li>
<li><a href="http://bit.ly/SOLID-OOP">SOLID Principles of OO Design</a> (Pluralsight)</li>
<li><a href="http://bit.ly/PS-Refactoring">Refactoring Fundamentals</a> (Pluralsight)</li>
<li><a href="http://deviq.com/don-t-repeat-yourself/">Don't Repeat Yourself (DRY)</a></li>
<li><a href="http://deviq.com/explicit-dependencies-principle/">Explicit Dependencies Principle</a></li>
<li><a href="http://amzn.to/2DXVSJT">Design Patterns</a> by Gamma, Helm, Johnson, Vlissides (Gang of Four)</li>
<li><a href="https://www.pluralsight.com/courses/patterns-library">Design Patterns Library</a> (Pluralsight)</li>
</ul>
]]></content:encoded>
      <enclosure length="3513585" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/c4d42b24-6e93-4365-aced-ad481c4eb508/7392d55d_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Learn the Strategy Pattern</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/c4d42b24-6e93-4365-aced-ad481c4eb508/3000x3000/1519696934artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:05:35</itunes:duration>
      <itunes:summary>The Strategy design pattern is one of the most fundamental and commonly-used patterns in modern object-oriented design. Take some time to make sure you&apos;re proficient with it.</itunes:summary>
      <itunes:subtitle>The Strategy design pattern is one of the most fundamental and commonly-used patterns in modern object-oriented design. Take some time to make sure you&apos;re proficient with it.</itunes:subtitle>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>19</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">e36ef5eb-079d-49a2-a0a0-22abc746fb13</guid>
      <title>Repository Tip - Encapsulate Query Logic</title>
      <description><![CDATA[<h1>Repository Tip - Encapsulate Query Logic</h1>
<p>The Repository design pattern is one of the most popular patterns in .NET development today. However, depending on its specific implementation, its benefits to the system's design may vary. One thing to watch out for is query logic leaking out of the repository implementation.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>Last week I talked about Design Patterns in general, and how in most cases it makes sense to have basic familiarity with a breadth of patterns, but to go deep on the ones that are most valuable in your day-to-day development. Repository is one of a handful of patterns I've found to be useful in virtually every ASP.NET app I've been involved with over the last ten years or so. Before I knew about this pattern, I'd already learned that <a href="http://deviq.com/separation-of-concerns/">separation of concerns</a> was a good idea, and that having a separate layer or set of types for data access was beneficial. The biggest benefit you get by using a Repository instead of a Data Access Layer or static DB helper class is reduced coupling, because you can follow the <a href="http://deviq.com/dependency-inversion-principle/">Dependency Inversion Principle</a>. By the way, if you're not familiar with any of these terms or principles, there are links on the show notes page at <a href="http://weeklydevtips.com/018">weeklydevtips.com/018</a>, where you'll also find a link to my recommended <a href="http://deviq.com/repository-pattern/">generic repository implementation</a>.</p>
<p>This week's tip assumes you're already at least basically familiar with the repository pattern. Recently, I'm spending most of my time helping a variety of teams to write better software, and a pretty common issue I find for those app using the repository is that query logic can leak out. This can result in code and concept duplication, which violates the <a href="http://deviq.com/don-t-repeat-yourself/">Don't Repeat Yourself, or DRY, principle</a>. It can also result in runtime errors if query expressions are used that LINQ-to-Entities cannot translate into SQL.</p>
<p>The most common reason for this issue is repository <code>List</code> implementations that return back <code>IQueryable</code> results. An <code>IQueryable</code> result is an expression, not a true collection type. It can be enumerated, but until it is, the actual translation from the expression into a SQL query isn't performed. This is referred to as <em>deferred execution</em>, and it does have some advantages. For instance, if you have a repository method that returns a list of customers, and you only want those whose last name is 'Smith', it can dramatically reduce how much data you need to pull back from the database if you can apply the <code>LastName == Smith</code> filter before the database query is made.</p>
<p>But where are you going to add the query logic that says you only want customers named 'Smith'? That sort of thing is often done in the UI layer, perhaps in an MVC Controller action method. For something very simple, it's hard to see the harm in this. But imagine that instead of filtering for customers named 'Smith', you were instead writing a filter that would list the optimal customers to target for your next marketing campaign, using a variety of customer characteristics and perhaps some machine learning algorithms. Once you start putting your query logic in the UI, it's going to start to multiply, and you're going to have important business logic where it doesn't belong. This makes your business logic harder to isolate and test, and makes your UI layer bloated and harder to work with.</p>
<p>The problem with the <code>IQueryable</code> return type from repositories is that it invites this kind of thing. Developers find it easy to build complex filters using LINQ and lambda expressions, but rarely take the time to see whether they're reinventing the wheel with a particular query. The fact that this approach can easily be justified because of the benefits of deferred execution and perhaps the notion that the underlying repository <code>List</code> method is benefiting greatly from code reuse only exacerbates the problem. The underlying problem with returning <code>IQueryable</code> is that it breaks encapsulation and leaks data access responsiblities out of the repository abstraction where it belongs.</p>
<p>Rather than returning <code>IQueryable</code>, repositories should return <code>IEnumerable</code> or even just <code>List</code> types. Doing so consistently will ensure there is no confusion among developers as to whether the result of a repository is an in-memory result or an expression that can still be modified before a query is made. But then how do you allow for different kinds of queries, without performing them all in memory? There are a few different approaches that can work, and I'll cover them in future tips, but the simplest one is to add additional methods to the Repository as needed. This is often a good place to start, as it is simple and discoverable. In the example I'm using here, the <code>CustomerRepository</code> class could have a new method called <code>ListByLastName</code> added to it, which accepted a <code>lastName</code> parameter and returned all customers with that last name. Likewise, a collection of customers fitting certain characteristics for a new marketing campaign would be returned by another appropriately-named method. Over time, this may result in repositories with a lot of different methods, but this is preferable to having query logic scattered across the UI and possibly other parts of your application (and we'll see how to fix this soon).</p>
<p><em>Would your team or application benefit from an application assessment, highlighting potential problem areas and identifying a path toward better maintainability? Contact me at ardalis.com and let's see how I can help.</em></p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="http://deviq.com/repository-pattern/">Repository Pattern</a></li>
<li><a href="http://amzn.to/2DXVSJT">Design Patterns</a> by Gamma, Helm, Johnson, Vlissides (Gang of Four)</li>
<li><a href="http://bit.ly/ddd-fundamentals">Domain-Driven Design Fundamentals</a> (Pluralsight)</li>
<li><a href="https://www.pluralsight.com/courses/patterns-library">Design Patterns Library</a> (Pluralsight)</li>
</ul>
]]></description>
      <pubDate>Mon, 19 Feb 2018 07:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h1>Repository Tip - Encapsulate Query Logic</h1>
<p>The Repository design pattern is one of the most popular patterns in .NET development today. However, depending on its specific implementation, its benefits to the system's design may vary. One thing to watch out for is query logic leaking out of the repository implementation.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>Last week I talked about Design Patterns in general, and how in most cases it makes sense to have basic familiarity with a breadth of patterns, but to go deep on the ones that are most valuable in your day-to-day development. Repository is one of a handful of patterns I've found to be useful in virtually every ASP.NET app I've been involved with over the last ten years or so. Before I knew about this pattern, I'd already learned that <a href="http://deviq.com/separation-of-concerns/">separation of concerns</a> was a good idea, and that having a separate layer or set of types for data access was beneficial. The biggest benefit you get by using a Repository instead of a Data Access Layer or static DB helper class is reduced coupling, because you can follow the <a href="http://deviq.com/dependency-inversion-principle/">Dependency Inversion Principle</a>. By the way, if you're not familiar with any of these terms or principles, there are links on the show notes page at <a href="http://weeklydevtips.com/018">weeklydevtips.com/018</a>, where you'll also find a link to my recommended <a href="http://deviq.com/repository-pattern/">generic repository implementation</a>.</p>
<p>This week's tip assumes you're already at least basically familiar with the repository pattern. Recently, I'm spending most of my time helping a variety of teams to write better software, and a pretty common issue I find for those app using the repository is that query logic can leak out. This can result in code and concept duplication, which violates the <a href="http://deviq.com/don-t-repeat-yourself/">Don't Repeat Yourself, or DRY, principle</a>. It can also result in runtime errors if query expressions are used that LINQ-to-Entities cannot translate into SQL.</p>
<p>The most common reason for this issue is repository <code>List</code> implementations that return back <code>IQueryable</code> results. An <code>IQueryable</code> result is an expression, not a true collection type. It can be enumerated, but until it is, the actual translation from the expression into a SQL query isn't performed. This is referred to as <em>deferred execution</em>, and it does have some advantages. For instance, if you have a repository method that returns a list of customers, and you only want those whose last name is 'Smith', it can dramatically reduce how much data you need to pull back from the database if you can apply the <code>LastName == Smith</code> filter before the database query is made.</p>
<p>But where are you going to add the query logic that says you only want customers named 'Smith'? That sort of thing is often done in the UI layer, perhaps in an MVC Controller action method. For something very simple, it's hard to see the harm in this. But imagine that instead of filtering for customers named 'Smith', you were instead writing a filter that would list the optimal customers to target for your next marketing campaign, using a variety of customer characteristics and perhaps some machine learning algorithms. Once you start putting your query logic in the UI, it's going to start to multiply, and you're going to have important business logic where it doesn't belong. This makes your business logic harder to isolate and test, and makes your UI layer bloated and harder to work with.</p>
<p>The problem with the <code>IQueryable</code> return type from repositories is that it invites this kind of thing. Developers find it easy to build complex filters using LINQ and lambda expressions, but rarely take the time to see whether they're reinventing the wheel with a particular query. The fact that this approach can easily be justified because of the benefits of deferred execution and perhaps the notion that the underlying repository <code>List</code> method is benefiting greatly from code reuse only exacerbates the problem. The underlying problem with returning <code>IQueryable</code> is that it breaks encapsulation and leaks data access responsiblities out of the repository abstraction where it belongs.</p>
<p>Rather than returning <code>IQueryable</code>, repositories should return <code>IEnumerable</code> or even just <code>List</code> types. Doing so consistently will ensure there is no confusion among developers as to whether the result of a repository is an in-memory result or an expression that can still be modified before a query is made. But then how do you allow for different kinds of queries, without performing them all in memory? There are a few different approaches that can work, and I'll cover them in future tips, but the simplest one is to add additional methods to the Repository as needed. This is often a good place to start, as it is simple and discoverable. In the example I'm using here, the <code>CustomerRepository</code> class could have a new method called <code>ListByLastName</code> added to it, which accepted a <code>lastName</code> parameter and returned all customers with that last name. Likewise, a collection of customers fitting certain characteristics for a new marketing campaign would be returned by another appropriately-named method. Over time, this may result in repositories with a lot of different methods, but this is preferable to having query logic scattered across the UI and possibly other parts of your application (and we'll see how to fix this soon).</p>
<p><em>Would your team or application benefit from an application assessment, highlighting potential problem areas and identifying a path toward better maintainability? Contact me at ardalis.com and let's see how I can help.</em></p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="http://deviq.com/repository-pattern/">Repository Pattern</a></li>
<li><a href="http://amzn.to/2DXVSJT">Design Patterns</a> by Gamma, Helm, Johnson, Vlissides (Gang of Four)</li>
<li><a href="http://bit.ly/ddd-fundamentals">Domain-Driven Design Fundamentals</a> (Pluralsight)</li>
<li><a href="https://www.pluralsight.com/courses/patterns-library">Design Patterns Library</a> (Pluralsight)</li>
</ul>
]]></content:encoded>
      <enclosure length="4310643" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/b0de9b11-4597-49c9-a4f7-af20afa179e6/933bf9dc_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Repository Tip - Encapsulate Query Logic</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/b0de9b11-4597-49c9-a4f7-af20afa179e6/3000x3000/1518796071artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:09:08</itunes:duration>
      <itunes:summary>The Repository design pattern is one of the most popular patterns in .NET development today. However, depending on its specific implementation, its benefits to the system&apos;s design may vary. One thing to watch out for is query logic leaking out of the repository implementation.</itunes:summary>
      <itunes:subtitle>The Repository design pattern is one of the most popular patterns in .NET development today. However, depending on its specific implementation, its benefits to the system&apos;s design may vary. One thing to watch out for is query logic leaking out of the repository implementation.</itunes:subtitle>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>18</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">0facf527-b292-422f-abbc-9d5c26c1bcdd</guid>
      <title>On Design Patterns</title>
      <description><![CDATA[<h1>On Design Patterns</h1>
<p>Design Patterns offer well-known, proven approaches to common problems or situations in software application development. Having a broad knowledge of the existence of patterns, and at least a few you're proficient in, can dramatically improve your productivity.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>I'll admit I've been a fan of design patterns for a long time. The idea of design patterns transcends software development, and in fact the so-called Gang of Four book, <a href="http://amzn.to/2DXVSJT">Design Patterns</a>, takes its organization and inspiration from the 1977 book, <a href="http://amzn.to/2GF4RRE">A Pattern Language</a>. That book, by Christpher Alexander, describes common patterns in towns, buildings, and construction methods, but the idea that there are common patterns to solving similar problems applies equally to software as well as traditional building construction and architecture.</p>
<p>One thing that really appeals to me about design patterns is their ability to reduce waste. As software developers, we tend to want to increase efficiency and productivity, and one of the most frustrating parts of writing software (for me, at least) is when I'm stuck on a problem. This frustration is even greater when it's a problem I feel like I should know the answer to, or that I know is relatively common, so <em>someone</em> has solved it before. Design patterns are a great way to help you avoid reinventing the wheel (or, in many cases, a giant square that you're hoping will work as a wheel).</p>
<p>Unfortunately, you can't always use your usual search engine skills to come up with a design pattern. You usually have to at least be aware that it exists so that you can start to recognize scenarios where it might apply. Once you know that a pattern exists, and have at least a vague sense of when it's used, then you can easily search for more information on how to apply the pattern when you think you might have a situation that warrants it. Thus, the first step in your path to pattern mastery is exposure. You need to spend at least a little bit of time learning the names of the patterns that exist, and where they're used.</p>
<p>If you haven't already, you'll probably find a few design patterns that you use all the time. You can go deep in your knowledge of how and when to use these patterns. Last week, I talked about <a href="/016">becoming a T-shaped developer</a> as a means of differentiating yourself among competitors. Your knowledge of design patterns should have a similar T-shape, but for different reasons. You want the wide breadth of knowledge so you can speak intelligently about patterns and know what terms to search for when you want to go deep. But many patterns have fairly specific uses, so there's no need for you to try and become an expert in all of them if you're not solving the kinds of problems for which some patterns are designed.</p>
<p>I'm sure I'll have more tips about design patterns in upcoming shows, but one last reason why you owe it to yourself to gain at least a cursory knowledge of them is their value as a higher level language tool. When you know a design pattern by name, and how and why one would use it, you can discuss possible solutions with your team in a far more efficient and clear manner. The actual implementation of many patterns can involve several different types organized in a particular fashion, usually with specific inheritance or composition relationships. How these types are used by your system is another aspect of the pattern's implementation. Without knowing the pattern and its name, communicating a proposed solution to another developer would require describe at least most of this detail. However, if both developers are familiar with the pattern in question, one can simply say to the other, &quot;have you thought about applying the XYZ pattern here?&quot; and convey the same intent with less chance for confusion and with fewer words.</p>
<p>If you want to learn more about design patterns, I recommend the Design Pattern Library on Pluralsight as a good place to start. You can also reach out to me if you think your team would benefit from a private workshop on design patterns.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="http://amzn.to/2DXVSJT">Design Patterns</a> by Gamma, Helm, Johnson, Vlissides (Gang of Four)</li>
<li><a href="http://amzn.to/2GF4RRE">A Pattern Language</a> by Christopher Alexander</li>
<li><a href="https://www.pluralsight.com/courses/patterns-library">Design Patterns Library</a> (Pluralsight)</li>
</ul>
]]></description>
      <pubDate>Mon, 5 Feb 2018 07:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h1>On Design Patterns</h1>
<p>Design Patterns offer well-known, proven approaches to common problems or situations in software application development. Having a broad knowledge of the existence of patterns, and at least a few you're proficient in, can dramatically improve your productivity.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>I'll admit I've been a fan of design patterns for a long time. The idea of design patterns transcends software development, and in fact the so-called Gang of Four book, <a href="http://amzn.to/2DXVSJT">Design Patterns</a>, takes its organization and inspiration from the 1977 book, <a href="http://amzn.to/2GF4RRE">A Pattern Language</a>. That book, by Christpher Alexander, describes common patterns in towns, buildings, and construction methods, but the idea that there are common patterns to solving similar problems applies equally to software as well as traditional building construction and architecture.</p>
<p>One thing that really appeals to me about design patterns is their ability to reduce waste. As software developers, we tend to want to increase efficiency and productivity, and one of the most frustrating parts of writing software (for me, at least) is when I'm stuck on a problem. This frustration is even greater when it's a problem I feel like I should know the answer to, or that I know is relatively common, so <em>someone</em> has solved it before. Design patterns are a great way to help you avoid reinventing the wheel (or, in many cases, a giant square that you're hoping will work as a wheel).</p>
<p>Unfortunately, you can't always use your usual search engine skills to come up with a design pattern. You usually have to at least be aware that it exists so that you can start to recognize scenarios where it might apply. Once you know that a pattern exists, and have at least a vague sense of when it's used, then you can easily search for more information on how to apply the pattern when you think you might have a situation that warrants it. Thus, the first step in your path to pattern mastery is exposure. You need to spend at least a little bit of time learning the names of the patterns that exist, and where they're used.</p>
<p>If you haven't already, you'll probably find a few design patterns that you use all the time. You can go deep in your knowledge of how and when to use these patterns. Last week, I talked about <a href="/016">becoming a T-shaped developer</a> as a means of differentiating yourself among competitors. Your knowledge of design patterns should have a similar T-shape, but for different reasons. You want the wide breadth of knowledge so you can speak intelligently about patterns and know what terms to search for when you want to go deep. But many patterns have fairly specific uses, so there's no need for you to try and become an expert in all of them if you're not solving the kinds of problems for which some patterns are designed.</p>
<p>I'm sure I'll have more tips about design patterns in upcoming shows, but one last reason why you owe it to yourself to gain at least a cursory knowledge of them is their value as a higher level language tool. When you know a design pattern by name, and how and why one would use it, you can discuss possible solutions with your team in a far more efficient and clear manner. The actual implementation of many patterns can involve several different types organized in a particular fashion, usually with specific inheritance or composition relationships. How these types are used by your system is another aspect of the pattern's implementation. Without knowing the pattern and its name, communicating a proposed solution to another developer would require describe at least most of this detail. However, if both developers are familiar with the pattern in question, one can simply say to the other, &quot;have you thought about applying the XYZ pattern here?&quot; and convey the same intent with less chance for confusion and with fewer words.</p>
<p>If you want to learn more about design patterns, I recommend the Design Pattern Library on Pluralsight as a good place to start. You can also reach out to me if you think your team would benefit from a private workshop on design patterns.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="http://amzn.to/2DXVSJT">Design Patterns</a> by Gamma, Helm, Johnson, Vlissides (Gang of Four)</li>
<li><a href="http://amzn.to/2GF4RRE">A Pattern Language</a> by Christopher Alexander</li>
<li><a href="https://www.pluralsight.com/courses/patterns-library">Design Patterns Library</a> (Pluralsight)</li>
</ul>
]]></content:encoded>
      <enclosure length="3102722" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/db3c60c2-d673-45cf-9c70-cc5baf05c959/7ed71f38_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>On Design Patterns</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/db3c60c2-d673-45cf-9c70-cc5baf05c959/3000x3000/1517927784artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:04:32</itunes:duration>
      <itunes:summary>Design Patterns offer well-known, proven approaches to common problems or situations in software application development. Having a broad knowledge of the existence of patterns, and at least a few you&apos;re proficient in, can dramatically improve your productivity.</itunes:summary>
      <itunes:subtitle>Design Patterns offer well-known, proven approaches to common problems or situations in software application development. Having a broad knowledge of the existence of patterns, and at least a few you&apos;re proficient in, can dramatically improve your productivity.</itunes:subtitle>
      <itunes:keywords>software development, coding, design patterns, clean code, programming, testing, debugging</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>17</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">2b355dda-d003-4040-b446-7d4807324789</guid>
      <title>Becoming a T-Shaped Developer</title>
      <description><![CDATA[<h1>Becoming a T-Shaped Developer</h1>
<p>It's difficult to differentiate yourself if you don't have a single area of expertise. Either you'll have difficulty landing work or you'll be forced to compete with a host of other non-specialists on rate. By becoming a T-shaped developer, you can market yourself as an expert in a particular area and stand out from the crowd!</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>In this episode, I'm going to talk about what it means to be a &quot;T-Shaped&quot; developer. But before we get into that, let's talk a little bit about how software developers typically market themselves, and how companies post job openings, using some real data and numbers. Let's consider a pretty common, but vague, job description: &quot;web developer&quot;. Let's search for jobs using this term on a few different sites. We'll leave location out of the search - remote work is becoming increasingly acceptable and it's just easier to compare numbers if we don't restrict by location. Looking at Indeed.com, there are 40,000 jobs matching this search string. LinkedIn's Job Search has over 14,000. GlassDoor finds 110,000. Monster.com will only tell us there were over 1000 results found, but it's a good guess it was a lot more than 1000. The point is, there are a huge number of positions out there that match the search term (or exact job title) of 'web developer'. If you identify primarily as simply a 'web developer', you're in a crowd of hundreds of thousands. The good news is, there's definitely demand for people to fill that kind of role. The bad news is, how do you convince a particular client that you're the best candidate for their 'web developer' vacancy, if that's as far as you've gone in differentiating yourself?</p>
<p>When you're marketing a product, one that isn't creating a brand new market segment, it can be useful to identify how big the market for that kind of product is. Say you're looking to enter the footwear business. It's good to know that there are billions of dollars spent by millions of customers on footwear every year. However, when you go to actually sell your footwear, you're probably not going to try to market it to &quot;people who buy shoes&quot; - you're going to niche down to a particular segment. Maybe basketball playing teens who aspire to be NBA players. Maybe outdoor fanatics who want the best hiking shoes. Maybe fashion-conscious women who will pay a premium for comfort. You'll sell more shoes by appealing to specific demographics of buyers than by trying to appeal broadly to any shoe-buyer. People can only remember one or two leaders in a given market niche, and as a marketer you want your product to occupy one of those positions. If you can't be the #1 or #2 for the market, you need to pick a smaller, more focused market in which you can occupy that position.</p>
<p>Think about it for automobile companies. What's the most successful automobile company? In my opinion there's not even a clear winner here. What if we narrow it down to trucks? Many of you would probably say Ford or Chevrolet. How about electric cars? I would argue Tesla has done an excellent job of being first in mind as the electric car manufacturer, even though last year Nissan sold more electric vehicles globally than did Tesla.</p>
<p>As a developer, you are the product you're trying to sell. You have a set of skills and experience that you can bring to bear when presented with a problem. There are a wide number of skills that most developers need to know, but don't need to be expert in. Visualize a horizontal line representing the breadth of skills you have. Now make the line thicker at the bottom by a few units to represent the relatively shallow depth of knowledge you have for most skills. You work with source control, but you're not known throughout the industry for your source control skills. You can apply CSS to HTML, but you're not writing books about how to apply CSS to HTML. You're competent with C#, or JavaScript, or PHP, but again you're not a well-known expert in them.</p>
<p>Now think about a particular skill or passion you have that goes beyond mere competence. Maybe you could have a podcast all about your git knowledge and the dark arts of mastering its intricacies. Maybe you could write a book about the most powerful ways to use CSS selectors to achieve amazing results. Whole programming languages might be tough to become well-known for (think Jon Skeet for C# for example), but you could position yourself as the go-to expert in lambda expressions or arrow functions or a particular design pattern. Whatever skill you already have, or could have, that's where you're going to go deep with your knowledge. Visualize that thick horizontal line representing your shallow knowledge of a wide variety of topics, and now draw a much deeper vertical line dropping down from its center, forming a 'T' shape. This T-shape represents your skillset, or at least how you'd like to market your skillset.</p>
<p>The T-shaped developer has greater success because they're able to position themselves in the minds of customers, managers, and peers as experts in a particular niche. How you choose your niche and how you make sure others are aware of your expertise will have to wait for future shows. Please leave a comment at weeklydevtips.com/016 if you have questions or ideas you'd like to share.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="http://amzn.to/2DNccjv">Positioning - The Battle for Your Mind (book)</a></li>
<li><a href="https://www.forbes.com/sites/bertelschmitt/2017/05/01/who-is-the-worlds-leading-ev-marker-no-its-not-tesla/#3267b30d3912">Tesla vs Nissan</a></li>
<li><a href="https://codeblog.jonskeet.uk/">Jon Skeet - C#</a></li>
<li><a href="https://ardalis.com/tag/career">More Career Advice Articles</a></li>
</ul>
]]></description>
      <pubDate>Mon, 29 Jan 2018 07:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h1>Becoming a T-Shaped Developer</h1>
<p>It's difficult to differentiate yourself if you don't have a single area of expertise. Either you'll have difficulty landing work or you'll be forced to compete with a host of other non-specialists on rate. By becoming a T-shaped developer, you can market yourself as an expert in a particular area and stand out from the crowd!</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>In this episode, I'm going to talk about what it means to be a &quot;T-Shaped&quot; developer. But before we get into that, let's talk a little bit about how software developers typically market themselves, and how companies post job openings, using some real data and numbers. Let's consider a pretty common, but vague, job description: &quot;web developer&quot;. Let's search for jobs using this term on a few different sites. We'll leave location out of the search - remote work is becoming increasingly acceptable and it's just easier to compare numbers if we don't restrict by location. Looking at Indeed.com, there are 40,000 jobs matching this search string. LinkedIn's Job Search has over 14,000. GlassDoor finds 110,000. Monster.com will only tell us there were over 1000 results found, but it's a good guess it was a lot more than 1000. The point is, there are a huge number of positions out there that match the search term (or exact job title) of 'web developer'. If you identify primarily as simply a 'web developer', you're in a crowd of hundreds of thousands. The good news is, there's definitely demand for people to fill that kind of role. The bad news is, how do you convince a particular client that you're the best candidate for their 'web developer' vacancy, if that's as far as you've gone in differentiating yourself?</p>
<p>When you're marketing a product, one that isn't creating a brand new market segment, it can be useful to identify how big the market for that kind of product is. Say you're looking to enter the footwear business. It's good to know that there are billions of dollars spent by millions of customers on footwear every year. However, when you go to actually sell your footwear, you're probably not going to try to market it to &quot;people who buy shoes&quot; - you're going to niche down to a particular segment. Maybe basketball playing teens who aspire to be NBA players. Maybe outdoor fanatics who want the best hiking shoes. Maybe fashion-conscious women who will pay a premium for comfort. You'll sell more shoes by appealing to specific demographics of buyers than by trying to appeal broadly to any shoe-buyer. People can only remember one or two leaders in a given market niche, and as a marketer you want your product to occupy one of those positions. If you can't be the #1 or #2 for the market, you need to pick a smaller, more focused market in which you can occupy that position.</p>
<p>Think about it for automobile companies. What's the most successful automobile company? In my opinion there's not even a clear winner here. What if we narrow it down to trucks? Many of you would probably say Ford or Chevrolet. How about electric cars? I would argue Tesla has done an excellent job of being first in mind as the electric car manufacturer, even though last year Nissan sold more electric vehicles globally than did Tesla.</p>
<p>As a developer, you are the product you're trying to sell. You have a set of skills and experience that you can bring to bear when presented with a problem. There are a wide number of skills that most developers need to know, but don't need to be expert in. Visualize a horizontal line representing the breadth of skills you have. Now make the line thicker at the bottom by a few units to represent the relatively shallow depth of knowledge you have for most skills. You work with source control, but you're not known throughout the industry for your source control skills. You can apply CSS to HTML, but you're not writing books about how to apply CSS to HTML. You're competent with C#, or JavaScript, or PHP, but again you're not a well-known expert in them.</p>
<p>Now think about a particular skill or passion you have that goes beyond mere competence. Maybe you could have a podcast all about your git knowledge and the dark arts of mastering its intricacies. Maybe you could write a book about the most powerful ways to use CSS selectors to achieve amazing results. Whole programming languages might be tough to become well-known for (think Jon Skeet for C# for example), but you could position yourself as the go-to expert in lambda expressions or arrow functions or a particular design pattern. Whatever skill you already have, or could have, that's where you're going to go deep with your knowledge. Visualize that thick horizontal line representing your shallow knowledge of a wide variety of topics, and now draw a much deeper vertical line dropping down from its center, forming a 'T' shape. This T-shape represents your skillset, or at least how you'd like to market your skillset.</p>
<p>The T-shaped developer has greater success because they're able to position themselves in the minds of customers, managers, and peers as experts in a particular niche. How you choose your niche and how you make sure others are aware of your expertise will have to wait for future shows. Please leave a comment at weeklydevtips.com/016 if you have questions or ideas you'd like to share.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="http://amzn.to/2DNccjv">Positioning - The Battle for Your Mind (book)</a></li>
<li><a href="https://www.forbes.com/sites/bertelschmitt/2017/05/01/who-is-the-worlds-leading-ev-marker-no-its-not-tesla/#3267b30d3912">Tesla vs Nissan</a></li>
<li><a href="https://codeblog.jonskeet.uk/">Jon Skeet - C#</a></li>
<li><a href="https://ardalis.com/tag/career">More Career Advice Articles</a></li>
</ul>
]]></content:encoded>
      <enclosure length="3770390" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/61cd97fd-5981-4a50-b13a-e39a13eeba78/7d326014_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Becoming a T-Shaped Developer</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/61cd97fd-5981-4a50-b13a-e39a13eeba78/3000x3000/1516976953artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:05:20</itunes:duration>
      <itunes:summary>It&apos;s difficult to differentiate yourself if you don&apos;t have a single area of expertise. Either you&apos;ll have difficulty landing work or you&apos;ll be forced to compete with a host of other non-specialists on rate. By becoming a T-shaped developer, you can market yourself as an expert in a particular area and stand out from the crowd!</itunes:summary>
      <itunes:subtitle>It&apos;s difficult to differentiate yourself if you don&apos;t have a single area of expertise. Either you&apos;ll have difficulty landing work or you&apos;ll be forced to compete with a host of other non-specialists on rate. By becoming a T-shaped developer, you can market yourself as an expert in a particular area and stand out from the crowd!</itunes:subtitle>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>16</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">84956693-2e0f-4948-938c-e5b49ca3907a</guid>
      <title>Maintain Legacy Code with New Code</title>
      <description><![CDATA[<h1>Maintain Legacy Code with New Code</h1><p>Many developers work in legacy codebases, which are notoriously difficult to test and maintain in many cases. One way you can address these issues is by trying to maximize the use of new, better designed constructs in the code you add to the system.</p><h2>Sponsor - DevIQ</h2><p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p><h2>Show Notes / Transcript</h2><p>Legacy code can be difficult to work with. Michael Feathers defines legacy code in his book, <a href="http://amzn.to/2CYWqPJ">Working Effectively with Legacy Code</a>, as "code without tests", and frequently it's true that legacy codebases are difficult to test. They're often tightly coupled, overly complex, and weren't written with modern understanding of good design principles in mind. Whether you're working with a legacy codebase you've inherited, or one you wrote yourself over some period of time, you probably have experienced the pain that can be involved with trying to change a large, complex system that suffers from a fair bit of <a href="http://deviq.com/technical-debt/">technical debt</a> and lacks the safety net of tests.</p><p>There are several common approaches to working with such codebases. One simple approach, that can be appropriate in many scenarios, is to do as little as possible to the code. The business is running on it, none of the original authors are still with the company, nobody understands it, so just keep your distance and hope it doesn't break on your watch. Maybe in the meantime someone is working on a replacement, but you have no idea if or when that might ever ship, and anyway you have other things you need to work on that are less likely to keep you at work late or bring you in on the weekends. I don't have any solid numbers on how much software falls into this category, but I suspect it's a lot.</p><p>The second approach is also common, and usually takes place when the first one isn't an option because business requirements won't wait for a rewrite of the current system. In this case, developers must spend time working with the legacy system in order to add or change functionality. Because it's big, complex, and probably untestable, changes and deployments are stressful and error-prone, and a lot of manual testing effort is required. Regression bugs are common, as tight coupling within the system means changes in one area affect others areas in often inexplicable and unpredictable ways. This is where I think the largest amount of maintenance software development takes place, since let's face it most software running today was written without tests but still needs to be updated to meet changing business needs.</p><p>A third approach some forward-thinking companies take, understanding the risks and costs involved in full application rewrites, is to invest in <a href="http://bit.ly/PS-Refactoring">refactoring</a> the legacy system to improve its quality. This can take the place of dedicated effort focused on refactoring, as opposed to adding features or fixing bugs. Or it can be a commitment to follow the <a href="http://deviq.com/boy-scout-rule/">Boy Scout Rule</a> such that every new change to the system also improves the system's quality by improving its design (and, ideally, adding tests). Some initial steps teams often take when adopting this approach are to ensure source control is being used effectively and to set up a continuous integration server if none is in place. An initial assessment using static analysis tools can establish the baseline quality metrics for the application, and the build server can track these heuristics to help the team measure progress over time. This approach works well for systems that are mission-critical and aren't yet so far gone into technical debt that it's better to just declare "technical bankruptcy" and rewrite them. I've had success working with several companies using this approach - let me know if you have questions about how to do it with your application.</p><p>Now let's stop for a moment and think about why working with legacy code is so expensive and stressful. Yes, there's the lack of tests which limits our confidence that changes to the code don't break things unintentionally, but that's based on a root assumption. The assumption is that we're <i>changing existing code</i> and therefore, other code that depends on it might break unexpectedly. What if we break down that assumption, and instead we minimize the amount of existing code we touch in favor of writing new code. Yes, there's still some risk that our changes to allow incorporating our new code might cause problems, but outside of that, we're able to operate in the liberating zone of green field development, at least on a small scale.</p><p>When I say write new code, I don't mean go into a method, add a new if statement or else clause, and start writing new statements in that method. That's the traditional approach that tends to increase complexity and technical debt. What I'm proposing instead is that you write new <i>classes</i>. You put new functionality into types and methods that <strong>didn't exist before</strong>. Since you're writing brand new classes, you know that no other code in the system currently has any dependencies on the code you're writing. You're also free to unit test your new classes and methods, since you're able to write them in a way that ensures they're loosely coupled and follow <a href="http://bit.ly/SOLID-OOP">SOLID principles</a>.</p><p>So, what does this look like in practice? Frequently, the first step will be some kind of refactoring in order to accommodate the use of a new class. Let's you've identified a big, complex method that currently does the work that you need to change, and in a certain case you need it to do something different. Your de facto approach would be to dive into the nested conditional statements, find the right place to add an <code>else</code> clause, and add the new behavior there. The alternative approach would be to put the new behavior into a new method, ideally in a new type so that it's completely separate from any existing structures. A very basic first step could be to do exactly what you were going to do, but instead of putting the actual code into the else clause, instantiate your new type and call your new method there instead, passing any parameters it might require. This works well if what you're adding is fairly complex, since now you have a much easier way to test that complex code rather than going through an already big and complex method to get to it.</p><p>Depending on the conditions that dictate when your new behavior should run, you might be able to get out of using the existing big complex method at all. Let's say the existing method is called <code>BigMethod</code>. Move <code>BigMethod</code> into a new class called <code>Original</code> and wherever you had code calling <code>BigMethod</code> change it to call <code>new Original().BigMethod()</code>. This is one of those cases where you're forced to change the existing code in order to prepare it for your new code, so you'll want to be very careful and do a lot of testing. If there are a lot of global or static dependencies running through <code>BigMethod</code>, this approach might not work well, so keep that in mind. However, assuming you're able to pull <code>BigMethod</code> into its own class that you then call as needed, the next step is to create another new class for your new implementation. We'll call the new class <code>BetterDesign</code> and we'll keep the method named <code>BigMethod</code> for now so that if we want we can use polymorphism via inheritance or an interface. Copy <code>BigMethod</code> from the <code>Original</code> class to your <code>BetterDesign</code> class and modify it so it <strong>only does what your new requirements need</strong>. It should be much smaller and simpler than what's in <code>Original</code>. Now, find all the places where you're instantiating <code>Original</code> and put in a conditional statement there so you'll instantiate <code>BetterDesign</code> instead, in the appropriate circumstances. At this point you should be able to add the behavior you need, in a new and testable class, without breaking anything that previously depended on <code>BigMethod</code>. If you have more than a few places where you need to decide whether to create <code>Original</code> or <code>BetterDesign</code>, look at using the Factory design pattern.</p><p>By adjusting the way we maintain legacy systems to maximize how much new behavior we add through new classes and methods, we can minimize the likelihood of introducing regressions. This improves the code quality over time, increases team productivity, and makes the code more enjoyable to work with. If you have experience working with legacy code, please share it in this show's comments at <a href="/015">www.weeklydevtips.com/015</a>.</p><h2>Show Resources and Links</h2><ul><li><a href="https://amzn.to/2CYWqPJ">Working Effectively with Legacy Code</a></li><li><a href="https://deviq.com/technical-debt/">Technical Debt</a></li><li><a href="https://www.pluralsight.com/courses/refactoring-csharp-developers">Refactoring</a></li><li><a href="https://deviq.com/boy-scout-rule/">Boy Scout Rule</a></li><li><a href="https://www.pluralsight.com/courses/csharp-solid-principles">SOLID Principles</a></li></ul>
]]></description>
      <pubDate>Mon, 8 Jan 2018 07:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h1>Maintain Legacy Code with New Code</h1><p>Many developers work in legacy codebases, which are notoriously difficult to test and maintain in many cases. One way you can address these issues is by trying to maximize the use of new, better designed constructs in the code you add to the system.</p><h2>Sponsor - DevIQ</h2><p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p><h2>Show Notes / Transcript</h2><p>Legacy code can be difficult to work with. Michael Feathers defines legacy code in his book, <a href="http://amzn.to/2CYWqPJ">Working Effectively with Legacy Code</a>, as "code without tests", and frequently it's true that legacy codebases are difficult to test. They're often tightly coupled, overly complex, and weren't written with modern understanding of good design principles in mind. Whether you're working with a legacy codebase you've inherited, or one you wrote yourself over some period of time, you probably have experienced the pain that can be involved with trying to change a large, complex system that suffers from a fair bit of <a href="http://deviq.com/technical-debt/">technical debt</a> and lacks the safety net of tests.</p><p>There are several common approaches to working with such codebases. One simple approach, that can be appropriate in many scenarios, is to do as little as possible to the code. The business is running on it, none of the original authors are still with the company, nobody understands it, so just keep your distance and hope it doesn't break on your watch. Maybe in the meantime someone is working on a replacement, but you have no idea if or when that might ever ship, and anyway you have other things you need to work on that are less likely to keep you at work late or bring you in on the weekends. I don't have any solid numbers on how much software falls into this category, but I suspect it's a lot.</p><p>The second approach is also common, and usually takes place when the first one isn't an option because business requirements won't wait for a rewrite of the current system. In this case, developers must spend time working with the legacy system in order to add or change functionality. Because it's big, complex, and probably untestable, changes and deployments are stressful and error-prone, and a lot of manual testing effort is required. Regression bugs are common, as tight coupling within the system means changes in one area affect others areas in often inexplicable and unpredictable ways. This is where I think the largest amount of maintenance software development takes place, since let's face it most software running today was written without tests but still needs to be updated to meet changing business needs.</p><p>A third approach some forward-thinking companies take, understanding the risks and costs involved in full application rewrites, is to invest in <a href="http://bit.ly/PS-Refactoring">refactoring</a> the legacy system to improve its quality. This can take the place of dedicated effort focused on refactoring, as opposed to adding features or fixing bugs. Or it can be a commitment to follow the <a href="http://deviq.com/boy-scout-rule/">Boy Scout Rule</a> such that every new change to the system also improves the system's quality by improving its design (and, ideally, adding tests). Some initial steps teams often take when adopting this approach are to ensure source control is being used effectively and to set up a continuous integration server if none is in place. An initial assessment using static analysis tools can establish the baseline quality metrics for the application, and the build server can track these heuristics to help the team measure progress over time. This approach works well for systems that are mission-critical and aren't yet so far gone into technical debt that it's better to just declare "technical bankruptcy" and rewrite them. I've had success working with several companies using this approach - let me know if you have questions about how to do it with your application.</p><p>Now let's stop for a moment and think about why working with legacy code is so expensive and stressful. Yes, there's the lack of tests which limits our confidence that changes to the code don't break things unintentionally, but that's based on a root assumption. The assumption is that we're <i>changing existing code</i> and therefore, other code that depends on it might break unexpectedly. What if we break down that assumption, and instead we minimize the amount of existing code we touch in favor of writing new code. Yes, there's still some risk that our changes to allow incorporating our new code might cause problems, but outside of that, we're able to operate in the liberating zone of green field development, at least on a small scale.</p><p>When I say write new code, I don't mean go into a method, add a new if statement or else clause, and start writing new statements in that method. That's the traditional approach that tends to increase complexity and technical debt. What I'm proposing instead is that you write new <i>classes</i>. You put new functionality into types and methods that <strong>didn't exist before</strong>. Since you're writing brand new classes, you know that no other code in the system currently has any dependencies on the code you're writing. You're also free to unit test your new classes and methods, since you're able to write them in a way that ensures they're loosely coupled and follow <a href="http://bit.ly/SOLID-OOP">SOLID principles</a>.</p><p>So, what does this look like in practice? Frequently, the first step will be some kind of refactoring in order to accommodate the use of a new class. Let's you've identified a big, complex method that currently does the work that you need to change, and in a certain case you need it to do something different. Your de facto approach would be to dive into the nested conditional statements, find the right place to add an <code>else</code> clause, and add the new behavior there. The alternative approach would be to put the new behavior into a new method, ideally in a new type so that it's completely separate from any existing structures. A very basic first step could be to do exactly what you were going to do, but instead of putting the actual code into the else clause, instantiate your new type and call your new method there instead, passing any parameters it might require. This works well if what you're adding is fairly complex, since now you have a much easier way to test that complex code rather than going through an already big and complex method to get to it.</p><p>Depending on the conditions that dictate when your new behavior should run, you might be able to get out of using the existing big complex method at all. Let's say the existing method is called <code>BigMethod</code>. Move <code>BigMethod</code> into a new class called <code>Original</code> and wherever you had code calling <code>BigMethod</code> change it to call <code>new Original().BigMethod()</code>. This is one of those cases where you're forced to change the existing code in order to prepare it for your new code, so you'll want to be very careful and do a lot of testing. If there are a lot of global or static dependencies running through <code>BigMethod</code>, this approach might not work well, so keep that in mind. However, assuming you're able to pull <code>BigMethod</code> into its own class that you then call as needed, the next step is to create another new class for your new implementation. We'll call the new class <code>BetterDesign</code> and we'll keep the method named <code>BigMethod</code> for now so that if we want we can use polymorphism via inheritance or an interface. Copy <code>BigMethod</code> from the <code>Original</code> class to your <code>BetterDesign</code> class and modify it so it <strong>only does what your new requirements need</strong>. It should be much smaller and simpler than what's in <code>Original</code>. Now, find all the places where you're instantiating <code>Original</code> and put in a conditional statement there so you'll instantiate <code>BetterDesign</code> instead, in the appropriate circumstances. At this point you should be able to add the behavior you need, in a new and testable class, without breaking anything that previously depended on <code>BigMethod</code>. If you have more than a few places where you need to decide whether to create <code>Original</code> or <code>BetterDesign</code>, look at using the Factory design pattern.</p><p>By adjusting the way we maintain legacy systems to maximize how much new behavior we add through new classes and methods, we can minimize the likelihood of introducing regressions. This improves the code quality over time, increases team productivity, and makes the code more enjoyable to work with. If you have experience working with legacy code, please share it in this show's comments at <a href="/015">www.weeklydevtips.com/015</a>.</p><h2>Show Resources and Links</h2><ul><li><a href="https://amzn.to/2CYWqPJ">Working Effectively with Legacy Code</a></li><li><a href="https://deviq.com/technical-debt/">Technical Debt</a></li><li><a href="https://www.pluralsight.com/courses/refactoring-csharp-developers">Refactoring</a></li><li><a href="https://deviq.com/boy-scout-rule/">Boy Scout Rule</a></li><li><a href="https://www.pluralsight.com/courses/csharp-solid-principles">SOLID Principles</a></li></ul>
]]></content:encoded>
      <enclosure length="5401733" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/448fb1c1-5aea-444c-b275-2662e33364fd/e7e83d34_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Maintain Legacy Code with New Code</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/448fb1c1-5aea-444c-b275-2662e33364fd/3000x3000/1515187404artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:08:57</itunes:duration>
      <itunes:summary>Many developers work in legacy codebases, which are notoriously difficult to test and maintain in many cases. One way you can address these issues is by trying to maximize the use of new, better designed constructs in the code you add to the system.</itunes:summary>
      <itunes:subtitle>Many developers work in legacy codebases, which are notoriously difficult to test and maintain in many cases. One way you can address these issues is by trying to maximize the use of new, better designed constructs in the code you add to the system.</itunes:subtitle>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>15</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">e1929115-7b67-405f-92fa-dc209339d7b1</guid>
      <title>Smarter Enumerations</title>
      <description><![CDATA[<h1>Smarter Enumerations</h1>
<p>Enumerations are a very primitive type that are frequently overused. In many scenarios, actual objects are a better choice.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>Enums are an extremely common construct in applications. They provide a simple way to give labels to numeric values. They're especially useful for efficiently capturing a set of flag values by using binary AND and OR operations on values set to powers of 2. However, as primitive value types, they don't have the capability to add behavior to the values they represent, and this often results in a particular flavor of the primitive obsession code smell that I discussed in <a href="/012">episode 12</a>.</p>
<p>One of the first signs that you're stretching the limits of an enum in C# is if you find that you want to display the names associated with the values to the user, and some of the names should have spaces in them when displayed. For example, you might have a Roles enum that includes a SalesRepresentative name. If you display that in a dropdownlist in the UI, you'll want to have a space between Sales and Representative. There are a few hacky ways to achieve this. The first would be to parse the name of the enum and insert spaces anywhere you find capital letters in the middle of the string. Another common one is to add an attribute that contains the user-friendly version of the enum's name, and if this attribute is present, use it when displaying the enum's name. Both of these can work, but they're not ideal. They both require more code outside of the enum, making it harder to work with, and scattering logic related to the enum into other types.</p>
<p>While we're on the topic of displaying enum values to end users, another fairly common requirement in this area is to control which enum options are displayed to the user. Once again, you can use attributes to control this behavior, or maybe even some kind of naming convention for the enum labels (maybe add a Visible or Hidden suffix and then strip off the suffix when displaying the name). As you can guess, both of these approaches just lead you further down the path of cluttering up your non-enum code to accommodate the lack of behavior within the enums themselves. What you really need is a better abstraction.</p>
<h3>Enumeration Classes</h3>
<p>The pattern I favor is the <a href="https://github.com/ardalis/SmartEnum">SmartEnum</a> class, also known as the Strongly Typed Enum Class. With this pattern, you start with a class definiton that includes the basic capabilities of an enum type, such as having a simple name and value. Then, you define the set of available options as static properties on the class. For example, if you were creating a Roles enumeration class, you would add static properties on the Roles class for things like Administrator or SalesRepresentative. These static properties would be of type Roles (or Role, as you prefer). Working with these static instances mirrors working with enums. You can simply type Roles (dot) and your IDE will show you the set of static properties that represent the possible options, just the same as an enum.</p>
<p>Since you're representing your options as a class, you now have the ability to add any behavior you require. If you need to display the value in a certain way, you can add a property or method to do so. If you need to add metadata that will determine when or whether a particular option is visible or available to a given user, you can add this as well. When you do, the business logic you're adding is encapsulated within the enumeration class, rather than spread throughout your user interface code.</p>
<p>If you're looking to get started with this approach, I've created a GitHub repo and Nuget package at Ardalis.SmartEnum. I've also written several articles over the years on this topic that I'll add to the show notes for this episode, which you'll find at weeklydevtips.com/014.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://github.com/ardalis/SmartEnum">SmartEnum (GitHub)</a></li>
<li><a href="https://www.nuget.org/packages/Ardalis.SmartEnum">SmartEnum (Nuget)</a></li>
<li><a href="https://ardalis.com/listing-strongly-typed-enum-options-in-c">Listing Strongly Typed Enum Options in C#</a></li>
<li><a href="https://ardalis.com/enum-alternatives-in-c">Enum Alternatives in C#</a></li>
</ul>
]]></description>
      <pubDate>Mon, 11 Dec 2017 07:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h1>Smarter Enumerations</h1>
<p>Enumerations are a very primitive type that are frequently overused. In many scenarios, actual objects are a better choice.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>Enums are an extremely common construct in applications. They provide a simple way to give labels to numeric values. They're especially useful for efficiently capturing a set of flag values by using binary AND and OR operations on values set to powers of 2. However, as primitive value types, they don't have the capability to add behavior to the values they represent, and this often results in a particular flavor of the primitive obsession code smell that I discussed in <a href="/012">episode 12</a>.</p>
<p>One of the first signs that you're stretching the limits of an enum in C# is if you find that you want to display the names associated with the values to the user, and some of the names should have spaces in them when displayed. For example, you might have a Roles enum that includes a SalesRepresentative name. If you display that in a dropdownlist in the UI, you'll want to have a space between Sales and Representative. There are a few hacky ways to achieve this. The first would be to parse the name of the enum and insert spaces anywhere you find capital letters in the middle of the string. Another common one is to add an attribute that contains the user-friendly version of the enum's name, and if this attribute is present, use it when displaying the enum's name. Both of these can work, but they're not ideal. They both require more code outside of the enum, making it harder to work with, and scattering logic related to the enum into other types.</p>
<p>While we're on the topic of displaying enum values to end users, another fairly common requirement in this area is to control which enum options are displayed to the user. Once again, you can use attributes to control this behavior, or maybe even some kind of naming convention for the enum labels (maybe add a Visible or Hidden suffix and then strip off the suffix when displaying the name). As you can guess, both of these approaches just lead you further down the path of cluttering up your non-enum code to accommodate the lack of behavior within the enums themselves. What you really need is a better abstraction.</p>
<h3>Enumeration Classes</h3>
<p>The pattern I favor is the <a href="https://github.com/ardalis/SmartEnum">SmartEnum</a> class, also known as the Strongly Typed Enum Class. With this pattern, you start with a class definiton that includes the basic capabilities of an enum type, such as having a simple name and value. Then, you define the set of available options as static properties on the class. For example, if you were creating a Roles enumeration class, you would add static properties on the Roles class for things like Administrator or SalesRepresentative. These static properties would be of type Roles (or Role, as you prefer). Working with these static instances mirrors working with enums. You can simply type Roles (dot) and your IDE will show you the set of static properties that represent the possible options, just the same as an enum.</p>
<p>Since you're representing your options as a class, you now have the ability to add any behavior you require. If you need to display the value in a certain way, you can add a property or method to do so. If you need to add metadata that will determine when or whether a particular option is visible or available to a given user, you can add this as well. When you do, the business logic you're adding is encapsulated within the enumeration class, rather than spread throughout your user interface code.</p>
<p>If you're looking to get started with this approach, I've created a GitHub repo and Nuget package at Ardalis.SmartEnum. I've also written several articles over the years on this topic that I'll add to the show notes for this episode, which you'll find at weeklydevtips.com/014.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://github.com/ardalis/SmartEnum">SmartEnum (GitHub)</a></li>
<li><a href="https://www.nuget.org/packages/Ardalis.SmartEnum">SmartEnum (Nuget)</a></li>
<li><a href="https://ardalis.com/listing-strongly-typed-enum-options-in-c">Listing Strongly Typed Enum Options in C#</a></li>
<li><a href="https://ardalis.com/enum-alternatives-in-c">Enum Alternatives in C#</a></li>
</ul>
]]></content:encoded>
      <enclosure length="3670107" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/f7d78c41-426e-4792-abea-436147f64774/fa3dfc1f_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Smarter Enumerations</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/f7d78c41-426e-4792-abea-436147f64774/3000x3000/1512913799artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:05:19</itunes:duration>
      <itunes:summary>Enumerations are a very primitive type that are frequently overused. In many scenarios, actual objects are a better choice.</itunes:summary>
      <itunes:subtitle>Enumerations are a very primitive type that are frequently overused. In many scenarios, actual objects are a better choice.</itunes:subtitle>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>14</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">249c7b34-b414-4193-8108-8ac731c60a26</guid>
      <title>Be Thankful and Show Gratitude</title>
      <description><![CDATA[<h1>Be Thankful and Show Gratitude</h1>
<p>It's highly unlikely that you're a software developer who works in a vacuum. Here are a few tips for showing your gratitude to the people, companies, products, and tools that help you to be successful.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>Last year around Thanksgiving I published an article about showing gratitude as a software developer. I'll link to it in the show notes and I encourage you to read it if you find this topic interesting. The topic of showing gratitude and being thankful, specifically as software developers, remains relevant today, so I thought it worth revisiting.</p>
<p>Since you're listening to this podcast, I'm going to go out on a limb and assume you're a software developer. A programmer. A coder. Maybe that's not your title, and maybe it's not even your main responsibility, but you've built software. In building that software, regardless of your platform or language of choice, you've almost certainly leveraged a wide variety of resources that helped you along the way. You may not even realize, or perhaps you've taken for granted, some of the things that helped you. As the saying goes, sometimes you don't know how much you miss something until it's gone. Many of the most valuable resources we have available to us are provided freely by others. If those others feel unappreciated, they may take their passion and energy elsewhere, so don't assume that just because someone isn't charging you money for their efforts, that they don't value things you might do, non-monetarily.</p>
<p>Let's consider a few simple examples to highlight this point. One is <a href="https://stackoverflow.com/users/13729/ssmith">StackOverflow</a>. You've probably used it, since it's the de facto standard question and answer site for software development. When you find that answer you were looking for, try to give it an upvote. And while you're at it, vote the question up, too, since someone had to ask it in order for you to get the answer you needed.</p>
<p>Some publications, like <a href="https://medium.com/@ardalis">Medium</a>, provide a way for you to show appreciation by liking or clapping for an article. Be sure to show your support for content you find valuable by taking advantage of these features. In addition, you can share content you find interesting on social media with a quick <a href="http://twitter.com/home?status=Just%20listened%20to%20an%20interesting%20show%20on%20@weeklydevtips.%20Check%20it%20out!">tweet</a> or post on Facebook or your own blog (thus producing some additional content of your own).</p>
<p>Of course, for a podcast like this one, leaving a review in iTunes or Stitcher is highly appreciated (assuming it's a good review). Reviews help your favorite podcasts get discovered by more people, and also encourage publishers to keep producing content. It can be difficult sometimes to record content in a vacuum and send it out to the Internet, not knowing who is actually listening to it, or how they're feeling about it. It's very different from public speaking because of this lack of feedback. Reviews, as well as comments on individual show pages, are one way you can let publishers know they're being heard and appreciated.</p>
<p>You're probably using some open source tools as part of your development. Most open source projects I work with today are hosted on <a href="http://github.com/ardalis">GitHub</a>. If you find a particular project helpful or interesting, see if you can help support it. In GitHub, starred repositories are easier for you to find later. In addition, from their docs, &quot;Starring a repository also shows appreciation to the repository maintainer for their work. Many of GitHub's repository rankings depend on the number of stars a repository has. For example, repositories can be sorted and searched based on their star count.&quot; Of course, you can also take to social media or any of the other things I mentioned to show support, as well as offering to help by adding issues, fixing issues via pull requests, or offering to help document the project. Often end users can provide extremely valuable documentation since the maintainer of the project may not realize the ways in which many developers use their library or tools.</p>
<p>By showing appreciation for the tools and resources you use to be successful, you're doing a few things. You're helping to ensure these (generally free) resources continue to exist. This is obviously good for you. You're also setting an example for others, who may do the same, which magnifies your own contributions to further help support these resources. Again, good for you. You're also potentially developing positive relationships within the developer community. Who knows which tweet, comment, or pull request of yours that expresses gratitude will lead to a connection that culminates in a new contract or job opportunity. People get invited to help support projects they support. People want to work with supportive, helpful people. Aside from &quot;being nice&quot; or being &quot;the right thing to do&quot;, actively showing gratitude within your professional community costs you nearly nothing but can yield tangible benefits in your career.</p>
<p>If you found this particular episode helpful, please consider leaving a comment on the show notes pages. If there's a way that you like to show gratitude, or if you're someone who offers their time for free and there's a way you like to get positive encouragement from your users or audience, please share it.</p>
<h2>Additional Ways To Show Gratitude (add yours in comments below):</h2>
<ul>
<li>Follow person/project on twitter</li>
<li>Like their Facebook page</li>
<li>Follow individual/project on GitHub</li>
</ul>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://medium.com/@ardalis/be-a-thankful-developer-22a46015b44c">Be a Thankful Developer</a> (Medium - revised 2017)</li>
<li><a href="https://ardalis.com/be-a-thankful-developer">Be a Thankful Developer</a> (original 2016 ardalis.com version)</li>
<li><a href="https://help.github.com/articles/about-stars/">About GitHub Stars</a></li>
</ul>
]]></description>
      <pubDate>Mon, 4 Dec 2017 07:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h1>Be Thankful and Show Gratitude</h1>
<p>It's highly unlikely that you're a software developer who works in a vacuum. Here are a few tips for showing your gratitude to the people, companies, products, and tools that help you to be successful.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>Last year around Thanksgiving I published an article about showing gratitude as a software developer. I'll link to it in the show notes and I encourage you to read it if you find this topic interesting. The topic of showing gratitude and being thankful, specifically as software developers, remains relevant today, so I thought it worth revisiting.</p>
<p>Since you're listening to this podcast, I'm going to go out on a limb and assume you're a software developer. A programmer. A coder. Maybe that's not your title, and maybe it's not even your main responsibility, but you've built software. In building that software, regardless of your platform or language of choice, you've almost certainly leveraged a wide variety of resources that helped you along the way. You may not even realize, or perhaps you've taken for granted, some of the things that helped you. As the saying goes, sometimes you don't know how much you miss something until it's gone. Many of the most valuable resources we have available to us are provided freely by others. If those others feel unappreciated, they may take their passion and energy elsewhere, so don't assume that just because someone isn't charging you money for their efforts, that they don't value things you might do, non-monetarily.</p>
<p>Let's consider a few simple examples to highlight this point. One is <a href="https://stackoverflow.com/users/13729/ssmith">StackOverflow</a>. You've probably used it, since it's the de facto standard question and answer site for software development. When you find that answer you were looking for, try to give it an upvote. And while you're at it, vote the question up, too, since someone had to ask it in order for you to get the answer you needed.</p>
<p>Some publications, like <a href="https://medium.com/@ardalis">Medium</a>, provide a way for you to show appreciation by liking or clapping for an article. Be sure to show your support for content you find valuable by taking advantage of these features. In addition, you can share content you find interesting on social media with a quick <a href="http://twitter.com/home?status=Just%20listened%20to%20an%20interesting%20show%20on%20@weeklydevtips.%20Check%20it%20out!">tweet</a> or post on Facebook or your own blog (thus producing some additional content of your own).</p>
<p>Of course, for a podcast like this one, leaving a review in iTunes or Stitcher is highly appreciated (assuming it's a good review). Reviews help your favorite podcasts get discovered by more people, and also encourage publishers to keep producing content. It can be difficult sometimes to record content in a vacuum and send it out to the Internet, not knowing who is actually listening to it, or how they're feeling about it. It's very different from public speaking because of this lack of feedback. Reviews, as well as comments on individual show pages, are one way you can let publishers know they're being heard and appreciated.</p>
<p>You're probably using some open source tools as part of your development. Most open source projects I work with today are hosted on <a href="http://github.com/ardalis">GitHub</a>. If you find a particular project helpful or interesting, see if you can help support it. In GitHub, starred repositories are easier for you to find later. In addition, from their docs, &quot;Starring a repository also shows appreciation to the repository maintainer for their work. Many of GitHub's repository rankings depend on the number of stars a repository has. For example, repositories can be sorted and searched based on their star count.&quot; Of course, you can also take to social media or any of the other things I mentioned to show support, as well as offering to help by adding issues, fixing issues via pull requests, or offering to help document the project. Often end users can provide extremely valuable documentation since the maintainer of the project may not realize the ways in which many developers use their library or tools.</p>
<p>By showing appreciation for the tools and resources you use to be successful, you're doing a few things. You're helping to ensure these (generally free) resources continue to exist. This is obviously good for you. You're also setting an example for others, who may do the same, which magnifies your own contributions to further help support these resources. Again, good for you. You're also potentially developing positive relationships within the developer community. Who knows which tweet, comment, or pull request of yours that expresses gratitude will lead to a connection that culminates in a new contract or job opportunity. People get invited to help support projects they support. People want to work with supportive, helpful people. Aside from &quot;being nice&quot; or being &quot;the right thing to do&quot;, actively showing gratitude within your professional community costs you nearly nothing but can yield tangible benefits in your career.</p>
<p>If you found this particular episode helpful, please consider leaving a comment on the show notes pages. If there's a way that you like to show gratitude, or if you're someone who offers their time for free and there's a way you like to get positive encouragement from your users or audience, please share it.</p>
<h2>Additional Ways To Show Gratitude (add yours in comments below):</h2>
<ul>
<li>Follow person/project on twitter</li>
<li>Like their Facebook page</li>
<li>Follow individual/project on GitHub</li>
</ul>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://medium.com/@ardalis/be-a-thankful-developer-22a46015b44c">Be a Thankful Developer</a> (Medium - revised 2017)</li>
<li><a href="https://ardalis.com/be-a-thankful-developer">Be a Thankful Developer</a> (original 2016 ardalis.com version)</li>
<li><a href="https://help.github.com/articles/about-stars/">About GitHub Stars</a></li>
</ul>
]]></content:encoded>
      <enclosure length="4292670" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/e73dc4fa-879d-46b0-a67b-1fc449190a56/fbd3d747_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Be Thankful and Show Gratitude</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/e73dc4fa-879d-46b0-a67b-1fc449190a56/3000x3000/1512430637artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:06:49</itunes:duration>
      <itunes:summary>It&apos;s highly unlikely that you&apos;re a software developer who works in a vacuum. Here are a few tips for showing your gratitude to the people, companies, products, and tools that help you to be successful.</itunes:summary>
      <itunes:subtitle>It&apos;s highly unlikely that you&apos;re a software developer who works in a vacuum. Here are a few tips for showing your gratitude to the people, companies, products, and tools that help you to be successful.</itunes:subtitle>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>13</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">aedb12f4-a17f-43b0-81a0-845538dd104c</guid>
      <title>Primitive Obsession</title>
      <description><![CDATA[<h1>Primitive Obsession</h1><p>Primitive Obsession describes code in which the design relies too heavily on primitive types, rather than solution-specific abstractions. It often results in more verbose code with more duplication of logic, since logic cannot be embedded with the primitive types used.</p><h2>Sponsor - DevIQ</h2><p>Thanks to DevIQ for sponsoring this episode!</p><h2>Show Notes / Transcript</h2><p>Primitives refer to built-in types, like <code>bool</code>, <code>int</code>, <code>string</code>, etc. The primitive obsession code smell refers to overuse of primitive types to represent concepts that aren't a perfect fit, because the primitive supports values that don't make sense for the element they're representing. For example, it's not unusual to use a <code>string</code> to represent a ZIP Code value or a Social Security Number. Many systems will use an <code>int</code> to represent a value that cannot be negative, such as the number of items in a shopping basket. In such a case, if the system even bothers to enforce the invariant stating that shopping basket quantity must be positive, it must do so somewhere other than in the type representing the quantity. Ideally, the shopping basket or basket item type would enforce this, but again in many designs the shopping basket item quantity is simply a property that can be set to anything. In which case any service, UI call, etc. that manipulates a basket item would first need to ensure it was being set properly. This can result in a great deal of duplicate code, with the usual technical debt that arises when you violate the Don't Repeat Yourself principle. In some places, someone will forget to perform the checks, or they'll perform them differently, and bugs will creep in. Or the rules will be updated, but not everywhere, which results in the same inconsistent behavior. When you work with too primitive of an abstraction, you end up having to code around this deficiency every time you work with the type.</p><h3>Encapsulation</h3><p>I've talked about encapsulation before - it's obviously an important concept in software design. By choosing to represent a concept with a primitive, you give up the ability to leverage encapsulation when working with this concept in your solution. The biggest problem with primitive obsession is that it results in a lot of behavior being added <strong>around</strong> the types in question, rather than encapsulated within them. Instead of having to check, probably in many places, that Quantity is positive or that a string represents a valid ZIP code, it's far better to create a type to represent the concept in question, along with its rules.</p><p>Such types should typically be immutable value objects that cannot be created in an invalid state (and thus need not be validated where they are passed in as parameters). It's useful to have easy ways to cast primitives to and from these value objects, but this should be done only at the edges of the application (user input/output, persistence). Try to use the value object as much as possible within your actual business logic or domain model, rather than a primitive representation of the type.</p><p>You can make working with your new type about as easy as working with the primitive it's replacing by making sure you override its <code>ToString</code> method. You can also handle comparisons and equality, and configure implicit and explicit casting operators. Jimmy Bogard wrote an <a href="https://lostechies.com/jimmybogard/2007/12/03/dealing-with-primitive-obsession/">article</a> about 10 years ago that describes how to do exactly this for a simple ZIP Code type in C# - there's a link in the show notes. Yes, you'll end up with a dozen or so lines of code in your ZIP Code class instead of just using a string, but any logic that relates to ZIP Codes will also live in this class, rather than being scattered throughout your application.</p><p>When you represent a concept in your system with a primitive type, you're asserting that the concept can be represented by any value that type can hold. If you expose method signatures that accept primitive values, the only clue you might offer to clients of that method could be the names of the parameters. Invalid values might no immediately be discovered, or if they are, the related errors might be buried within the behavior of the method, rather than immediately apparent. If instead you use a separate value object to represent a concept, a method that accepts parameters using this type will be much easier for clients to work with. If there are exceptions related to type conversion, they will be discovered immediately when the client attempts to create an instance of the value object, and this behavior will be consistent everywhere, unlike different methods that may or may not perform validity checks on their inputs.</p><p>You can learn more about the primitive obsession code smell and literally dozens of others, along with how to refactor them, in my Pluralsight course, Refactoring Fundamentals.</p><h2>Show Resources and Links</h2><ul><li><a href="https://deviq.com/encapsulation/">Encapsulation</a></li><li><a href="https://deviq.com/don-t-repeat-yourself/">Don't Repeat Yourself</a></li><li><a href="https://www.pluralsight.com/courses/refactoring-csharp-developers">Refactoring for C# Developers</a></li><li><a href="https://www.pluralsight.com/courses/refactoring-fundamentals">Refactoring Fundamentals</a></li><li><a href="https://lostechies.com/jimmybogard/2007/12/03/dealing-with-primitive-obsession/">Dealing with Primitive Obsession</a> - Jimmy Bogard</li><li><a href="https://blog.ploeh.dk/2011/05/25/DesignSmellPrimitiveObsession/">Design Smell: Primitive Obsession</a> - Mark Seeman</li></ul>
]]></description>
      <pubDate>Mon, 20 Nov 2017 07:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h1>Primitive Obsession</h1><p>Primitive Obsession describes code in which the design relies too heavily on primitive types, rather than solution-specific abstractions. It often results in more verbose code with more duplication of logic, since logic cannot be embedded with the primitive types used.</p><h2>Sponsor - DevIQ</h2><p>Thanks to DevIQ for sponsoring this episode!</p><h2>Show Notes / Transcript</h2><p>Primitives refer to built-in types, like <code>bool</code>, <code>int</code>, <code>string</code>, etc. The primitive obsession code smell refers to overuse of primitive types to represent concepts that aren't a perfect fit, because the primitive supports values that don't make sense for the element they're representing. For example, it's not unusual to use a <code>string</code> to represent a ZIP Code value or a Social Security Number. Many systems will use an <code>int</code> to represent a value that cannot be negative, such as the number of items in a shopping basket. In such a case, if the system even bothers to enforce the invariant stating that shopping basket quantity must be positive, it must do so somewhere other than in the type representing the quantity. Ideally, the shopping basket or basket item type would enforce this, but again in many designs the shopping basket item quantity is simply a property that can be set to anything. In which case any service, UI call, etc. that manipulates a basket item would first need to ensure it was being set properly. This can result in a great deal of duplicate code, with the usual technical debt that arises when you violate the Don't Repeat Yourself principle. In some places, someone will forget to perform the checks, or they'll perform them differently, and bugs will creep in. Or the rules will be updated, but not everywhere, which results in the same inconsistent behavior. When you work with too primitive of an abstraction, you end up having to code around this deficiency every time you work with the type.</p><h3>Encapsulation</h3><p>I've talked about encapsulation before - it's obviously an important concept in software design. By choosing to represent a concept with a primitive, you give up the ability to leverage encapsulation when working with this concept in your solution. The biggest problem with primitive obsession is that it results in a lot of behavior being added <strong>around</strong> the types in question, rather than encapsulated within them. Instead of having to check, probably in many places, that Quantity is positive or that a string represents a valid ZIP code, it's far better to create a type to represent the concept in question, along with its rules.</p><p>Such types should typically be immutable value objects that cannot be created in an invalid state (and thus need not be validated where they are passed in as parameters). It's useful to have easy ways to cast primitives to and from these value objects, but this should be done only at the edges of the application (user input/output, persistence). Try to use the value object as much as possible within your actual business logic or domain model, rather than a primitive representation of the type.</p><p>You can make working with your new type about as easy as working with the primitive it's replacing by making sure you override its <code>ToString</code> method. You can also handle comparisons and equality, and configure implicit and explicit casting operators. Jimmy Bogard wrote an <a href="https://lostechies.com/jimmybogard/2007/12/03/dealing-with-primitive-obsession/">article</a> about 10 years ago that describes how to do exactly this for a simple ZIP Code type in C# - there's a link in the show notes. Yes, you'll end up with a dozen or so lines of code in your ZIP Code class instead of just using a string, but any logic that relates to ZIP Codes will also live in this class, rather than being scattered throughout your application.</p><p>When you represent a concept in your system with a primitive type, you're asserting that the concept can be represented by any value that type can hold. If you expose method signatures that accept primitive values, the only clue you might offer to clients of that method could be the names of the parameters. Invalid values might no immediately be discovered, or if they are, the related errors might be buried within the behavior of the method, rather than immediately apparent. If instead you use a separate value object to represent a concept, a method that accepts parameters using this type will be much easier for clients to work with. If there are exceptions related to type conversion, they will be discovered immediately when the client attempts to create an instance of the value object, and this behavior will be consistent everywhere, unlike different methods that may or may not perform validity checks on their inputs.</p><p>You can learn more about the primitive obsession code smell and literally dozens of others, along with how to refactor them, in my Pluralsight course, Refactoring Fundamentals.</p><h2>Show Resources and Links</h2><ul><li><a href="https://deviq.com/encapsulation/">Encapsulation</a></li><li><a href="https://deviq.com/don-t-repeat-yourself/">Don't Repeat Yourself</a></li><li><a href="https://www.pluralsight.com/courses/refactoring-csharp-developers">Refactoring for C# Developers</a></li><li><a href="https://www.pluralsight.com/courses/refactoring-fundamentals">Refactoring Fundamentals</a></li><li><a href="https://lostechies.com/jimmybogard/2007/12/03/dealing-with-primitive-obsession/">Dealing with Primitive Obsession</a> - Jimmy Bogard</li><li><a href="https://blog.ploeh.dk/2011/05/25/DesignSmellPrimitiveObsession/">Design Smell: Primitive Obsession</a> - Mark Seeman</li></ul>
]]></content:encoded>
      <enclosure length="3755291" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/1b872b11-020c-45b7-9dee-3fe45625bd4e/288f75ed_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Primitive Obsession</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/1b872b11-020c-45b7-9dee-3fe45625bd4e/3000x3000/1511201999artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:06:44</itunes:duration>
      <itunes:summary>Primitive Obsession describes code in which the design relies too heavily on primitive types, rather than solution-specific abstractions. It often results in more verbose code with more duplication of logic, since logic cannot be embedded with the primitive types used.</itunes:summary>
      <itunes:subtitle>Primitive Obsession describes code in which the design relies too heavily on primitive types, rather than solution-specific abstractions. It often results in more verbose code with more duplication of logic, since logic cannot be embedded with the primitive types used.</itunes:subtitle>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>12</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">b8cd5004-e097-4d2d-b0af-99ee07724806</guid>
      <title>Encapsulating Collection Properties</title>
      <description><![CDATA[<h1>Encapsulating Collection Properties</h1>
<p>Encapsulation is a key aspect of object-oriented programming and software engineering. Unfortunately, many systems fail to properly encapsulate collection properties, resulting in reduced quality.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>Encapsulation essentially means hiding the inner workings of something and exposing a limited public interface. It helps promote more modular code that is more reliable, since verifying the public interface's behavior provides a high degree of confidence that the object will interact properly with collaborators in a system. One area in which encapsulation often isn't properly followed is with collection properties.</p>
<h3>Collection Properties</h3>
<p>Any time you have an object that has a collection of related or child objects, you may find this represented as a collection property. If you're using .NET and Entity Framework, this property is often referred to as a navigation property. Some client code can fetch the parent object from persistence, specify to EF that it should load the related entities, and then navigate from the parent object to its related objects by iterating over an exposed collection property. For example, a Customer object might have a set of Orders they've placed previously. This could be represented most simply by having a public List property on the Customer class. This property must expose a getter, and in many cases system designs will have it expose a public setter as well. In that case, any code in the system would be able to set a Customer's order collection to any list of Orders, or to null. This could obviously result in undesired behavior.</p>
<p>Some developers might offer token resistance to this total lack of encapsulation by removing the setter (or making it private), but the damage is done as long as the property exposes a List data type, with all of its mutable functionality. This kind of design exposes too much functionality from the Customer, since it inherently allows any client code that works with a Customer to:</p>
<ul>
<li>Directly add or remove an order to/from the Customer</li>
<li>Clear all orders from the Customer</li>
</ul>
<p>In these cases, the Customer object in question has no way of controlling, preventing, or even detecting these changes to its Orders collection. Why is this important? Well, there is probably a decent amount of workflow involved in placing a new order for a customer. It's probably not sufficient to simply add a new order without any additional work. Now, you can argue that somewhere there's a service that does all the required work, but how does the object model enforce the use of said service? If any client code can instantiate an order and add it to a customer, how is the design of the system leading developers toward doing the right thing (using a service, in this case)? On the other hand, if there is no way to directly add an order to a customer, developers will probably quickly discover that there is a service for this  purpose, and it's more likely that this service will provide the only way of adding new orders to customers.</p>
<p>In most cases, there are only certain operations on related collections that an object should expose, and these it probably wants to have direct control over. If Customer collaborators shouldn't be able to directly delete all of a customer's orders, don't expose the collection as a List. Instead, expose a ReadOnlyCollection, or an IEnumerable. Both EF 6 and EF Core support properly encapsulating collection navigation properties, so don't feel like you have to expose List types in order to keep EF happy. Check out the links in the show notes at WeeklyDevTips.com/011 to see how to configure EF to support proper collection encapsulation.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://ardalis.com/encapsulated-collections-in-entity-framework-core">Encapsulated Collections in EF Core</a></li>
<li><a href="https://ardalis.com/exposing-private-collection-properties-to-entity-framework">Exposing Private Collection Properties to Entity Framework</a></li>
<li><a href="http://deviq.com/encapsulation/">Encapsulation</a></li>
<li><a href="http://deviq.com/exposing-collection-properties/">Exposing Collection Properties</a></li>
</ul>
]]></description>
      <pubDate>Mon, 13 Nov 2017 07:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h1>Encapsulating Collection Properties</h1>
<p>Encapsulation is a key aspect of object-oriented programming and software engineering. Unfortunately, many systems fail to properly encapsulate collection properties, resulting in reduced quality.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>Encapsulation essentially means hiding the inner workings of something and exposing a limited public interface. It helps promote more modular code that is more reliable, since verifying the public interface's behavior provides a high degree of confidence that the object will interact properly with collaborators in a system. One area in which encapsulation often isn't properly followed is with collection properties.</p>
<h3>Collection Properties</h3>
<p>Any time you have an object that has a collection of related or child objects, you may find this represented as a collection property. If you're using .NET and Entity Framework, this property is often referred to as a navigation property. Some client code can fetch the parent object from persistence, specify to EF that it should load the related entities, and then navigate from the parent object to its related objects by iterating over an exposed collection property. For example, a Customer object might have a set of Orders they've placed previously. This could be represented most simply by having a public List property on the Customer class. This property must expose a getter, and in many cases system designs will have it expose a public setter as well. In that case, any code in the system would be able to set a Customer's order collection to any list of Orders, or to null. This could obviously result in undesired behavior.</p>
<p>Some developers might offer token resistance to this total lack of encapsulation by removing the setter (or making it private), but the damage is done as long as the property exposes a List data type, with all of its mutable functionality. This kind of design exposes too much functionality from the Customer, since it inherently allows any client code that works with a Customer to:</p>
<ul>
<li>Directly add or remove an order to/from the Customer</li>
<li>Clear all orders from the Customer</li>
</ul>
<p>In these cases, the Customer object in question has no way of controlling, preventing, or even detecting these changes to its Orders collection. Why is this important? Well, there is probably a decent amount of workflow involved in placing a new order for a customer. It's probably not sufficient to simply add a new order without any additional work. Now, you can argue that somewhere there's a service that does all the required work, but how does the object model enforce the use of said service? If any client code can instantiate an order and add it to a customer, how is the design of the system leading developers toward doing the right thing (using a service, in this case)? On the other hand, if there is no way to directly add an order to a customer, developers will probably quickly discover that there is a service for this  purpose, and it's more likely that this service will provide the only way of adding new orders to customers.</p>
<p>In most cases, there are only certain operations on related collections that an object should expose, and these it probably wants to have direct control over. If Customer collaborators shouldn't be able to directly delete all of a customer's orders, don't expose the collection as a List. Instead, expose a ReadOnlyCollection, or an IEnumerable. Both EF 6 and EF Core support properly encapsulating collection navigation properties, so don't feel like you have to expose List types in order to keep EF happy. Check out the links in the show notes at WeeklyDevTips.com/011 to see how to configure EF to support proper collection encapsulation.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://ardalis.com/encapsulated-collections-in-entity-framework-core">Encapsulated Collections in EF Core</a></li>
<li><a href="https://ardalis.com/exposing-private-collection-properties-to-entity-framework">Exposing Private Collection Properties to Entity Framework</a></li>
<li><a href="http://deviq.com/encapsulation/">Encapsulation</a></li>
<li><a href="http://deviq.com/exposing-collection-properties/">Exposing Collection Properties</a></li>
</ul>
]]></content:encoded>
      <enclosure length="3477187" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/493a20b1-3320-428c-93d1-d8571590c085/78724aa6_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Encapsulating Collection Properties</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/493a20b1-3320-428c-93d1-d8571590c085/3000x3000/1510594065artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:05:38</itunes:duration>
      <itunes:summary>Encapsulation is a key aspect of object-oriented programming and software engineering. Unfortunately, many systems fail to properly encapsulate collection properties, resulting in reduced quality.</itunes:summary>
      <itunes:subtitle>Encapsulation is a key aspect of object-oriented programming and software engineering. Unfortunately, many systems fail to properly encapsulate collection properties, resulting in reduced quality.</itunes:subtitle>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>11</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">3125d4d0-b60c-4927-895f-c1bc5192e6ef</guid>
      <title>Pain Driven Development</title>
      <description><![CDATA[<h1>Pain Driven Development</h1><p>Pain Driven Development, or PDD, is the practice of writing software in such a way that you only "fix" problems when they are causing pain, rather than trying to preempt every possible issue.</p><h2>Sponsor - DevIQ</h2><p>Thanks to DevIQ for sponsoring this episode!</p><h2>Show Notes / Transcript</h2><p>Many of you have probably heard of various "DD" approaches to writing software. There's TDD, or Test Driven Development. There's BDD, for Behavior Driven Development. In this tip, I want to introduce you to another one, PDD: Pain Driven Development.</p><h3>Pain Driven Development</h3><p>Software development is full of principles, patterns, and best practices. It can be tempting, especially when you've recently learned about a new way of doing things, to want to apply it widely to maximize its benefits. Some time ago, when XML was a new thing, for instance, Microsoft went all-in with it. They decided to "XML ALL THE THINGS" and in some places, this was great. And in many cases, not so much. In my own experience, I find this is often the case when I'm learning a new design pattern or trying to fully understand a particular principle. It can be easy, when you're constantly on the lookout for applications of recent knowledge, to find excuses to apply these techniques.</p><p>One particular set of principles that many object-oriented programmers know are the SOLID principles. I have a course on SOLID on Pluralsight that I encourage you to check out, which covers these principles in depth. One thing that is worth remembering, though, is that you shouldn't, and honestly can't, apply all of the principles to every aspect of your software. You need to pick your battles. You need to actually ship working software. You don't know when you begin a project where extension is going to be necessary, so you can't anticipate every way in which you might support the Open-Closed Principle for every class or method in your program. Build and ship working software, and let feedback and new requirements guide you when it comes to applying iterative design improvements to your code. When you're back in the same method for the Nth time in the last month because yet another requirement has changed how it's supposed to work, that's when you should recognize the pain your current design is causing you. That's where Pain Driven Development comes into play. Refactor your code so that the pain you're experiencing as a result of its current design is abated.</p><p>Extreme Programming introduced the concept of YAGNI, or You Ain't Gonna Need It. PDD is closely aligned with this concept. YAGNI cautions against building things you <i>might</i> need in the application, and instead favors building only what's required today (but in a responsible manner, so you can revise the design in the future). PDD offers similar guidance, but from a different perspective. The message with PDD is, follow YAGNI and build only what is required today, but recognize when you'll "need it" by the pain the current design causes you as you try to work around/with it.</p><p>Well-designed code is enjoyable to work with. If you frequently find yourself frustrated with the code you're working with, see if you can identity the source(s) of the pain, and apply refactoring techniques to alleviate the problem.</p><h2>Show Resources and Links</h2><ul><li><a href="https://deviq.com/pain-driven-development/">Pain Driven Development (PDD)</a></li><li><a href="https://www.pluralsight.com/courses/csharp-solid-principles">SOLID Principles of OOD</a></li><li><a href="https://www.pluralsight.com/courses/refactoring-csharp-developers">Refactoring Fundamentals</a></li></ul>
]]></description>
      <pubDate>Mon, 6 Nov 2017 07:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h1>Pain Driven Development</h1><p>Pain Driven Development, or PDD, is the practice of writing software in such a way that you only "fix" problems when they are causing pain, rather than trying to preempt every possible issue.</p><h2>Sponsor - DevIQ</h2><p>Thanks to DevIQ for sponsoring this episode!</p><h2>Show Notes / Transcript</h2><p>Many of you have probably heard of various "DD" approaches to writing software. There's TDD, or Test Driven Development. There's BDD, for Behavior Driven Development. In this tip, I want to introduce you to another one, PDD: Pain Driven Development.</p><h3>Pain Driven Development</h3><p>Software development is full of principles, patterns, and best practices. It can be tempting, especially when you've recently learned about a new way of doing things, to want to apply it widely to maximize its benefits. Some time ago, when XML was a new thing, for instance, Microsoft went all-in with it. They decided to "XML ALL THE THINGS" and in some places, this was great. And in many cases, not so much. In my own experience, I find this is often the case when I'm learning a new design pattern or trying to fully understand a particular principle. It can be easy, when you're constantly on the lookout for applications of recent knowledge, to find excuses to apply these techniques.</p><p>One particular set of principles that many object-oriented programmers know are the SOLID principles. I have a course on SOLID on Pluralsight that I encourage you to check out, which covers these principles in depth. One thing that is worth remembering, though, is that you shouldn't, and honestly can't, apply all of the principles to every aspect of your software. You need to pick your battles. You need to actually ship working software. You don't know when you begin a project where extension is going to be necessary, so you can't anticipate every way in which you might support the Open-Closed Principle for every class or method in your program. Build and ship working software, and let feedback and new requirements guide you when it comes to applying iterative design improvements to your code. When you're back in the same method for the Nth time in the last month because yet another requirement has changed how it's supposed to work, that's when you should recognize the pain your current design is causing you. That's where Pain Driven Development comes into play. Refactor your code so that the pain you're experiencing as a result of its current design is abated.</p><p>Extreme Programming introduced the concept of YAGNI, or You Ain't Gonna Need It. PDD is closely aligned with this concept. YAGNI cautions against building things you <i>might</i> need in the application, and instead favors building only what's required today (but in a responsible manner, so you can revise the design in the future). PDD offers similar guidance, but from a different perspective. The message with PDD is, follow YAGNI and build only what is required today, but recognize when you'll "need it" by the pain the current design causes you as you try to work around/with it.</p><p>Well-designed code is enjoyable to work with. If you frequently find yourself frustrated with the code you're working with, see if you can identity the source(s) of the pain, and apply refactoring techniques to alleviate the problem.</p><h2>Show Resources and Links</h2><ul><li><a href="https://deviq.com/pain-driven-development/">Pain Driven Development (PDD)</a></li><li><a href="https://www.pluralsight.com/courses/csharp-solid-principles">SOLID Principles of OOD</a></li><li><a href="https://www.pluralsight.com/courses/refactoring-csharp-developers">Refactoring Fundamentals</a></li></ul>
]]></content:encoded>
      <enclosure length="3009482" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/53894d2d-3a08-4d8e-8ebe-f2956e29c899/044c2765_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Pain Driven Development</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/53894d2d-3a08-4d8e-8ebe-f2956e29c899/3000x3000/1509627355artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:04:29</itunes:duration>
      <itunes:summary>Many of you have probably heard of various &quot;DD&quot; approaches to writing software. There&apos;s TDD, or Test Driven Development. There&apos;s BDD, for Behavior Driven Development. In this tip, I want to introduce you to another one, PDD: Pain Driven Development.</itunes:summary>
      <itunes:subtitle>Many of you have probably heard of various &quot;DD&quot; approaches to writing software. There&apos;s TDD, or Test Driven Development. There&apos;s BDD, for Behavior Driven Development. In this tip, I want to introduce you to another one, PDD: Pain Driven Development.</itunes:subtitle>
      <itunes:keywords>test driven development, pain driven development, programming, tdd, software, pdd, refactoring, solid</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>10</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">3a174842-c4ea-46d9-b5f9-620eb58f38de</guid>
      <title>Data Transfer Objects (part 2)</title>
      <description><![CDATA[<h1>Data Transfer Object Tips (Part 2)</h1>
<p>One classification of objects in many applications is the Data Transfer Object, or DTO. Here are some more tips that may help you avoid problems when using these objects.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>Last week we talked about the definition of a DTO and how they're typically used. This week we'll cover a few more common problems with them and offer some Dos and Don'ts.</p>
<h3>Mapping and Factories</h3>
<p>It's fairly common to need to map to a DTO and another type, such as an entity. If you're doing this in several places, it's a good idea to consolidate the mapping code in one place. A static factory method on the DTO is a common approach to this. Note that this isn't adding behavior <em>to the DTO</em>, but rather is just a static helper method that we're putting on the DTO type for organizational purposes. I usually name such methods with a <code>From</code> prefix, such as <code>FromCustomer(Customer customer)</code> for a <code>CustomerDTO</code> type. There's a simple example in the show notes for episode 8.</p>
<pre><code>public class CustomerDTO
{
    public string FirstName { get; set; }
    public string LastName { get; set;}

    public static CustomerDTO FromCustomer(Customer customer)
    {
        return new CustomerDTO() 
        {
            FirstName = customer.FirstName,
            LastName = customer.LastName
        };
    }
}
</code></pre>
<p>You can also use a tool like <a href="http://automapper.org/">AutoMapper</a>, which will eliminate the need to use such static factory methods. I usually quickly end up moving to AutoMapper if I have more than a couple of these methods to write myself.</p>
<h3>What about attributes?</h3>
<p>It's common in ASP.NET MVC apps to use attributes from the <code>System.ComponentModel.DataAnnotations</code> namespace to decorate model types for validation purposes. For example, you can add a <code>Required</code> attribute to a property, and during model binding if that property isn't, an error will be added to a collection of validation errors. Since these attributes don't impact your ability to work with the class as a DTO, and since typically the DTO is tailor made for the purpose of doing this binding, I think it's perfectly reasonable to use these attributes for this purpose. You can rethink this decision if at some point the attributes start to cause you pain. Follow <a href="http://deviq.com/pain-driven-development/">Pain Driven Development (PDD)</a>: if something hurts, take a moment to analyze and correct the problem. Otherwise, keep on delivering value to your customers.</p>
<p>If you're not a fan of attribute-based validation, you can use <a href="https://github.com/JeremySkinner/FluentValidation">Fluent Validation</a> and define your validation logic using a fluent interface. You'll find a link in the show notes.</p>
<h3>Keeping DTOs Pure</h3>
<p>Avoid referencing non-DTO or primitive types from your DTOs. This can pull in dependencies that can make it difficult to secure your DTO. In some cases, it can introduce security vulnerabilities, such as if you have methods accepting input as DTOs, and these DTOs reference entities that your app is directly updating in the database. An attacker could guess at the structure of the entity and perhaps its navigation properties and could add or update data outside of the bounds of what you thought you were accepting. Take care in your update operations to only update specific fields, rather than model binding an entity object from external input and then saving it.</p>
<h3>DTO Dos and Don'ts</h3>
<p>Let's wrap up with some quick dos and don't for Data Transfer Objects:</p>
<ul>
<li>Don't hide the default constructor</li>
<li>Do make properties available via public get and set methods</li>
<li>Don't validate inputs to a DTO</li>
<li>Don't add instance methods to your DTO</li>
<li>Do consolidate mapping logic into static factories</li>
<li>Do consider moving to AutoMapper if you have more than a few such factory methods</li>
<li>Do feel free to use attributes to help with model validation</li>
<li>Don't reference non-DTO types, such as entities, from DTOs</li>
</ul>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="http://automapper.org/">AutoMapper</a></li>
<li><a href="http://deviq.com/pain-driven-development/">Pain Driven Development (PDD)</a></li>
<li><a href="https://github.com/JeremySkinner/FluentValidation">Fluent Validation</a></li>
</ul>
]]></description>
      <pubDate>Mon, 16 Oct 2017 06:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h1>Data Transfer Object Tips (Part 2)</h1>
<p>One classification of objects in many applications is the Data Transfer Object, or DTO. Here are some more tips that may help you avoid problems when using these objects.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>Last week we talked about the definition of a DTO and how they're typically used. This week we'll cover a few more common problems with them and offer some Dos and Don'ts.</p>
<h3>Mapping and Factories</h3>
<p>It's fairly common to need to map to a DTO and another type, such as an entity. If you're doing this in several places, it's a good idea to consolidate the mapping code in one place. A static factory method on the DTO is a common approach to this. Note that this isn't adding behavior <em>to the DTO</em>, but rather is just a static helper method that we're putting on the DTO type for organizational purposes. I usually name such methods with a <code>From</code> prefix, such as <code>FromCustomer(Customer customer)</code> for a <code>CustomerDTO</code> type. There's a simple example in the show notes for episode 8.</p>
<pre><code>public class CustomerDTO
{
    public string FirstName { get; set; }
    public string LastName { get; set;}

    public static CustomerDTO FromCustomer(Customer customer)
    {
        return new CustomerDTO() 
        {
            FirstName = customer.FirstName,
            LastName = customer.LastName
        };
    }
}
</code></pre>
<p>You can also use a tool like <a href="http://automapper.org/">AutoMapper</a>, which will eliminate the need to use such static factory methods. I usually quickly end up moving to AutoMapper if I have more than a couple of these methods to write myself.</p>
<h3>What about attributes?</h3>
<p>It's common in ASP.NET MVC apps to use attributes from the <code>System.ComponentModel.DataAnnotations</code> namespace to decorate model types for validation purposes. For example, you can add a <code>Required</code> attribute to a property, and during model binding if that property isn't, an error will be added to a collection of validation errors. Since these attributes don't impact your ability to work with the class as a DTO, and since typically the DTO is tailor made for the purpose of doing this binding, I think it's perfectly reasonable to use these attributes for this purpose. You can rethink this decision if at some point the attributes start to cause you pain. Follow <a href="http://deviq.com/pain-driven-development/">Pain Driven Development (PDD)</a>: if something hurts, take a moment to analyze and correct the problem. Otherwise, keep on delivering value to your customers.</p>
<p>If you're not a fan of attribute-based validation, you can use <a href="https://github.com/JeremySkinner/FluentValidation">Fluent Validation</a> and define your validation logic using a fluent interface. You'll find a link in the show notes.</p>
<h3>Keeping DTOs Pure</h3>
<p>Avoid referencing non-DTO or primitive types from your DTOs. This can pull in dependencies that can make it difficult to secure your DTO. In some cases, it can introduce security vulnerabilities, such as if you have methods accepting input as DTOs, and these DTOs reference entities that your app is directly updating in the database. An attacker could guess at the structure of the entity and perhaps its navigation properties and could add or update data outside of the bounds of what you thought you were accepting. Take care in your update operations to only update specific fields, rather than model binding an entity object from external input and then saving it.</p>
<h3>DTO Dos and Don'ts</h3>
<p>Let's wrap up with some quick dos and don't for Data Transfer Objects:</p>
<ul>
<li>Don't hide the default constructor</li>
<li>Do make properties available via public get and set methods</li>
<li>Don't validate inputs to a DTO</li>
<li>Don't add instance methods to your DTO</li>
<li>Do consolidate mapping logic into static factories</li>
<li>Do consider moving to AutoMapper if you have more than a few such factory methods</li>
<li>Do feel free to use attributes to help with model validation</li>
<li>Don't reference non-DTO types, such as entities, from DTOs</li>
</ul>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="http://automapper.org/">AutoMapper</a></li>
<li><a href="http://deviq.com/pain-driven-development/">Pain Driven Development (PDD)</a></li>
<li><a href="https://github.com/JeremySkinner/FluentValidation">Fluent Validation</a></li>
</ul>
]]></content:encoded>
      <enclosure length="4459049" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/d7d9d59b-bdc4-4d02-a6ce-9f3fdd0c238e/cde0c1e7_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Data Transfer Objects (part 2)</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/d7d9d59b-bdc4-4d02-a6ce-9f3fdd0c238e/3000x3000/1507473392artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:06:48</itunes:duration>
      <itunes:summary>One classification of objects in many applications is the Data Transfer Object, or DTO. Here are some more tips that may help you avoid problems when using these objects.</itunes:summary>
      <itunes:subtitle>One classification of objects in many applications is the Data Transfer Object, or DTO. Here are some more tips that may help you avoid problems when using these objects.</itunes:subtitle>
      <itunes:keywords>dto, object oriented design, data transfer object, programming, software</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>9</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">a47346a1-658e-498d-8c8e-07122676eae1</guid>
      <title>Data Transfer Objects (part 1)</title>
      <description><![CDATA[<h1>Data Transfer Object Tips (Part 1)</h1>
<p>One classification of objects in many applications is the Data Transfer Object, or DTO. Here are some tips that may help you avoid problems when using these objects.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>Data Transfer Objects, or DTOs, are, as the name suggests, objects whose main purpose is to transfer data. In Object Oriented Programming, we typically think about objects as encapsulating together state, or data, and behavior. DTOs have the distinction of being all about the data side of things, without the behavior.</p>
<h3>Why do we need DTOs?</h3>
<p>DTOs are used as <em>messages</em>. They transfer information from one part of an application to another. Depending on where and how they transfer information, they might have different names. Often, they're simply referred to as DTOs. In some cases, you may see them characterized as View Models, API Models, or Binding Models. Not all view models in MVC apps are DTOs, but many can and probably should be. For instance, in an ASP.NET MVC application, you typically don't want to have any behavior in the ViewModel type that you pass from a controller action to a view. It's just data that you want to pass to the view in a strongly typed fashion. If you're following the MVVM pattern to build apps using WPF or something similar, then your ViewModel in that scenario is supposed to have behavior, not be a DTO. Ideally we'll come up with a better name for ViewModels in MVC apps, but obvious choices like ViewData are already overloaded.</p>
<h3>Why shouldn't DTOs have behavior?</h3>
<p>DTOs don't have behavior because if they did, they wouldn't be DTOs. Their entire purpose is to transfer data, not to have behavior. And because they are purely data objects, they can easily be serialized and deserialized into JSON, XML, etc. Your DTO's data schema can be published and external systems can send data to your system in a wire format that your system can translate into an instance of your DTO. If your DTO has behavior on it, for instance to ensure its properties are only set to valid values, this behavior won't exist in the string representation of the object. Furthermore, depending on how you coded it, you might not be able to deserialize objects coming from external sources. They might not follow contraints you've set, or you might not have provided a default public constructor, for instance.</p>
<p>The goal of DTOs is simply to hold some state, so you can set it in one place and access it in another. To that end, the properties on a DTO should all have public get and set methods. There's no need to try to implement encapsulation or data hiding in a DTO.</p>
<p>That's it for this week. Next week I'll talk some more about DTOs and provide a list of Do's and Don'ts.</p>
]]></description>
      <pubDate>Mon, 9 Oct 2017 06:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h1>Data Transfer Object Tips (Part 1)</h1>
<p>One classification of objects in many applications is the Data Transfer Object, or DTO. Here are some tips that may help you avoid problems when using these objects.</p>
<h2>Sponsor - DevIQ</h2>
<p>Thanks to DevIQ for sponsoring this episode! Check out their <a href="http://app.deviq.com/">list of available courses and how-to videos</a>.</p>
<h2>Show Notes / Transcript</h2>
<p>Data Transfer Objects, or DTOs, are, as the name suggests, objects whose main purpose is to transfer data. In Object Oriented Programming, we typically think about objects as encapsulating together state, or data, and behavior. DTOs have the distinction of being all about the data side of things, without the behavior.</p>
<h3>Why do we need DTOs?</h3>
<p>DTOs are used as <em>messages</em>. They transfer information from one part of an application to another. Depending on where and how they transfer information, they might have different names. Often, they're simply referred to as DTOs. In some cases, you may see them characterized as View Models, API Models, or Binding Models. Not all view models in MVC apps are DTOs, but many can and probably should be. For instance, in an ASP.NET MVC application, you typically don't want to have any behavior in the ViewModel type that you pass from a controller action to a view. It's just data that you want to pass to the view in a strongly typed fashion. If you're following the MVVM pattern to build apps using WPF or something similar, then your ViewModel in that scenario is supposed to have behavior, not be a DTO. Ideally we'll come up with a better name for ViewModels in MVC apps, but obvious choices like ViewData are already overloaded.</p>
<h3>Why shouldn't DTOs have behavior?</h3>
<p>DTOs don't have behavior because if they did, they wouldn't be DTOs. Their entire purpose is to transfer data, not to have behavior. And because they are purely data objects, they can easily be serialized and deserialized into JSON, XML, etc. Your DTO's data schema can be published and external systems can send data to your system in a wire format that your system can translate into an instance of your DTO. If your DTO has behavior on it, for instance to ensure its properties are only set to valid values, this behavior won't exist in the string representation of the object. Furthermore, depending on how you coded it, you might not be able to deserialize objects coming from external sources. They might not follow contraints you've set, or you might not have provided a default public constructor, for instance.</p>
<p>The goal of DTOs is simply to hold some state, so you can set it in one place and access it in another. To that end, the properties on a DTO should all have public get and set methods. There's no need to try to implement encapsulation or data hiding in a DTO.</p>
<p>That's it for this week. Next week I'll talk some more about DTOs and provide a list of Do's and Don'ts.</p>
]]></content:encoded>
      <enclosure length="2769324" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/41bdb434-f976-453e-9545-945926d77031/d2a763a5_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Data Transfer Objects (part 1)</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/41bdb434-f976-453e-9545-945926d77031/3000x3000/1507471716artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:04:14</itunes:duration>
      <itunes:summary>One classification of objects in many applications is the Data Transfer Object, or DTO. Here are some tips that may help you avoid problems when using these objects.</itunes:summary>
      <itunes:subtitle>One classification of objects in many applications is the Data Transfer Object, or DTO. Here are some tips that may help you avoid problems when using these objects.</itunes:subtitle>
      <itunes:keywords>dto, object oriented development, programming, software, data</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>8</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">066024d6-331f-4ede-ae23-8b7d46bb745f</guid>
      <title>Prefer Custom Exceptions</title>
      <description><![CDATA[<h1>Prefer Custom Exceptions</h1><p>Low level built-in exception types offer little context and are much harder to diagnose than custom exceptions that can use the language of the model or application.</p><h2>Sponsor - DevIQ</h2><p>Thanks to DevIQ for sponsoring this episode!</p><h2>Show Notes / Transcript</h2><p>Given the choice, avoid throwing basic exception types like <code>Exception</code>, <code>ApplicationException</code>, and <code>SystemException</code> from your application code. Instead, create your own exception types that inherit from <code>System.Exception</code>. You can also catch common but difficult-to-diagnose exceptions like <code>NullReferenceException</code> and wrap them in your own application-specific exceptions. You should think about your application exceptions as being part of your domain model. They represent known bad states that your system can find itself in or having to deal with. You should be able to use your <i>ubiquitous language</i> to discuss these exceptions and their sources within the system with your non-technical domain experts and stakeholders. Let's talk about a few different examples.</p><h3>Throwing Low-Level Exceptions</h3><p>Consider some code that does the following:</p><pre><code>public decimal CalculateShipping(string zipCode){    var area = GetAreaFromZipcode(zipcode);    if (area == null)    {        throw new Exception("Unknown ZIP Code");    }    // perform shipping calculation}</code></pre><p>The problem with this kind of code is, client code that attempts to catch exceptions resulting from the shipping calculation are forced to catch generic <code>Exception</code> instances, instead of a more specific exception type. It takes very little code to create a custom exception type for application-specific exceptions like this one:</p><pre><code>public class UnknownZipCodeException : Exception{    public string ZipCode { get; private set; }    public UnknownZipCodeException(string message,         string zipCode) : base(message)    {        ZipCode = zipCode;    }}</code></pre><p>In fact, in many cases you can create an overload that sets a standard default exception message, so you're consistent and your code is more expressive with fewer magic strings. Add this overload to the above exception, for instance:</p><pre><code>public UnknownZipCodeException(string zipCode)         :this("Unknown ZIP Code",zipCode){}</code></pre><p>And now the original code can change to:</p><pre><code>public decimal CalculateShipping(string zipCode){    var area = GetAreaFromZipcode(zipcode);    if (area == null)    {        throw new UnknownZipCodeException(zipCode);    }    // perform shipping calculation}</code></pre><p>Now client code can easily catch and handle the <code>UnkownZipcodeException</code> type, resulting in a more robust and intuitive design.</p><h3>Replace Framework Exceptions with Custom Exceptions</h3><p>An easy way to make your software easier to work with, both for your users and for developers, is to use higher level custom exceptions instead of low level exceptions. Low level exceptions like <code>NullReferenceException</code> should rarely be returned from business-level classes, where most of your custom logic should reside. By using custom exceptions, you make it much more clear to everybody involved what the actual problem is. You're working at a higher abstraction level, using the language of the business domain.</p><p>For example, let’s say you’re writing an application that works with a database. Perhaps it’s an ASP.NET Core application in the medical or insurance industry, and it references individual customers as Subjects. Within some business logic dedicated to creating an invoice, recording a prescription, or filing a claim, there’s a reference to the Subject Id that is invalid. When your data layer makes the request and returns from the database, the result is empty.</p><pre><code>var subject = GetSubject(subjectId);subject.DoSomething();</code></pre><p>Obviously in this code, if Subject is null, the last line is going to throw an exception (you can avoid this by using the <a href="https://deviq.com/design-patterns/null-object-pattern">Null Object Pattern</a>). Let’s further assume that we can’t handle this exception here – if the subject id is incorrect, there’s nothing else for this method to do but throw an exception, since it was going to return the subject otherwise. The current behavior for a user, tester, or developer is this:</p><pre><code>Unhandled Exception:System.NullReferenceException: Object reference not set to an instance of an object.</code></pre><p>One of the most annoying things about the NullReferenceException is that it is so vague. It never actually specifies which reference, exactly, was not set to an instance of an object. This can make debugging, or reporting problems, much more difficult. In the above example, we’re not specifically throwing any exception, but we are allowing a NullReferenceException to be thrown in the event that we’re unsuccessful in looking up a Subject for a given ID. It’s still a part of our design to rely on NullReferenceException, though in this case it’s implicit. What if instead of returning null from GetSubject we threw a SubjectNotFoundException? Or if we weren’t sure that an exception made sense in every scenario, what if we checked for null and then threw a better exception before moving on to work with the returned subject, like in this example:</p><pre><code>var subject = GetSubject(subjectId);if (subject == null) throw new SubjectNotFoundException(subjectId);subject.DoSomething();</code></pre><p>If we don’t follow this approach, and instead we let the NullReference propagate up the stack, it’s likely (if the application doesn’t simply show a Yellow Screen of Death or a default Oops page) that we will try to catch NullReferenceException and inform the user of what might be the problem. But by then we might be so far removed from the exception that even we can’t know for sure what might have been null and resulted in the exception being thrown. It's also possible that this exception might be thrown in the middle of a long multi-line LINQ statement or object initializer, making it difficult to know what, exactly, was null. Raising a more specific, higher level exception makes our own exception handlers much easier to write.</p><h4>Writing Custom Exceptions</h4><p>As I described earlier, it's very easy to write a custom exception for the case where no Subject exists for a given Subject ID. You should name it something very specific, and end the name with the <code>Exception</code> suffix. In this case, we're going to call it <code>SubjectDoesNotExistException</code> (or maybe <code>SubjectNotFoundException</code>), since that seems very clear to me. You can create a class that inherits from <code>Exception</code> and use <i>constructor chaining</i> to pass in some information to the base <code>Exception</code> constructor, like this:</p><pre><code>public class SubjectDoesNotExistException : Exception{    public SubjectDoesNotExistException(int subjectId)        : base($"Subject with ID \"{subjectId}\" does not exist.")    { }}</code></pre><p>(you'll find code samples in the show notes for <a href="https://www.weeklydevtips.com/007">www.weeklydevtips.com/007</a>)</p><p>Now in the example above, with no error handling in place, the user will get a message stating "Subject with ID 123 does not exist." instead of "Object reference not set to an instance of an object." which is far more useful for debugging or reporting purposes. In general, you should avoid putting custom logic into your custom exceptions. In most scenarios, custom exceptions should consist only of a class definition and one or more constructors that chain to the base <code>Exception</code> constructor.</p><p>If you follow <a href="https://www.pluralsight.com/courses/domain-driven-design-fundamentals">domain-driven design</a>, I recommend placing most of your business-logic related exceptions in your Core project, within your domain model. You should be able to easily unit test that these exceptions are thrown when you expect them to be from your entities and services.</p><h2>Show Resources and Links</h2><ul><li><a href="https://ardalis.com/prefer-custom-exceptions-to-framework-exceptions">Prefer Custom Exceptions to Framework Exceptions</a></li><li><a href="https://www.pluralsight.com/courses/domain-driven-design-fundamentals">Domain-Driven Design Fundamentals</a></li><li><a href="https://deviq.com/design-patterns/null-object-pattern">Null Object Pattern</a></li><li><a href="https://deviq.com/principles/dont-repeat-yourself">Don't Repeat Yourself (DRY)</a></li></ul>
]]></description>
      <pubDate>Mon, 25 Sep 2017 06:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h1>Prefer Custom Exceptions</h1><p>Low level built-in exception types offer little context and are much harder to diagnose than custom exceptions that can use the language of the model or application.</p><h2>Sponsor - DevIQ</h2><p>Thanks to DevIQ for sponsoring this episode!</p><h2>Show Notes / Transcript</h2><p>Given the choice, avoid throwing basic exception types like <code>Exception</code>, <code>ApplicationException</code>, and <code>SystemException</code> from your application code. Instead, create your own exception types that inherit from <code>System.Exception</code>. You can also catch common but difficult-to-diagnose exceptions like <code>NullReferenceException</code> and wrap them in your own application-specific exceptions. You should think about your application exceptions as being part of your domain model. They represent known bad states that your system can find itself in or having to deal with. You should be able to use your <i>ubiquitous language</i> to discuss these exceptions and their sources within the system with your non-technical domain experts and stakeholders. Let's talk about a few different examples.</p><h3>Throwing Low-Level Exceptions</h3><p>Consider some code that does the following:</p><pre><code>public decimal CalculateShipping(string zipCode){    var area = GetAreaFromZipcode(zipcode);    if (area == null)    {        throw new Exception("Unknown ZIP Code");    }    // perform shipping calculation}</code></pre><p>The problem with this kind of code is, client code that attempts to catch exceptions resulting from the shipping calculation are forced to catch generic <code>Exception</code> instances, instead of a more specific exception type. It takes very little code to create a custom exception type for application-specific exceptions like this one:</p><pre><code>public class UnknownZipCodeException : Exception{    public string ZipCode { get; private set; }    public UnknownZipCodeException(string message,         string zipCode) : base(message)    {        ZipCode = zipCode;    }}</code></pre><p>In fact, in many cases you can create an overload that sets a standard default exception message, so you're consistent and your code is more expressive with fewer magic strings. Add this overload to the above exception, for instance:</p><pre><code>public UnknownZipCodeException(string zipCode)         :this("Unknown ZIP Code",zipCode){}</code></pre><p>And now the original code can change to:</p><pre><code>public decimal CalculateShipping(string zipCode){    var area = GetAreaFromZipcode(zipcode);    if (area == null)    {        throw new UnknownZipCodeException(zipCode);    }    // perform shipping calculation}</code></pre><p>Now client code can easily catch and handle the <code>UnkownZipcodeException</code> type, resulting in a more robust and intuitive design.</p><h3>Replace Framework Exceptions with Custom Exceptions</h3><p>An easy way to make your software easier to work with, both for your users and for developers, is to use higher level custom exceptions instead of low level exceptions. Low level exceptions like <code>NullReferenceException</code> should rarely be returned from business-level classes, where most of your custom logic should reside. By using custom exceptions, you make it much more clear to everybody involved what the actual problem is. You're working at a higher abstraction level, using the language of the business domain.</p><p>For example, let’s say you’re writing an application that works with a database. Perhaps it’s an ASP.NET Core application in the medical or insurance industry, and it references individual customers as Subjects. Within some business logic dedicated to creating an invoice, recording a prescription, or filing a claim, there’s a reference to the Subject Id that is invalid. When your data layer makes the request and returns from the database, the result is empty.</p><pre><code>var subject = GetSubject(subjectId);subject.DoSomething();</code></pre><p>Obviously in this code, if Subject is null, the last line is going to throw an exception (you can avoid this by using the <a href="https://deviq.com/design-patterns/null-object-pattern">Null Object Pattern</a>). Let’s further assume that we can’t handle this exception here – if the subject id is incorrect, there’s nothing else for this method to do but throw an exception, since it was going to return the subject otherwise. The current behavior for a user, tester, or developer is this:</p><pre><code>Unhandled Exception:System.NullReferenceException: Object reference not set to an instance of an object.</code></pre><p>One of the most annoying things about the NullReferenceException is that it is so vague. It never actually specifies which reference, exactly, was not set to an instance of an object. This can make debugging, or reporting problems, much more difficult. In the above example, we’re not specifically throwing any exception, but we are allowing a NullReferenceException to be thrown in the event that we’re unsuccessful in looking up a Subject for a given ID. It’s still a part of our design to rely on NullReferenceException, though in this case it’s implicit. What if instead of returning null from GetSubject we threw a SubjectNotFoundException? Or if we weren’t sure that an exception made sense in every scenario, what if we checked for null and then threw a better exception before moving on to work with the returned subject, like in this example:</p><pre><code>var subject = GetSubject(subjectId);if (subject == null) throw new SubjectNotFoundException(subjectId);subject.DoSomething();</code></pre><p>If we don’t follow this approach, and instead we let the NullReference propagate up the stack, it’s likely (if the application doesn’t simply show a Yellow Screen of Death or a default Oops page) that we will try to catch NullReferenceException and inform the user of what might be the problem. But by then we might be so far removed from the exception that even we can’t know for sure what might have been null and resulted in the exception being thrown. It's also possible that this exception might be thrown in the middle of a long multi-line LINQ statement or object initializer, making it difficult to know what, exactly, was null. Raising a more specific, higher level exception makes our own exception handlers much easier to write.</p><h4>Writing Custom Exceptions</h4><p>As I described earlier, it's very easy to write a custom exception for the case where no Subject exists for a given Subject ID. You should name it something very specific, and end the name with the <code>Exception</code> suffix. In this case, we're going to call it <code>SubjectDoesNotExistException</code> (or maybe <code>SubjectNotFoundException</code>), since that seems very clear to me. You can create a class that inherits from <code>Exception</code> and use <i>constructor chaining</i> to pass in some information to the base <code>Exception</code> constructor, like this:</p><pre><code>public class SubjectDoesNotExistException : Exception{    public SubjectDoesNotExistException(int subjectId)        : base($"Subject with ID \"{subjectId}\" does not exist.")    { }}</code></pre><p>(you'll find code samples in the show notes for <a href="https://www.weeklydevtips.com/007">www.weeklydevtips.com/007</a>)</p><p>Now in the example above, with no error handling in place, the user will get a message stating "Subject with ID 123 does not exist." instead of "Object reference not set to an instance of an object." which is far more useful for debugging or reporting purposes. In general, you should avoid putting custom logic into your custom exceptions. In most scenarios, custom exceptions should consist only of a class definition and one or more constructors that chain to the base <code>Exception</code> constructor.</p><p>If you follow <a href="https://www.pluralsight.com/courses/domain-driven-design-fundamentals">domain-driven design</a>, I recommend placing most of your business-logic related exceptions in your Core project, within your domain model. You should be able to easily unit test that these exceptions are thrown when you expect them to be from your entities and services.</p><h2>Show Resources and Links</h2><ul><li><a href="https://ardalis.com/prefer-custom-exceptions-to-framework-exceptions">Prefer Custom Exceptions to Framework Exceptions</a></li><li><a href="https://www.pluralsight.com/courses/domain-driven-design-fundamentals">Domain-Driven Design Fundamentals</a></li><li><a href="https://deviq.com/design-patterns/null-object-pattern">Null Object Pattern</a></li><li><a href="https://deviq.com/principles/dont-repeat-yourself">Don't Repeat Yourself (DRY)</a></li></ul>
]]></content:encoded>
      <enclosure length="6933823" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/a142b62a-7996-42f3-a40d-6787a2491ba8/de522fdc_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Prefer Custom Exceptions</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/a142b62a-7996-42f3-a40d-6787a2491ba8/3000x3000/1506433695artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:11:38</itunes:duration>
      <itunes:summary>Low level built-in exception types offer little context and are much harder to diagnose than custom exceptions that can use the language of the model or application.</itunes:summary>
      <itunes:subtitle>Low level built-in exception types offer little context and are much harder to diagnose than custom exceptions that can use the language of the model or application.</itunes:subtitle>
      <itunes:keywords>clean code, programming, exceptions</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>7</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">f242cd3a-5f9d-4c8e-b1cc-17cf5e176dc0</guid>
      <title>Make It Work. Make It Right. Make It Fast.</title>
      <description><![CDATA[<h1>Make It (Work|Right|Fast)</h1><p>Don't fall into the premature optimization trap. Follow this sequence when developing new features.</p><h2>Sponsor - DevIQ</h2><p>Thanks to DevIQ for sponsoring this episode!</p><h2>Show Notes / Transcript</h2><p>There's a three step process that I first heard of from Kent Beck. Following these steps when implementing a new feature can help you remain focused on getting the work done, and can avoid falling into the trap of premature optimization.</p><h3>The First Step: Make it <i>work</i></h3><p>The first step is to make it work. Since we're talking about software, there is no cost of materials. You can make the code do what it's supposed to do in whatever ugly, messy manner you want, so long as it works. Don't waste time worrying about whether your approach is ideal, your code elegant, or your design patterns perfect. If you can see multiple ways to do something, and you're not sure which is best, pick one and go with it. You can leave a TODO comment or make a note in your notebook that you keep with you as you code if you think it's important enough to revisit. Otherwise, when you're done, be sure it works, and works repeatably. You should have some kind of automated tests that demonstrate that it works. I should probably also note that this process works best with small units of work. In fact, <a href="https://www.pluralsight.com/courses/kanban-getting-started">kanban</a> demonstrates that your overall process will be improved if you work on the smallest scoped work items you can. You should be able to follow all three of these steps multiple times per day. If you're spending days or longer just trying to make it work, you need to come up with a smaller "it" and get the reduced scope item to work, first. Then move on to steps two and three before continuing on with the larger scoped work.</p><h3>The Second Step: Make it <i>right</i></h3><p>Once you have a working solution, and an inexpensive way to ensure it remains working while you modify it, follow the <a href="https://www.pluralsight.com/courses/refactoring-csharp-developers">refactoring fundamentals</a> to improve your code's design. Look for <a href="https://deviq.com/antipatterns/code-smells">code smells</a>. Follow software <a href="https://deviq.com/principles/principles-overview">principles</a>. Make sure it's good enough that when you return to it, you'll be able to understand and change it without too much effort (or someone else will be able to do so). Tests serve as a great form of documentation, especially if you <a href="https://ardalis.com/unit-test-naming-convention">name them well</a>. If you think you need more tests, or you need to better organize your tests, this is the time to do so. But stop when you have enough tests that when they're green, you're confident your code does what it should. Don't chase some arbitrary metric beyond this point, when you could be delivering more value in the form of more features or bug fixes.</p><h3>The Third Step: Make it <i>fast</i></h3><p>If it's not fast (in terms of performance) enough already, now is the time to <a href="https://app.pluralsight.com/courses/web-perf">measure and tune the application's performance</a>. Performance characteristics of the system should be described just like other system requirements, and effort should be made on improving performance only until these measurable requirements are met (otherwise, how will you know when you're done?). For some applications, there is great ROI for every small bit of performance improvement. This is true of large, public ecommerce sites like Amazon.com, where they've measured customer cart abandonment levels increasing based on milliseconds of additional latency. However, most applications have less stringent requirements, and in many cases users who have no choice but to use the system for their job. In such cases, you want to provide the user with good enough performance, but remember that <a href="https://ardalis.com/beyond-good-enough-is-waste">beyond good enough is waste</a>. If users don't really notice the difference between 1 second page load times and 800ms page load times, you probably don't need to spend several hours trying to trim 200ms when that time could have been spent fixing a bug that's been plaguing users for weeks.</p><h3>Summary</h3><p>Your key takeaways from this episode should be:</p><ul><li>Work on small pieces of work. For each piece:</li><li>Make it work</li><li>Make it right</li><li>Make it fast</li></ul><p>Stop working on the code as soon as it work. Stop cleaning it up and adding tests as soon as you're confident it works and is clean enough to maintain next time someone needs to touch it. Stop tuning its performance as soon as it's good enough. If you follow these steps, you'll stay as productive as possible, you'll ship quality software, and you won't get mired in analysis paralysis or gold plating your code. Check the show notes at weeklydevtips.com/006 for a bunch of links to more information on many of the things I mentioned in this episode.</p><h2>Show Resources and Links</h2><ul><li><a href="https://www.pluralsight.com/courses/kanban-getting-started">Kanban: Getting Started</a></li><li><a href="https://www.pluralsight.com/courses/refactoring-fundamentals">Refactoring Fundamentals</a></li><li><a href="https://deviq.com/antipatterns/code-smells">List of Code Smells</a></li><li><a href="https://deviq.com/principles/principles-overview">List of Software Principles</a></li><li><a href="https://ardalis.com/unit-test-naming-convention">Unit Test Naming Convention</a></li><li><a href="https://www.pluralsight.com/courses/web-perf">Measuring and Tuning Web Performance</a></li><li><a href="https://ardalis.com/beyond-good-enough-is-waste">Beyond Good Enough is Waste</a></li></ul>
]]></description>
      <pubDate>Mon, 18 Sep 2017 06:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h1>Make It (Work|Right|Fast)</h1><p>Don't fall into the premature optimization trap. Follow this sequence when developing new features.</p><h2>Sponsor - DevIQ</h2><p>Thanks to DevIQ for sponsoring this episode!</p><h2>Show Notes / Transcript</h2><p>There's a three step process that I first heard of from Kent Beck. Following these steps when implementing a new feature can help you remain focused on getting the work done, and can avoid falling into the trap of premature optimization.</p><h3>The First Step: Make it <i>work</i></h3><p>The first step is to make it work. Since we're talking about software, there is no cost of materials. You can make the code do what it's supposed to do in whatever ugly, messy manner you want, so long as it works. Don't waste time worrying about whether your approach is ideal, your code elegant, or your design patterns perfect. If you can see multiple ways to do something, and you're not sure which is best, pick one and go with it. You can leave a TODO comment or make a note in your notebook that you keep with you as you code if you think it's important enough to revisit. Otherwise, when you're done, be sure it works, and works repeatably. You should have some kind of automated tests that demonstrate that it works. I should probably also note that this process works best with small units of work. In fact, <a href="https://www.pluralsight.com/courses/kanban-getting-started">kanban</a> demonstrates that your overall process will be improved if you work on the smallest scoped work items you can. You should be able to follow all three of these steps multiple times per day. If you're spending days or longer just trying to make it work, you need to come up with a smaller "it" and get the reduced scope item to work, first. Then move on to steps two and three before continuing on with the larger scoped work.</p><h3>The Second Step: Make it <i>right</i></h3><p>Once you have a working solution, and an inexpensive way to ensure it remains working while you modify it, follow the <a href="https://www.pluralsight.com/courses/refactoring-csharp-developers">refactoring fundamentals</a> to improve your code's design. Look for <a href="https://deviq.com/antipatterns/code-smells">code smells</a>. Follow software <a href="https://deviq.com/principles/principles-overview">principles</a>. Make sure it's good enough that when you return to it, you'll be able to understand and change it without too much effort (or someone else will be able to do so). Tests serve as a great form of documentation, especially if you <a href="https://ardalis.com/unit-test-naming-convention">name them well</a>. If you think you need more tests, or you need to better organize your tests, this is the time to do so. But stop when you have enough tests that when they're green, you're confident your code does what it should. Don't chase some arbitrary metric beyond this point, when you could be delivering more value in the form of more features or bug fixes.</p><h3>The Third Step: Make it <i>fast</i></h3><p>If it's not fast (in terms of performance) enough already, now is the time to <a href="https://app.pluralsight.com/courses/web-perf">measure and tune the application's performance</a>. Performance characteristics of the system should be described just like other system requirements, and effort should be made on improving performance only until these measurable requirements are met (otherwise, how will you know when you're done?). For some applications, there is great ROI for every small bit of performance improvement. This is true of large, public ecommerce sites like Amazon.com, where they've measured customer cart abandonment levels increasing based on milliseconds of additional latency. However, most applications have less stringent requirements, and in many cases users who have no choice but to use the system for their job. In such cases, you want to provide the user with good enough performance, but remember that <a href="https://ardalis.com/beyond-good-enough-is-waste">beyond good enough is waste</a>. If users don't really notice the difference between 1 second page load times and 800ms page load times, you probably don't need to spend several hours trying to trim 200ms when that time could have been spent fixing a bug that's been plaguing users for weeks.</p><h3>Summary</h3><p>Your key takeaways from this episode should be:</p><ul><li>Work on small pieces of work. For each piece:</li><li>Make it work</li><li>Make it right</li><li>Make it fast</li></ul><p>Stop working on the code as soon as it work. Stop cleaning it up and adding tests as soon as you're confident it works and is clean enough to maintain next time someone needs to touch it. Stop tuning its performance as soon as it's good enough. If you follow these steps, you'll stay as productive as possible, you'll ship quality software, and you won't get mired in analysis paralysis or gold plating your code. Check the show notes at weeklydevtips.com/006 for a bunch of links to more information on many of the things I mentioned in this episode.</p><h2>Show Resources and Links</h2><ul><li><a href="https://www.pluralsight.com/courses/kanban-getting-started">Kanban: Getting Started</a></li><li><a href="https://www.pluralsight.com/courses/refactoring-fundamentals">Refactoring Fundamentals</a></li><li><a href="https://deviq.com/antipatterns/code-smells">List of Code Smells</a></li><li><a href="https://deviq.com/principles/principles-overview">List of Software Principles</a></li><li><a href="https://ardalis.com/unit-test-naming-convention">Unit Test Naming Convention</a></li><li><a href="https://www.pluralsight.com/courses/web-perf">Measuring and Tuning Web Performance</a></li><li><a href="https://ardalis.com/beyond-good-enough-is-waste">Beyond Good Enough is Waste</a></li></ul>
]]></content:encoded>
      <enclosure length="3356194" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/1989815c-0896-4f93-b30d-6d35b8e991ce/0579d90a_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Make It Work. Make It Right. Make It Fast.</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/1989815c-0896-4f93-b30d-6d35b8e991ce/3000x3000/1505750556artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:05:17</itunes:duration>
      <itunes:summary>Don&apos;t fall into the premature optimization trap. Follow this sequence when developing new features.</itunes:summary>
      <itunes:subtitle>Don&apos;t fall into the premature optimization trap. Follow this sequence when developing new features.</itunes:subtitle>
      <itunes:keywords>development, programming, software, getting things done, tips</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>6</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">07b8c23b-5793-45aa-9016-6a9aeb57eff0</guid>
      <title>New is Glue</title>
      <description><![CDATA[<h1>New is Glue</h1><p>Be wary of the new keyword in your code, and recognize the decision you're making by using it.</p><h2>Show Notes / Transcript</h2><p>This week we're going to talk about the phrase, "New is Glue". I came up with this phrase a few years ago and wrote a blog post about it, and have incorporated it into a number of my conference presentations and training courses on <a href="https://www.pluralsight.com/authors/steve-smith">Pluralsight</a> and <a href="https://deviq.com/">DevIQ</a>. The goal of the phrase is to stick in developers' heads so that when they are writing or reviewing code that directly instantiates an object, they understand that this is tightly coupling their code to that particular object implementation. Let's step back for a moment and talk about coupling, and then return to why tight coupling and the new keyword can be problematic.</p><h3>Coupling</h3><p>Your software is going to be coupled to a variety of things in order to function. Software that has no coupling is too abstract to actually do anything. Some things, like your choice of framework or language, are likely tight coupling decisions you're happy with because you've considered the alternatives and are satisfied that you can achieve your application's goals in the language and framework of choice. Other things, like the infrastructure your application depends on, might be tightly or loosely coupled depending on how you write your code. Code that is tightly coupled to a particular file system or a particular vendor's database tends to be more difficult to test, change, and maintain than software that is loosely coupled to its infrastructure. Although coupling is unavoidable, you want to make a conscious decision about whether and where you want to tightly couple your code to specific implementations, rather than having accidental coupling spread throughout your codebase.</p><h3>Couplers</h3><p>There are typically three ways in which code references specific implementations in a tightly coupled manner. Each of these violates the <a href="https://www.pluralsight.com/courses/csharp-solid-principles">Open-Closed Principle</a> since functions that use these techniques cannot change their implementation logic without the code itself being changed. The first two are making calls to static methods and the closely related technique of referencing a Singleton pattern instance, particularly when accessed using a static Instance method (making this just a variation of the static method call). The third is the use of the new keyword to directly instantiate a particular instance type. Your application needs to work with certain implementation types in order to be useful, but the decision of which implementation types to use should be made in ideally one place, not scattered throughout your system.</p><h3>When is new a problem?</h3><p>Using the new keyword can be a problem when the type being created is not just a POCO, or Plain Old CLR Type, and especially when the type has side effects that make the calling logic difficult to test in isolation. If you find yourself instantiating a string or a DateTime in a function, or a custom DTO, that's probably not going to make that function any more difficult to test. The fact that you're gluing your code to that particular implementation is not a large concern, so you should recognize it but move on because it isn't a major risk to the software's maintainability.</p><p>However, if you discover a function that is directly instantiating a SqlConnection that, during its construction, immediately tries to connect to a database server and throws an exception if it can't find one, that presents a much bigger risk. Without special tools, there's no simple way to test the calling code in a way that doesn't involve setting up a real database for it to try to connect to. Further, the lack of abstraction around the connection may make it more difficult to implement connection pooling, caching, or a different kind of data store. If you find code like this in your data access layer, implementing an interface, then it's probably fine and in the right location. If you find it in your business logic or UI layer, you should think long and hard before you decide it's a good risk to tightly couple to a particular data technology from this location in your code.</p><h3>Is new bad?</h3><p>The point of "New is Glue" is not to say that "new is bad", but rather to raise awareness. You should <i>think</i> about the fact that you're tightly coupling the current function or class to a particular implementation when you use the new keyword. In many cases, after briefly considering this, you'll conclude that you're fine with the coupling and continue on. But in some cases you may realize that you're about to add tight coupling to an implementation, and the current code isn't where you want to make that decision. In that case, you'll want to <a href="https://www.pluralsight.com/courses/refactoring-csharp-developers">refactor</a> your code so that it works with an abstraction and some other code is responsible for providing the actual implementation the function or class will use.</p><h3>What about in tests?</h3><p>Often, our unit tests become very brittle and slow us down when there is a lot of repetition in them. Repeatedly instantiating types to be tested within each test is a common problem. You can mitigate this issue by ensuring that your code for creating a class for test purposes in a particular way only exists at most once per test class, rather than once per test. You can easily achieve this by placing instantiation logic in setup or constructor methods of your test classes. You can further extract common construction logic from your tests by using the Builder design pattern and having common builder classes that all of your test classes rely on to create the instances they will use. With these approaches in place, changes to how objects are instantiated will require minimal changes in your tests.</p><h2>Show Resources and Links</h2><ul><li><a href="https://ardalis.com/new-is-glue">New is Glue</a></li><li><a href="https://ardalis.com/Tight-Coupling,-Legos,-and-Super-Glue">Tight Coupling, LEGOs, and Super Glue</a></li><li><a href="https://ardalis.com/tips">Weekly Dev Tips Email</a></li><li><a href="https://www.pluralsight.com/courses/csharp-solid-principles">SOLID Principles for C# Developers</a></li><li><a href="https://www.pluralsight.com/courses/principles-oo-design">SOLID Principles of Object-Oriented Design</a></li><li><a href="https://www.pluralsight.com/courses/refactoring-csharp-developers">Refactoring for C# Developers</a></li><li><a href="https://www.pluralsight.com/courses/refactoring-fundamentals">Refactoring Fundamentals</a></li></ul>
]]></description>
      <pubDate>Mon, 11 Sep 2017 06:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h1>New is Glue</h1><p>Be wary of the new keyword in your code, and recognize the decision you're making by using it.</p><h2>Show Notes / Transcript</h2><p>This week we're going to talk about the phrase, "New is Glue". I came up with this phrase a few years ago and wrote a blog post about it, and have incorporated it into a number of my conference presentations and training courses on <a href="https://www.pluralsight.com/authors/steve-smith">Pluralsight</a> and <a href="https://deviq.com/">DevIQ</a>. The goal of the phrase is to stick in developers' heads so that when they are writing or reviewing code that directly instantiates an object, they understand that this is tightly coupling their code to that particular object implementation. Let's step back for a moment and talk about coupling, and then return to why tight coupling and the new keyword can be problematic.</p><h3>Coupling</h3><p>Your software is going to be coupled to a variety of things in order to function. Software that has no coupling is too abstract to actually do anything. Some things, like your choice of framework or language, are likely tight coupling decisions you're happy with because you've considered the alternatives and are satisfied that you can achieve your application's goals in the language and framework of choice. Other things, like the infrastructure your application depends on, might be tightly or loosely coupled depending on how you write your code. Code that is tightly coupled to a particular file system or a particular vendor's database tends to be more difficult to test, change, and maintain than software that is loosely coupled to its infrastructure. Although coupling is unavoidable, you want to make a conscious decision about whether and where you want to tightly couple your code to specific implementations, rather than having accidental coupling spread throughout your codebase.</p><h3>Couplers</h3><p>There are typically three ways in which code references specific implementations in a tightly coupled manner. Each of these violates the <a href="https://www.pluralsight.com/courses/csharp-solid-principles">Open-Closed Principle</a> since functions that use these techniques cannot change their implementation logic without the code itself being changed. The first two are making calls to static methods and the closely related technique of referencing a Singleton pattern instance, particularly when accessed using a static Instance method (making this just a variation of the static method call). The third is the use of the new keyword to directly instantiate a particular instance type. Your application needs to work with certain implementation types in order to be useful, but the decision of which implementation types to use should be made in ideally one place, not scattered throughout your system.</p><h3>When is new a problem?</h3><p>Using the new keyword can be a problem when the type being created is not just a POCO, or Plain Old CLR Type, and especially when the type has side effects that make the calling logic difficult to test in isolation. If you find yourself instantiating a string or a DateTime in a function, or a custom DTO, that's probably not going to make that function any more difficult to test. The fact that you're gluing your code to that particular implementation is not a large concern, so you should recognize it but move on because it isn't a major risk to the software's maintainability.</p><p>However, if you discover a function that is directly instantiating a SqlConnection that, during its construction, immediately tries to connect to a database server and throws an exception if it can't find one, that presents a much bigger risk. Without special tools, there's no simple way to test the calling code in a way that doesn't involve setting up a real database for it to try to connect to. Further, the lack of abstraction around the connection may make it more difficult to implement connection pooling, caching, or a different kind of data store. If you find code like this in your data access layer, implementing an interface, then it's probably fine and in the right location. If you find it in your business logic or UI layer, you should think long and hard before you decide it's a good risk to tightly couple to a particular data technology from this location in your code.</p><h3>Is new bad?</h3><p>The point of "New is Glue" is not to say that "new is bad", but rather to raise awareness. You should <i>think</i> about the fact that you're tightly coupling the current function or class to a particular implementation when you use the new keyword. In many cases, after briefly considering this, you'll conclude that you're fine with the coupling and continue on. But in some cases you may realize that you're about to add tight coupling to an implementation, and the current code isn't where you want to make that decision. In that case, you'll want to <a href="https://www.pluralsight.com/courses/refactoring-csharp-developers">refactor</a> your code so that it works with an abstraction and some other code is responsible for providing the actual implementation the function or class will use.</p><h3>What about in tests?</h3><p>Often, our unit tests become very brittle and slow us down when there is a lot of repetition in them. Repeatedly instantiating types to be tested within each test is a common problem. You can mitigate this issue by ensuring that your code for creating a class for test purposes in a particular way only exists at most once per test class, rather than once per test. You can easily achieve this by placing instantiation logic in setup or constructor methods of your test classes. You can further extract common construction logic from your tests by using the Builder design pattern and having common builder classes that all of your test classes rely on to create the instances they will use. With these approaches in place, changes to how objects are instantiated will require minimal changes in your tests.</p><h2>Show Resources and Links</h2><ul><li><a href="https://ardalis.com/new-is-glue">New is Glue</a></li><li><a href="https://ardalis.com/Tight-Coupling,-Legos,-and-Super-Glue">Tight Coupling, LEGOs, and Super Glue</a></li><li><a href="https://ardalis.com/tips">Weekly Dev Tips Email</a></li><li><a href="https://www.pluralsight.com/courses/csharp-solid-principles">SOLID Principles for C# Developers</a></li><li><a href="https://www.pluralsight.com/courses/principles-oo-design">SOLID Principles of Object-Oriented Design</a></li><li><a href="https://www.pluralsight.com/courses/refactoring-csharp-developers">Refactoring for C# Developers</a></li><li><a href="https://www.pluralsight.com/courses/refactoring-fundamentals">Refactoring Fundamentals</a></li></ul>
]]></content:encoded>
      <enclosure length="4053568" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/0b678cc3-df67-4e2b-948d-572167cf35b8/2e67e5c2_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>New is Glue</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/0b678cc3-df67-4e2b-948d-572167cf35b8/3000x3000/1505149610artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:06:28</itunes:duration>
      <itunes:summary>Be wary of the &apos;new&apos; keyword in your code, and recognize the decision you&apos;re making by using it.</itunes:summary>
      <itunes:subtitle>Be wary of the &apos;new&apos; keyword in your code, and recognize the decision you&apos;re making by using it.</itunes:subtitle>
      <itunes:keywords>craftsmanship, clean code, programming, testing</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>5</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">72a07ffa-c386-44b6-9f20-dcf133b3621a</guid>
      <title>Guard Clauses</title>
      <description><![CDATA[<p>Your methods should fail fast, if doing so can short-circuit their execution. Guard clauses are a programming technique that enables this behavior, resulting in smaller, simpler functions.</p><h2>Show Notes / Transcript</h2><p>Complexity in our code makes it harder for us and others to understand what the code is doing. The smallest unit of our code tends to be the function or method. You should be able to look at a given function and quickly determine what it's doing. This tends to be much easier if the function is small, well-named, and focused. One factor that's constantly working against you as you try to keep your functions manageable is conditional complexity (a <a href="http://deviq.com/code-smells/">code smell</a>) - if and switch statements. When not properly managed, these two constructs can quickly cause functions to shift from simple and easily understood to long, obtuse, and scary. One way you can cut down on some of the complexity is through the use of guard clauses.</p><p>A guard clause is simply a check that immediately exits the function, either with a return statement or an exception. If you're used to writing code such that you check to ensure that everything is valid for the function to run, then you write the main function code, and then you write else statements to deal with error cases, this involves inverting your current workflow. The benefit is that your code will tend to be shorter and simpler, and less deeply indented.</p><p>Imagine you have a method that performs a subscribe operation, and takes in three objects: a user, a subscription, and a term. Naturally, you want to ensure that these objects are not null before you start working with them. One way to structure the method would be to first check if the user is not null. Then, inside this if statement, check if the subscription is not null. And in this statement, check if the term is not null. Now in this statement, we are in what is sometimes referred to as the "happy path" for the function. Assuming the values of these objects are otherwise valid, the expected work of the function can take place in this block. Each of the different cases of invalid inputs should result in an appropriate exception being thrown, though, and so these require else blocks. There will be an else block for the term != null check, another for the subscription != null check, and finally an else block for the user != null check. This results in a fair amount of plumbing code and complexity that adds to the noise of the function and obscures its true purpose - to subscribe a user to a subscription.</p><h3>Refactor to reduce nesting and else statements</h3><p>The first way to address this is to eliminate the need for the else clauses. You can do this by inverting the if checks and putting the exception throwing statements at the start of the function instead of at the end. The first thing you check is if the user is null. If it is, throw an exception. No need for an else clause and no need for a nested if statement. Move on to the next argument. Check it, throw if it's null. Do the same for the third parameter. When you're done, you have 3 simple if statements, none of which are nested, and no else clauses. The function now fails fast, and after the input checks, the happy path for the function is whatever remains.</p><h3>Refactor to use Guard helper methods</h3><p>Checking for null arguments is a common enough task in strongly typed programs that you can probably encapsulate it in its own helper function. I use a common static class I call Guard which provides static helper methods for common scenarios. For instance, in the example I just described, I'm going to want to throw an ArgumentNullException with the name of whichever argument was null in each of the three possible cases. Thus, it's very easy to write a method I call AgainstNull that simply takes in the argument and the argument's name, and throws an ArgumentNullException if the argument is null. This exception will bubble up and out of the calling method. When you implement this in the scenario I described, you end up with code that reads like this:</p><p>Guard.AgainstNull(user, nameof(user));Guard.AgainstNull(subscription, nameof(subscription));Guard.AgainstNull(term, nameof(term));</p><p>You can add additional Guard helper methods for any other common cases you need to check for, such as empty strings, negative numbers, invalid enum values, etc.</p><p>If statements can take over your functions if you're not careful, making them much harder to understand and thus much harder to maintain. Cyclomatic complexity refers to the total number of paths through a given function, and should be kept in the low single digits whenever possible. Using guard clauses is one simple way to tame complexity in your functions and keep them smaller, simpler, and easier to maintain.</p><h2>Show Resources and Links</h2><ul><li><a href="http://deviq.com/guard-clause/">Guard Clauses</a></li><li><a href="https://www.nuget.org/packages/Ardalis.GuardClauses">GuardClauses Nuget Package</a></li><li><a href="https://ardalis.com/tips">Weekly Dev Tips Email</a></li><li><a href="https://www.pluralsight.com/courses/refactoring-fundamentals">Code Smells and Refactoring Course</a></li><li><a href="https://www.pluralsight.com/courses/refactoring-csharp-developers">Refactoring for C# Developers</a></li></ul>
]]></description>
      <pubDate>Mon, 4 Sep 2017 06:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>Your methods should fail fast, if doing so can short-circuit their execution. Guard clauses are a programming technique that enables this behavior, resulting in smaller, simpler functions.</p><h2>Show Notes / Transcript</h2><p>Complexity in our code makes it harder for us and others to understand what the code is doing. The smallest unit of our code tends to be the function or method. You should be able to look at a given function and quickly determine what it's doing. This tends to be much easier if the function is small, well-named, and focused. One factor that's constantly working against you as you try to keep your functions manageable is conditional complexity (a <a href="http://deviq.com/code-smells/">code smell</a>) - if and switch statements. When not properly managed, these two constructs can quickly cause functions to shift from simple and easily understood to long, obtuse, and scary. One way you can cut down on some of the complexity is through the use of guard clauses.</p><p>A guard clause is simply a check that immediately exits the function, either with a return statement or an exception. If you're used to writing code such that you check to ensure that everything is valid for the function to run, then you write the main function code, and then you write else statements to deal with error cases, this involves inverting your current workflow. The benefit is that your code will tend to be shorter and simpler, and less deeply indented.</p><p>Imagine you have a method that performs a subscribe operation, and takes in three objects: a user, a subscription, and a term. Naturally, you want to ensure that these objects are not null before you start working with them. One way to structure the method would be to first check if the user is not null. Then, inside this if statement, check if the subscription is not null. And in this statement, check if the term is not null. Now in this statement, we are in what is sometimes referred to as the "happy path" for the function. Assuming the values of these objects are otherwise valid, the expected work of the function can take place in this block. Each of the different cases of invalid inputs should result in an appropriate exception being thrown, though, and so these require else blocks. There will be an else block for the term != null check, another for the subscription != null check, and finally an else block for the user != null check. This results in a fair amount of plumbing code and complexity that adds to the noise of the function and obscures its true purpose - to subscribe a user to a subscription.</p><h3>Refactor to reduce nesting and else statements</h3><p>The first way to address this is to eliminate the need for the else clauses. You can do this by inverting the if checks and putting the exception throwing statements at the start of the function instead of at the end. The first thing you check is if the user is null. If it is, throw an exception. No need for an else clause and no need for a nested if statement. Move on to the next argument. Check it, throw if it's null. Do the same for the third parameter. When you're done, you have 3 simple if statements, none of which are nested, and no else clauses. The function now fails fast, and after the input checks, the happy path for the function is whatever remains.</p><h3>Refactor to use Guard helper methods</h3><p>Checking for null arguments is a common enough task in strongly typed programs that you can probably encapsulate it in its own helper function. I use a common static class I call Guard which provides static helper methods for common scenarios. For instance, in the example I just described, I'm going to want to throw an ArgumentNullException with the name of whichever argument was null in each of the three possible cases. Thus, it's very easy to write a method I call AgainstNull that simply takes in the argument and the argument's name, and throws an ArgumentNullException if the argument is null. This exception will bubble up and out of the calling method. When you implement this in the scenario I described, you end up with code that reads like this:</p><p>Guard.AgainstNull(user, nameof(user));Guard.AgainstNull(subscription, nameof(subscription));Guard.AgainstNull(term, nameof(term));</p><p>You can add additional Guard helper methods for any other common cases you need to check for, such as empty strings, negative numbers, invalid enum values, etc.</p><p>If statements can take over your functions if you're not careful, making them much harder to understand and thus much harder to maintain. Cyclomatic complexity refers to the total number of paths through a given function, and should be kept in the low single digits whenever possible. Using guard clauses is one simple way to tame complexity in your functions and keep them smaller, simpler, and easier to maintain.</p><h2>Show Resources and Links</h2><ul><li><a href="http://deviq.com/guard-clause/">Guard Clauses</a></li><li><a href="https://www.nuget.org/packages/Ardalis.GuardClauses">GuardClauses Nuget Package</a></li><li><a href="https://ardalis.com/tips">Weekly Dev Tips Email</a></li><li><a href="https://www.pluralsight.com/courses/refactoring-fundamentals">Code Smells and Refactoring Course</a></li><li><a href="https://www.pluralsight.com/courses/refactoring-csharp-developers">Refactoring for C# Developers</a></li></ul>
]]></content:encoded>
      <enclosure length="3999535" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/db1fec76-e6d5-4baf-889f-328da43ffdfe/2121700a_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Guard Clauses</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/db1fec76-e6d5-4baf-889f-328da43ffdfe/3000x3000/1504279341artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:06:27</itunes:duration>
      <itunes:summary>Your methods should fail fast, if doing so can short-circuit their execution. Guard clauses are a programming technique that enables this behavior, resulting in smaller, simpler functions.</itunes:summary>
      <itunes:subtitle>Your methods should fail fast, if doing so can short-circuit their execution. Guard clauses are a programming technique that enables this behavior, resulting in smaller, simpler functions.</itunes:subtitle>
      <itunes:keywords>coding, programming, software, patterns</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>4</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">ee49df26-acd9-494f-9f97-df0a1ec31d15</guid>
      <title>Listen Faster</title>
      <description><![CDATA[<h1>Listen (and learn) Faster</h1>
<p>If you can do it without getting left behind, listen or watch educational content at a higher speed.</p>
<h2>Show Notes / Transcript</h2>
<p>I've always been interested in speed reading. As a child, it seemed like a super-power, since it would dramatically increase how quickly I could consume information, giving me more time to do other things. On a related note, I often have wished for a nice substitute for sleep that didn't have nasty side effects. But I digress...</p>
<h3>Listening faster</h3>
<p>If you're listening to this episode on a phone or mobile device, the app you're using most likely has an option to change the speed. I try to record these at a fairly measured pace, even if I'm otherwise animated or excited by the topic, because  I want to make sure they're understandable even to those of you for whom English is not your first language. However, for those of you who can manage it, I encourage you to listen faster by adjusting the play speed to 1.25 or 1.5x, or even faster if you can manage it. If you're not sure how to configure a particular player, I cover a few options in <a href="https://ardalis.com/life-hack-listen-faster">an article on my blog about listening faster</a>. Look for it in the show notes.</p>
<p>If you're in a web browser on the show's site, there should be a little 1x icon on the right side of the player. Clicking it will cycle you through different speeds. Give it a shot and pick one that's comfortable for you.</p>
<h3>Watching faster</h3>
<p>Of course, there's also a lot of great content online. Whether it's <a href="https://www.youtube.com/channel/UC3n1sreTBOBLaFjNFs_Qx9Q">YouTube</a>, <a href="https://app.deviq.com">DevIQ</a>, or <a href="http://bit.ly/SOLID-OOP">Pluralsight</a>, you can learn a lot about programming and your career in software development from video content. Here, too, you can usually adjust the playback speed. By adjusting the speed from 1x to 1.5x, you can consume a 30 minute presentation in just 20 minutes. Over time, these gains really add up and can make the difference between you falling behind and you passing by others as you compete to be the best you can be.</p>
<h3>Counterpoint</h3>
<p>There are those who disagree, and feel that listening to content at 1.5x (or whatever speed you prefer) messes up the artistic intent of the author. A fairly recent article on The Verge is titled simply <a href="https://www.theverge.com/2015/2/17/8043077/stop-listening-to-podcasts-fast-speed">Stop listening to podcasts at 1.5x speed</a>. I mention this mainly to disagree with it and to give you my permission, as the author and &quot;artist&quot; involved in this podcast, to listen faster.</p>
<p>There may be instances where some subtlety is lost, especially when you're talking about a heavily produced and edited show with multiple speakers involved. I'm going to strive not to be that subtle. My goal for these shows is that they provide you with small, useful, concrete nuggets that you can immediately apply to your work. If you can't consume this information at a faster speed because I'm using too much nuance and subtlety (and not because perhaps English isn't your first language), then I'm failing.</p>
<p>Once I've produced one of these podcasts, I'm done with it. My only goal is that a significant number of developers find it, listen to it, and find it useful. The more content you're able to consume, hopefully the more value you're able to get from it. To that end, I encourage you to listen at a speed that works well for you.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://ardalis.com/life-hack-listen-faster">Life Hack: Listen Faster</a></li>
<li><a href="https://www.theverge.com/2015/2/17/8043077/stop-listening-to-podcasts-fast-speed">Stop Listening to Podcasts at 1.5x</a></li>
</ul>
]]></description>
      <pubDate>Mon, 28 Aug 2017 06:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h1>Listen (and learn) Faster</h1>
<p>If you can do it without getting left behind, listen or watch educational content at a higher speed.</p>
<h2>Show Notes / Transcript</h2>
<p>I've always been interested in speed reading. As a child, it seemed like a super-power, since it would dramatically increase how quickly I could consume information, giving me more time to do other things. On a related note, I often have wished for a nice substitute for sleep that didn't have nasty side effects. But I digress...</p>
<h3>Listening faster</h3>
<p>If you're listening to this episode on a phone or mobile device, the app you're using most likely has an option to change the speed. I try to record these at a fairly measured pace, even if I'm otherwise animated or excited by the topic, because  I want to make sure they're understandable even to those of you for whom English is not your first language. However, for those of you who can manage it, I encourage you to listen faster by adjusting the play speed to 1.25 or 1.5x, or even faster if you can manage it. If you're not sure how to configure a particular player, I cover a few options in <a href="https://ardalis.com/life-hack-listen-faster">an article on my blog about listening faster</a>. Look for it in the show notes.</p>
<p>If you're in a web browser on the show's site, there should be a little 1x icon on the right side of the player. Clicking it will cycle you through different speeds. Give it a shot and pick one that's comfortable for you.</p>
<h3>Watching faster</h3>
<p>Of course, there's also a lot of great content online. Whether it's <a href="https://www.youtube.com/channel/UC3n1sreTBOBLaFjNFs_Qx9Q">YouTube</a>, <a href="https://app.deviq.com">DevIQ</a>, or <a href="http://bit.ly/SOLID-OOP">Pluralsight</a>, you can learn a lot about programming and your career in software development from video content. Here, too, you can usually adjust the playback speed. By adjusting the speed from 1x to 1.5x, you can consume a 30 minute presentation in just 20 minutes. Over time, these gains really add up and can make the difference between you falling behind and you passing by others as you compete to be the best you can be.</p>
<h3>Counterpoint</h3>
<p>There are those who disagree, and feel that listening to content at 1.5x (or whatever speed you prefer) messes up the artistic intent of the author. A fairly recent article on The Verge is titled simply <a href="https://www.theverge.com/2015/2/17/8043077/stop-listening-to-podcasts-fast-speed">Stop listening to podcasts at 1.5x speed</a>. I mention this mainly to disagree with it and to give you my permission, as the author and &quot;artist&quot; involved in this podcast, to listen faster.</p>
<p>There may be instances where some subtlety is lost, especially when you're talking about a heavily produced and edited show with multiple speakers involved. I'm going to strive not to be that subtle. My goal for these shows is that they provide you with small, useful, concrete nuggets that you can immediately apply to your work. If you can't consume this information at a faster speed because I'm using too much nuance and subtlety (and not because perhaps English isn't your first language), then I'm failing.</p>
<p>Once I've produced one of these podcasts, I'm done with it. My only goal is that a significant number of developers find it, listen to it, and find it useful. The more content you're able to consume, hopefully the more value you're able to get from it. To that end, I encourage you to listen at a speed that works well for you.</p>
<h2>Show Resources and Links</h2>
<ul>
<li><a href="https://ardalis.com/life-hack-listen-faster">Life Hack: Listen Faster</a></li>
<li><a href="https://www.theverge.com/2015/2/17/8043077/stop-listening-to-podcasts-fast-speed">Stop Listening to Podcasts at 1.5x</a></li>
</ul>
]]></content:encoded>
      <enclosure length="2107437" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/58ba5149-567a-480b-935e-7b1a18bcbf73/a83415d5_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Listen Faster</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/58ba5149-567a-480b-935e-7b1a18bcbf73/3000x3000/1503603514artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:03:45</itunes:duration>
      <itunes:summary>If you can do it without getting left behind, listen or watch educational content at a higher speed.</itunes:summary>
      <itunes:subtitle>If you can do it without getting left behind, listen or watch educational content at a higher speed.</itunes:subtitle>
      <itunes:keywords>podcasts, life hack, technology</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>3</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">810983af-45b9-4448-9355-07f3b351b1c8</guid>
      <title>Check In Often</title>
      <description><![CDATA[<h1>Check In Often</h1>
<p>As a developer, you should be using source control. You should probably be using distributed source control. And you should check in, probably more often than you think.</p>
<h2>Show Notes</h2>
<p>No matter what specific tool you use for source control, you should be checking in your code to a source control repository. Right now, do you have code that you're working on (or were recently working on) that isn't checked in? How long ago did you check it out? If it's been more than a few hours, that's probably too long to go without checking in your work.</p>
<h3>Why should you commit often?</h3>
<p>The more often you commit your code to a central repository, the sooner you'll discover integration issues. This works best if you're using continuous integration, which we'll talk about later, but even without it, someone else on your team may discover an issue with your code sooner if it's checked in somewhere they can get to it sooner.</p>
<h3>Committing is like ctrl-S.</h3>
<p>If you grew up using word processors like Word, you've probably developed the muscle memory of hitting ctrl-S to save frequently. All it takes is for your machine or application to crash one time while you have hours of unsaved work for you to realize that you really should be saving all the time. The more often you commit your code (and ideally, push changes off your local machine), the better off you are if the unthinkable happens to your machine.</p>
<h3>Recovering from dead ends.</h3>
<p>Of course, an even more common use for frequent commits is that they let you jump back in time when you find that you've gone down a bad path. This, in turn, can give you more confidence to try different approaches to problems or more ambitious refactorings, because you know you can easily jump back to a known good state at any point. One of my favorite sayings is a Turkish proverb, &quot;No matter how far down the wrong path you've gone, turn back now.&quot; When you have an easy restore point to jump to, this is easy. When you don't, it can be tempting to keep fighting with an approach you know in your heart isn't great, simply because going backward is going to be at least as painful as struggling forward.</p>
<h3>Don't use folders for version control.</h3>
<p>Avoid the urge to use copy folder versioning. You know what I'm talking about. That copy of the code folder you made that appends today's date to it, that's sitting next to a dozen similarly named folders. That's not source control, it's undisciplined and sloppy. That's not to say I'm not guilty of doing it myself (this approach still gives me confidence when updating production code on a live server, for instance). But if you're regularly using source control properly, you won't find the need to do this in your local dev environment.</p>
<h3>When should you commit?</h3>
<p>You should be committing your code whenever you've made some tangible progress. Fixing a bug, adding a test or two, implementing a feature, completing a refactoring, cleaning up a bunch of formatting issues. Each of these could easily be represented as a single commit. Now, whether or not all of these end up in your commit history after you merge your changes into the master branch is another question. But while you're actively working locally, it can certainly be useful to have this granular of a commit history available to you.</p>
<h3>Commits are like game history</h3>
<p>If you’ve ever played a video game that allowed saving checkpoints, you understand the value of frequently saving your progress. If you don’t, and something comes along and kills you, you’ll have to repeat a lot of effort to get back to where you were. Frequent commits in your code will save you from the unexpected just like frequent saves in your games do.</p>
<h2>Show Resources and Links</h2>
<ul>
<li>The <a href="http://deviq.com/copy-folder-versioning/">Copy Folder Versioning Anti-Pattern</a></li>
<li>Blog Post: <a href="https://ardalis.com/check-in-often">Check In Often</a></li>
</ul>
]]></description>
      <pubDate>Mon, 21 Aug 2017 06:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<h1>Check In Often</h1>
<p>As a developer, you should be using source control. You should probably be using distributed source control. And you should check in, probably more often than you think.</p>
<h2>Show Notes</h2>
<p>No matter what specific tool you use for source control, you should be checking in your code to a source control repository. Right now, do you have code that you're working on (or were recently working on) that isn't checked in? How long ago did you check it out? If it's been more than a few hours, that's probably too long to go without checking in your work.</p>
<h3>Why should you commit often?</h3>
<p>The more often you commit your code to a central repository, the sooner you'll discover integration issues. This works best if you're using continuous integration, which we'll talk about later, but even without it, someone else on your team may discover an issue with your code sooner if it's checked in somewhere they can get to it sooner.</p>
<h3>Committing is like ctrl-S.</h3>
<p>If you grew up using word processors like Word, you've probably developed the muscle memory of hitting ctrl-S to save frequently. All it takes is for your machine or application to crash one time while you have hours of unsaved work for you to realize that you really should be saving all the time. The more often you commit your code (and ideally, push changes off your local machine), the better off you are if the unthinkable happens to your machine.</p>
<h3>Recovering from dead ends.</h3>
<p>Of course, an even more common use for frequent commits is that they let you jump back in time when you find that you've gone down a bad path. This, in turn, can give you more confidence to try different approaches to problems or more ambitious refactorings, because you know you can easily jump back to a known good state at any point. One of my favorite sayings is a Turkish proverb, &quot;No matter how far down the wrong path you've gone, turn back now.&quot; When you have an easy restore point to jump to, this is easy. When you don't, it can be tempting to keep fighting with an approach you know in your heart isn't great, simply because going backward is going to be at least as painful as struggling forward.</p>
<h3>Don't use folders for version control.</h3>
<p>Avoid the urge to use copy folder versioning. You know what I'm talking about. That copy of the code folder you made that appends today's date to it, that's sitting next to a dozen similarly named folders. That's not source control, it's undisciplined and sloppy. That's not to say I'm not guilty of doing it myself (this approach still gives me confidence when updating production code on a live server, for instance). But if you're regularly using source control properly, you won't find the need to do this in your local dev environment.</p>
<h3>When should you commit?</h3>
<p>You should be committing your code whenever you've made some tangible progress. Fixing a bug, adding a test or two, implementing a feature, completing a refactoring, cleaning up a bunch of formatting issues. Each of these could easily be represented as a single commit. Now, whether or not all of these end up in your commit history after you merge your changes into the master branch is another question. But while you're actively working locally, it can certainly be useful to have this granular of a commit history available to you.</p>
<h3>Commits are like game history</h3>
<p>If you’ve ever played a video game that allowed saving checkpoints, you understand the value of frequently saving your progress. If you don’t, and something comes along and kills you, you’ll have to repeat a lot of effort to get back to where you were. Frequent commits in your code will save you from the unexpected just like frequent saves in your games do.</p>
<h2>Show Resources and Links</h2>
<ul>
<li>The <a href="http://deviq.com/copy-folder-versioning/">Copy Folder Versioning Anti-Pattern</a></li>
<li>Blog Post: <a href="https://ardalis.com/check-in-often">Check In Often</a></li>
</ul>
]]></content:encoded>
      <enclosure length="2282799" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/e64742f1-73b8-4960-9e25-aa6eed92fda5/ebe28760_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Check In Often</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/e64742f1-73b8-4960-9e25-aa6eed92fda5/3000x3000/1503523245artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:03:59</itunes:duration>
      <itunes:summary>As a developer, you should be using source control. You should probably be using distributed source control. And you should check in, probably more often than you think.</itunes:summary>
      <itunes:subtitle>As a developer, you should be using source control. You should probably be using distributed source control. And you should check in, probably more often than you think.</itunes:subtitle>
      <itunes:keywords>version control, programming, software</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>2</itunes:episode>
    </item>
    <item>
      <guid isPermaLink="false">6ecf4673-273b-45f1-b67d-3fab8a8e7c65</guid>
      <title>Overview of Weekly Dev Tips</title>
      <description><![CDATA[<p>##Episode 1: Overview of Weekly Dev Tips</p>
<p>What is this podcast about, who is it for, and how can you participate in it?</p>
<p>If you have questions or comments, <a href="https://ardalis.com/tips">join my mailing list</a> and reply to the email you receive.</p>
]]></description>
      <pubDate>Mon, 14 Aug 2017 06:00:00 +0000</pubDate>
      <author>steve@ardalis.com (Steve Smith (@ardalis))</author>
      <link>http://weeklydevtips.com</link>
      <content:encoded><![CDATA[<p>##Episode 1: Overview of Weekly Dev Tips</p>
<p>What is this podcast about, who is it for, and how can you participate in it?</p>
<p>If you have questions or comments, <a href="https://ardalis.com/tips">join my mailing list</a> and reply to the email you receive.</p>
]]></content:encoded>
      <enclosure length="1330278" type="audio/mpeg" url="https://cdn.simplecast.com/audio/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/bc00cb4c-2347-43b8-bd8c-1b32817ac7e4/c55b7bab_tc.mp3?aid=rss_feed&amp;feed=W8bGHhCA"/>
      <itunes:title>Overview of Weekly Dev Tips</itunes:title>
      <itunes:author>Steve Smith (@ardalis)</itunes:author>
      <itunes:image href="https://image.simplecastcdn.com/images/b7b4f0/b7b4f0aa-b789-468a-9dec-08578bbb3673/bc00cb4c-2347-43b8-bd8c-1b32817ac7e4/3000x3000/1502396068artwork.jpg?aid=rss_feed"/>
      <itunes:duration>00:01:14</itunes:duration>
      <itunes:summary>What is this podcast about, who is it for, and how can you participate in it?</itunes:summary>
      <itunes:subtitle>What is this podcast about, who is it for, and how can you participate in it?</itunes:subtitle>
      <itunes:keywords>software development, coding, tips</itunes:keywords>
      <itunes:explicit>no</itunes:explicit>
      <itunes:episodeType>full</itunes:episodeType>
      <itunes:episode>1</itunes:episode>
    </item>
  </channel>
</rss>