<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Ka Wai Cheung</title>
    <description>The latest articles on Forem by Ka Wai Cheung (@developerscode).</description>
    <link>https://forem.com/developerscode</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F239%2FMC4KB4E3.jpeg</url>
      <title>Forem: Ka Wai Cheung</title>
      <link>https://forem.com/developerscode</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/developerscode"/>
    <language>en</language>
    <item>
      <title>Naming Things: Thoughts on one of coding’s most elusive tasks</title>
      <dc:creator>Ka Wai Cheung</dc:creator>
      <pubDate>Fri, 21 Feb 2020 20:11:57 +0000</pubDate>
      <link>https://forem.com/developerscode/a-short-book-on-naming-things-47l0</link>
      <guid>https://forem.com/developerscode/a-short-book-on-naming-things-47l0</guid>
      <description>&lt;p&gt;Hey Devs! &lt;/p&gt;

&lt;p&gt;I've just released a &lt;a href="https://namingthings.donedone.com"&gt;free online book called &lt;strong&gt;Naming Things&lt;/strong&gt;&lt;/a&gt;. It's a collection of experiences I've had with naming all kinds of things in code--classes, objects, methods, properties, and business concepts.&lt;/p&gt;

&lt;p&gt;I've had the unique opportunity to work mainly on one piece of software for many years--I began developing DoneDone in 2008 and I've been deeply involved in its maturation for more than a decade.&lt;/p&gt;

&lt;p&gt;DoneDone's codebase is something I look at nearly every day. To care for the same product for so long, it helps to actually love what you're working on. Naming things well is especially important to me because of this.&lt;/p&gt;

&lt;p&gt;As Phil Karlton famously wrote:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There are only two hard things in Computer Science: cache invalidation and naming things.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this book, I hope to show you a few of the surprising conundrums I've faced with naming and how I ultimately resolved (or did my best to resolve) them. This book is an honest and open discussion about a topic I think is underdiscussed in our industry. I do hope you enjoy it.&lt;/p&gt;

</description>
      <category>naming</category>
      <category>productivity</category>
      <category>codequality</category>
    </item>
    <item>
      <title>The joy of building a product and not a business.</title>
      <dc:creator>Ka Wai Cheung</dc:creator>
      <pubDate>Wed, 03 Jan 2018 23:24:41 +0000</pubDate>
      <link>https://forem.com/developerscode/the-joy-of-building-something-with-no-intention-of-making-money-1obd</link>
      <guid>https://forem.com/developerscode/the-joy-of-building-something-with-no-intention-of-making-money-1obd</guid>
      <description>&lt;p&gt;I've been writing code for twenty years. But, recently, it dawned on me that I've been writing code for &lt;em&gt;money&lt;/em&gt; for nearly twenty years. After a few months of getting my feet wet with HTML design in 1997, I started marketing myself for contract gigs. A few years later, I'd picked up enough skills to be hired as a programmer. And, ever since, coding has always coincided with earning a living.&lt;/p&gt;

&lt;p&gt;I'm grateful for being able to do what I love and get paid for it. But, it comes with a trade-off. When you're coding for cash, you can't put your own whims in front of your clients or your customers. You can't spend hours on naming things, or trying out a few different techniques just for the joy of it all.&lt;/p&gt;

&lt;p&gt;Recently, I decided to change that. The company I had co-founded a decade ago was undergoing a pretty significant transformation that included my own departure (I now work solely for one of the offshoot companies we created). This also gave me a rare chance to reset my work schedule. So, I decided to carve out time to work on my own pet projects again.&lt;/p&gt;

&lt;p&gt;But, I gave myself a constraint. When working on my own pet project, my natural inclination is to try to build things that might one day &lt;em&gt;sell&lt;/em&gt;. I've always tried to use my coding skillset to build another &lt;em&gt;business&lt;/em&gt; because that's what I've been doing for 20 years.&lt;/p&gt;

&lt;p&gt;This time, I decided to do the exact opposite. I wanted to build something solely for myself. I forebade myself from building something for an end goal of profit. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The product of this exercise is something I've released called &lt;a href="https://shiftlist.io"&gt;ShiftList&lt;/a&gt;.&lt;/strong&gt; It's a simple to-do list app made for the keyboard. And, obviously, it's completely free. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I wrote it because it's something I wanted to use.&lt;/li&gt;
&lt;li&gt;I wrote it without doing a whole lot of research on the competition. (I just know there are a lot of to-do list apps out there).&lt;/li&gt;
&lt;li&gt;I probably ended up deleting more code than what ended up in the final product.&lt;/li&gt;
&lt;li&gt;I also wrote it exactly how I wanted to (a jquery/vanilla javascript front-end, for example).&lt;/li&gt;
&lt;li&gt;I picked the features that were important to me (keyboard-friendly and it looks like paper!) and left out all the ones that weren't (mobile, calendar syncing, priorities, sharing, commenting, notifications, tagging, categories, reminders)&lt;/li&gt;
&lt;li&gt;I rewrote how the data persisted multiple times until it felt right to me. &lt;/li&gt;
&lt;li&gt;I spent an unspeakable amount of time tweaking the design. &lt;/li&gt;
&lt;li&gt;If this were on a budget, I blew it. I delivered late. I delivered with barely any features. And I had a blast building it. &lt;strong&gt;It was everything I was hoping it would be.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By all &lt;em&gt;business&lt;/em&gt; measures, I likely failed. But, when I took business out of the equation just this once, I allowed myself the pleasure to just create something. I gave myself the time to think, re-write, and even just throw stuff out that didn't feel good after awhile. I measured success simply by enjoying the process and getting to the final result---features, timelines, and budgets be damned!&lt;/p&gt;

&lt;p&gt;I imagine lots of the readers of this community, and particularly programmers that have been at this for years, have fallen into the trap of always equating building products to building businesses. &lt;/p&gt;

&lt;p&gt;But, if you have the opportunity, give yourself the luxury of just creating something for the love of the craft. Be self-indulgent. I'm really glad I did.&lt;/p&gt;

</description>
      <category>fun</category>
      <category>learning</category>
      <category>coding</category>
    </item>
    <item>
      <title>What are your personal stories/examples of "naming things"?</title>
      <dc:creator>Ka Wai Cheung</dc:creator>
      <pubDate>Wed, 08 Nov 2017 16:15:30 +0000</pubDate>
      <link>https://forem.com/developerscode/what-are-your-personal-storiesexamples-of-naming-things-am7</link>
      <guid>https://forem.com/developerscode/what-are-your-personal-storiesexamples-of-naming-things-am7</guid>
      <description>&lt;p&gt;Most programmers are familiar with the quote, "There are only two hard things in Computer Science: cache invalidation and naming things." I'm curious about your personal experiences with the latter.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What are some examples of really bad names you've encountered in code? &lt;/li&gt;
&lt;li&gt;What about the alternative -- any really good names that have stuck with you?&lt;/li&gt;
&lt;li&gt;What frameworks/libraries do it well or do it poorly?&lt;/li&gt;
&lt;li&gt;Has a really poor name ever come back to haunt you (i.e. caused you hours of extra debugging or misled you?)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I know we all have strategies for naming things, but I'm really curious about your personal examples and stories.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>naming</category>
    </item>
    <item>
      <title>A Maker’s Approach to Managing Projects</title>
      <dc:creator>Ka Wai Cheung</dc:creator>
      <pubDate>Tue, 07 Nov 2017 21:58:12 +0000</pubDate>
      <link>https://forem.com/developerscode/a-makers-approach-to-managing-projects-hb</link>
      <guid>https://forem.com/developerscode/a-makers-approach-to-managing-projects-hb</guid>
      <description>&lt;p&gt;&lt;em&gt;Republished from the &lt;a href="https://medium.com/we-are-mammoth/a-makers-approach-to-managing-projects-498a4fa503e2"&gt;We Are Mammoth blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;On the spectrum of what Paul Graham would call makers versus managers, I’m as far to the maker’s side as one can be. I’ve always had a penchant for creating things. Managing, by contrast, has never felt natural to me. So, when it comes to managing a project, I do things a little out of the norm–with what I’ll call a &lt;em&gt;maker’s approach&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Over the past six months, I’ve overseen two very different kinds of development projects for our products, &lt;a href="https://www.getdonedone.com"&gt;DoneDone&lt;/a&gt; and &lt;a href="https://www.kinhr.com"&gt;Kin&lt;/a&gt;. Between August and December, I oversaw the development of our iOS mobile app. Then, for seven weeks from early January to late February, I oversaw the development of Kin’s eSignature feature.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Vo1wgx3A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/7e4n0nqyfpsi5tl7z8ox.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Vo1wgx3A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/7e4n0nqyfpsi5tl7z8ox.jpg" alt="DoneDone iOS mobile app"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mfyU3nkg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/hb7ziqimyyznth1heg5g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mfyU3nkg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/hb7ziqimyyznth1heg5g.png" alt="Kin eSignatures"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In both projects, we worked with just a few veteran developers and without a whole lot of upfront planning. We dug into the build as early as possible. While this might seem hairy to some, it’s a kind of environment that can work with a maker’s mindset. Here are a few approaches I take as a maker in a manager’s role in these situations.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Jam Session
&lt;/h1&gt;

&lt;p&gt;I’m an advocate of keeping the beginning of a development cycle as free of constraints as possible. Given there isn’t anything tangible to chew on yet, I don’t like to prescribe the order in which development should flow right from the beginning.&lt;/p&gt;

&lt;p&gt;For DoneDone Mobile, did I care what the team worked on first? Did it matter if I could test out the behavior of issue lists before I could create an issue? Did it make a difference if the activity feed was built out before the search filter for the activity screen? Nope, nope and nope.&lt;/p&gt;

&lt;p&gt;We also had a unique challenge while developing the mobile app. The entire development team (Grant, Jeremy, and Chris) was simultaneously ramping up to &lt;a href="http://www.xamarin.com"&gt;Xamarin&lt;/a&gt;â€Š–â€Šthe .Net framework for building mobile apps we used for DoneDone. Grant had already completed his training and certification; but applying any learned knowledge to a real project is always a mental leap-of-faith.&lt;/p&gt;

&lt;p&gt;So, for the first two weeks of development, after I had carved out a one-page feature set to work from, I gave Grant a singular initiative: Start anywhere. Pick a place to start implementing and go. The only goal in this early phase of development is to &lt;em&gt;make progress&lt;/em&gt;. At the same time, our designer Mike took those two weeks to build out designs against the feature set I prepared for the team. His initiative? Start anywhere as well.&lt;/p&gt;

&lt;p&gt;Toward the end of those two weeks, Grant had completed some of the underlying plumbing and rudimentary views and Mike wrapped up the design for those views. Jeremy then came in to focus on the details of the UI. Again, I didn’t care about the order. Jeremy bounced between building some of the overall UI structure and polishing the views that Grant had hooked up earlier.&lt;/p&gt;

&lt;p&gt;I liken this phase of development to a jam session. Cerebral freedom eliminates any friction that a strict early development roadmap introduces. Pieces of the art come together in surprising ways. In the end work still gets done–and usually at a faster pace than if we had prescribed a roadmap to begin with.&lt;/p&gt;

&lt;p&gt;By keeping the objectives open, people get to work on the pieces that are most interesting to them at the moment. They get to move around the app at-will, when it makes sense to them naturally. They get to find out what the initially-unforeseen obstacles are and what to do about them. Most importantly, I think this approach helps developers build &lt;em&gt;momentum&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Now, at a certain point, the boundlessness of a jam session becomes more of a hindrance than a help. Enough of the initial hustle has turned into the actual product. It’s at this point that it makes sense to flush out the roadmap to the remaining work ahead.&lt;/p&gt;

&lt;p&gt;There’s no precise science behind when this happens. It’s a feeling in the room. But, ideally, the jam session should take no more than 20% of the overall time you have to build. That leaves 80% of the schedule left to flush out how to tactically approach what’s left–with the immense benefit of momentum and the understanding of what the team’s learned during the jam session.&lt;/p&gt;

&lt;h1&gt;
  
  
  Spiraling QA
&lt;/h1&gt;

&lt;p&gt;Traditionally, formal quality assurance testing begins toward the end of the development process. It’s parked somewhere between development completion just before release. However, I far prefer beginning QA as early as possible &lt;em&gt;during&lt;/em&gt; development. In the case of DoneDone Mobile, it was shortly after the jam session was complete.&lt;/p&gt;

&lt;p&gt;It works best to start QA with broad stroke testing. Over time, you gradually get into the devilish details. The QA process we went through in both of these projects was like traveling down a spiral.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PFUPlIa5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/q0io448m37mxv22tjppu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PFUPlIa5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/q0io448m37mxv22tjppu.jpg" alt="Spiral"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At the beginning, I focused on big picture functional issues (“I can’t create an issue or “I’m not getting an email notification when I’m assigned a document”). Even though there are obvious UI improvements, as a tester, I tend to leave those out of my initial rounds of testingâ€Š–â€Šthey’re just not as critical to the feature at the moment. It’s also not where a developer’s focus may be at. As iterations improve, the issues get more granular (“The spacing between selectors on the issue search screen isn’t consistent”). Eventually, we spiral downward to the actual feature we want.&lt;/p&gt;

&lt;p&gt;Because QA and development focus on roughly the same level of scope at the same time (big things in the beginning gradually spiraling toward finer details later on), spiraling QA also allows for a lot of iteration. I find this takes some of the time and pressure away from figuring out too much of the feature at the beginningâ€Š–â€Šparticularly all the little details. In other words, we exchange some scoping time at the beginning of a traditional feature cycle in order to begin development (and spiraling QA) earlier. This gives us more time to iterate against something real versus something sketched. I think the end result is always better.&lt;/p&gt;

&lt;h1&gt;
  
  
  Development baseball
&lt;/h1&gt;

&lt;p&gt;When I manage a project, I don’t actively manage the thing 100% of the timeâ€Š–â€Šthere simply isn’t a need to do so at every given moment of a project’s lifecycle. Doing so usually creates all the unnecessary &lt;a href="http://www.paulgraham.com/makersschedule.html"&gt;extra time disruption for makers that Paul Graham has described&lt;/a&gt;. I don’t like to schedule out daily or weekly check-ins weeks in advance. I think it’s far more valuable to plan meetings a week at a time. Some weeks you need more, some weeks you need less. Let the work-at-hand dictate that.&lt;/p&gt;

&lt;p&gt;Instead, I look at my role more like the hybrid player-manager of a bygone era in baseball. While I manage, I look for opportunities where it makes sense to implant myself as a developer. The benefits are many-fold:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, I get full exposure to the code my team is working on. It helps me understand where the pain points might be. I can manage with more context of what’s really going on.&lt;/li&gt;
&lt;li&gt;Second, it often helps with the extra push needed to get something out on a fixed time. It gives our team a little more confidence in hitting a deadline when there’s some flexibility with developer bandwidth. Because I’m already immersed in the project in other ways (scoping, QA, etc.), my extra hand &lt;em&gt;should&lt;/em&gt; help rather than hurt–it doesn’t result in Brooks’s infamous law: “Adding manpower to a late software project makes it later.”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Where I lend a hand will differ from project-to-project. For DoneDone Mobile, it made the most sense for me to come in late and help refactor some of the debt naturally introduced with a team who was learning a new framework. I’ve called this &lt;a href="https://medium.com/we-are-mammoth/quality-starts-and-a-save-starter-reliever-development-8767fce581df"&gt;Starter/Reliever development&lt;/a&gt; in the past.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--m6mTMQ0C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/pxsrrwkwymwuu79hshib.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--m6mTMQ0C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/pxsrrwkwymwuu79hshib.jpg" alt="Reliever"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By contrast, for Kin’s eSignature feature, I supported the development team at the very beginning. While Jeremy and Waylon were busy building the infrastructure within Kin to support eSignatures, I spent the first week of our development cycle investigating the best third-party integration for document uploading and signing. For the record, we ended up integrating with HelloSign and are ecstatic with the results.&lt;/p&gt;

&lt;p&gt;By week’s end, I had built proof-of-concepts in C# to create, embed, and share documents that I handed off to the team. In a sense, I played the role of a pinch hitterâ€Š–â€Šworking on a silo’d one-off task that the “starters later incorporated into the actual build.&lt;/p&gt;

&lt;h1&gt;
  
  
  Trust usurps heavy process
&lt;/h1&gt;

&lt;p&gt;The methods I use to manage a project aren’t textbook. The lucidity of each method requires a whole lot of faith and trust between your teammates. If I’ve only worked with members of my development team for a few months, I’d be a little weary of how, say, a jam session might run. But, I have the luxury of teammates I’ve worked with for over five years.&lt;/p&gt;

&lt;p&gt;With the longevity of a development team, &lt;a href="https://dev.to/developerscode/there-are-rockstars-and-there-are-bands"&gt;trust becomes the largest weight of confidence for me&lt;/a&gt;. And, the results surely prove it.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>leadership</category>
      <category>management</category>
      <category>culture</category>
    </item>
    <item>
      <title>Sympathy for the developer</title>
      <dc:creator>Ka Wai Cheung</dc:creator>
      <pubDate>Tue, 17 Jan 2017 15:36:30 +0000</pubDate>
      <link>https://forem.com/developerscode/sympathy-for-the-developer</link>
      <guid>https://forem.com/developerscode/sympathy-for-the-developer</guid>
      <description>&lt;p&gt;In most other art forms, &lt;strong&gt;the end product is final&lt;/strong&gt;. A song. A novel. A painting. A movie. A sculpture. A dish. Critics may revere or denounce it, but the end result is the end result. The artist puts a stamp on it and moves on to create something new.&lt;/p&gt;

&lt;p&gt;In most other art forms, &lt;strong&gt;the audience directly consumes the art&lt;/strong&gt;. When you read a beautifully crafted story, you read the very words the author wrote. When you admire an oil painting up-close, you see the very strokes the painter made in the process of creating it. When you listen to your favorite song, you hear every note in the exact way the musician intended you to hear it.&lt;/p&gt;

&lt;p&gt;In most other art forms, &lt;strong&gt;great works become better with age&lt;/strong&gt;, like the guitar riff on "Stairway to Heaven" or Van Gogh's "Starry Night". They don't lose their lust over time. If anything, the opposite happens—they're looked upon with even greater reverence as time goes by. It's why, six centuries later, people still wait in long lines at the Louvre to be within ten feet of the Mona Lisa, a painting that only stands a couple of feet long and wide on its own. &lt;/p&gt;

&lt;p&gt;In most other art forms, &lt;strong&gt;the audience shows deference to the artist&lt;/strong&gt;. I remember reading "The Sound and the Fury" in high school. If you've ever read it, you'd be familiar with William Faulkner's stream-of-consciousness style of prose. Though a 17-year-old version of me would've argued that this was simply a quick trick to meet a publisher's looming deadline, most would be appalled by my suggestion. Instead, it's high art and it falls on us as readers to consume those words, break them apart, and make sense of it all. &lt;/p&gt;

&lt;p&gt;But, writing code isn't like most other art forms. We get none of these returns. &lt;/p&gt;

&lt;p&gt;Our end product is only final if it fails. If, on the other hand, our product succeeds, we need to continually apply our art against it. We are in the constant battle between applying more of our art to it and ensuring we're not drowning the product in it.&lt;/p&gt;

&lt;p&gt;Our art is hidden from the purview of our audience. What may be a masterfully-crafted, elegantly-written piece of code will go unnoticed to the user because everything went...&lt;em&gt;right&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;We don't pay homage to the past. No developer looks back at that Flash site from 1999, or the RSS reader they wrote in 2004 and says to themselves, "They don't make 'em like they used to." &lt;/p&gt;

&lt;p&gt;And if a spinning loader revolves one too many times for a user's liking, it is met with disappointment and disdain, not with the idea that perhaps the complexity of the situation more than merits the wait.&lt;/p&gt;

&lt;p&gt;And, &lt;em&gt;rightfully so&lt;/em&gt;. Our art, as difficult as it sometimes is, serves primarily a utilitarian purpose. That's just the way this form of art shook itself out. &lt;/p&gt;

</description>
      <category>programming</category>
      <category>art</category>
    </item>
    <item>
      <title>Avoid anemic domain models by empowering your objects</title>
      <dc:creator>Ka Wai Cheung</dc:creator>
      <pubDate>Mon, 16 Jan 2017 03:34:14 +0000</pubDate>
      <link>https://forem.com/developerscode/avoid-anemic-domain-models-by-empowering-your-objects</link>
      <guid>https://forem.com/developerscode/avoid-anemic-domain-models-by-empowering-your-objects</guid>
      <description>&lt;p&gt;One of the common anti-patterns I see in a lot of object-oriented code today (including my own) is what Martin Fowler refers to as &lt;em&gt;anemic domain models&lt;/em&gt;. He writes about them &lt;a href="http://www.martinfowler.com/bliki/AnemicDomainModel.html"&gt;rather eloquently here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The gist of the idea is that we often create classes whose job entails nothing more than holding onto data. In Martin's words, "The catch comes when you...realize that there is hardly any behavior on these objects, making them little more than bags of getters and setters."&lt;/p&gt;

&lt;p&gt;In certain cases, these kinds of objects make sense. Data transfer objects (DTOs) that serve no other purpose than to transition data from one service to another is a prime example. However, Martin argues that in the business domain of your application code, objects should intermingle data and process together. It's the entire fruit of object-oriented programming's labor.&lt;/p&gt;

&lt;p&gt;I liken object-oriented programming to writing great characters in fiction. It's one skill to write a linear story. It's yet another to write characters. Doing so allows a story to keep building in the reader's mind. The sequel, third installment, and beyond are easier for the author to describe because the characters are developed well from the outset. &lt;/p&gt;

&lt;p&gt;This too, is true of object-oriented writing. Anemic objects are the equivalent of poorly described characters. The more you can avoid this tendency, the easier it is to build upon the story of your code as you write its natural iterations over time. Not only does your code gains all the tangible benefits of good design, but your audience (other programmers reading your code) can better consume what you're describing as well. Good characters are memorable in that way.&lt;/p&gt;

&lt;p&gt;I stumbled upon a real example of this problem while working through some of my own code recently. I thought I'd write about it in hopes of clarifying the anti-pattern for anyone who hasn't quite grasped the idea yet.&lt;/p&gt;

&lt;p&gt;Recently, I worked on some C# code for a new mobile application we're building with   &lt;a href="https://www.xamarin.com/"&gt;Xamarin&lt;/a&gt; for my product, &lt;a href="https://www.getdonedone.com"&gt;DoneDone&lt;/a&gt;. DoneDone is a simple web-based issue tracker for small development teams. On the app, we want to display the activity for specific issues during a given day. In a database, we track any modifications to an issue (edits, comments, status changes, reassignments) alongside the date the modification happened.  &lt;/p&gt;

&lt;p&gt;In code, we have a class called &lt;code&gt;ActivityFilter&lt;/code&gt; which holds all of a user's search criteria for the activity on their issues. It looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ActivityFilter&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="n"&gt;ActivityDate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; 
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;ProjectId&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;TagIds&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;FilterType&lt;/span&gt; &lt;span class="n"&gt;SelectedFilterType&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;DueType&lt;/span&gt; &lt;span class="n"&gt;SelectedDueType&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;ActivityFilter&lt;/code&gt; object is where we store search inputs from the user. When a user chooses a project on the app, the object's &lt;code&gt;ProjectId&lt;/code&gt; is updated and cached. When a user chooses to see activity on issues with specific tags, the object's &lt;code&gt;TagIds&lt;/code&gt; are updated and cached...and so forth.&lt;/p&gt;

&lt;p&gt;This object fits the description of Martin's anemic domain model like a glove—nothing more than "a bag of getters and setters." But, for now, I'm actually quite content with this. The class's sole purpose is to store some filtering data that other objects will use to do the dirty work. It's anemic because it needn't be anything more.&lt;/p&gt;

&lt;p&gt;On the mobile interface, you can choose a specific day upon which activity occurs—today, yesterday, or a random day a few years back. The application stores this date in an &lt;code&gt;ActivityFilter&lt;/code&gt; object and the object is then cached in memory. If you come back to the application tomorrow, the application reads the data off the cached object and displays the activity that meets whatever search criteria you last set.&lt;/p&gt;

&lt;p&gt;When I played around with this behavior, something felt a bit odd. Suppose you choose to view activity for today. Then, you leave the application. When you open it up again tomorrow afternoon, the app shows you activity from &lt;em&gt;yesterday&lt;/em&gt;. That makes perfect sense programmatically because the last &lt;code&gt;ActivityDate&lt;/code&gt; stored happens to be yesterday's date. But, it doesn't feel natural.&lt;/p&gt;

&lt;p&gt;Imagine you choose to view today's activity, and say today is &lt;em&gt;January 16th, 2017&lt;/em&gt;. If you close out of the application and come back tomorrow, you'd &lt;em&gt;actually&lt;/em&gt; expect the app to show you activity for &lt;em&gt;today&lt;/em&gt; again. Today would be the 17th rather than the 16th. This expectation is made more obvious because on the UI we display the word "Today" above the activity instead of the date, if the date you've chosen is today's date. &lt;/p&gt;

&lt;p&gt;However, suppose you explicitly choose to view activity from a day in the past (say July 8th, 2016). When you come back tomorrow, you should still see activity from that day—it shouldn't default you back to "today".&lt;/p&gt;

&lt;p&gt;In summary, the business logic around the &lt;code&gt;ActivityDate&lt;/code&gt; that I really want looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you set the activity date to something other than today's date, you should always see activity from that day, until you choose a new date.&lt;/li&gt;
&lt;li&gt;However, if you set the activity date to today's date, you should always see activity from "today" (right now, tomorrow, or three weeks from now), until you choose a new date.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All things considered, this business logic isn't terribly complex. But, who should own this bit of logic? Certainly, the &lt;code&gt;ActivityFilter&lt;/code&gt; object needs to store that extra bit of information. At first glance, it feels like we should expose some extra boolean on the class that denotes whether the selected date was today. Let's call it &lt;code&gt;IsActivityDateSetToToday&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ActivityFilter&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="n"&gt;ActivityDate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; 
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;IsActivityDateSetToToday&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// new param&lt;/span&gt;

    &lt;span class="c1"&gt;// Hiding the other properties in this post for clarity&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way, when the &lt;code&gt;ActivityDate&lt;/code&gt; is set, we can check against the current system date to see whether to set &lt;code&gt;IsActivityDateToday&lt;/code&gt; as well. Assuming &lt;code&gt;_CachedActivityFilter&lt;/code&gt; is the name of the cached instance of the &lt;code&gt;ActivityFilter&lt;/code&gt; object for the application's session, the application code that sets the date might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;onActivityDateChanged&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="n"&gt;selectedDate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_CachedActivityFilter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ActivityDate&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;selectedDate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;_CachedActivityFilter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsActivityDateSetToToday&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;selectedDate&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_cachedActivityFilter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsActivityDateSetToToday&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Side note: In C#, there is no built-in class that just holds a date. Instead, the &lt;code&gt;DateTime&lt;/code&gt; class stores both date and time information. For our purposes, we only care about the date portion. The &lt;code&gt;Date&lt;/code&gt; property off the &lt;code&gt;DateTime&lt;/code&gt; class returns a &lt;code&gt;DateTime&lt;/code&gt; object with the time portion automatically set to 00:00:00. Hence, throughout our code snippets, we evaluate &lt;code&gt;DateTime&lt;/code&gt; objects via their &lt;code&gt;Date&lt;/code&gt; property.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;With this extra piece of information, the application code that reads the cached &lt;code&gt;ActivityFilter&lt;/code&gt; object would perform some logic like this to grab the correct date to search activity against:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;dateToSearchFor&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_CachedActivityFilter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ActivityDate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_CachedActivityFilter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsActivityDateSetToToday&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;dateToSearchFor&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is nothing obviously wrong here. The &lt;code&gt;ActivityFilter&lt;/code&gt; object does what's being asked of it—it stores the information that the application needs to know what activity fits the user's criteria.&lt;/p&gt;

&lt;p&gt;However, if the role of the &lt;code&gt;ActivityFilter&lt;/code&gt; object is to be the keeper of a user's selection criteria, then, shouldn't it also know what date the user is asking for? This would likely be the argument Martin would make here. In a sense, we're not developing the &lt;code&gt;ActivityFilter&lt;/code&gt; character particularly well. &lt;/p&gt;

&lt;p&gt;We can fix this by pushing this activity date business logic into the &lt;code&gt;ActivityFilter&lt;/code&gt; object itself rather than expose that information to the code that sets and retrieves the date.&lt;/p&gt;

&lt;p&gt;First, let's privatize &lt;code&gt;IsActivityDateSetToToday&lt;/code&gt;. Let's also create a new private activity date property &lt;code&gt;activityDate&lt;/code&gt;. Then, let's expand the public &lt;code&gt;ActivityDate&lt;/code&gt; to handle the "today" logic when a value is set:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ActivityFilter&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="n"&gt;activityDate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;isActivityDateSetToToday&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="n"&gt;ActivityDate&lt;/span&gt; 
    &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="k"&gt;get&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// TODO&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;set&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Set the activity date to the passed in value&lt;/span&gt;
            &lt;span class="n"&gt;activityDate&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="c1"&gt;// Note whether the date set is 'today'&lt;/span&gt;
            &lt;span class="n"&gt;isActivityDateSetToToday&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Date&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Hiding the other properties in this post for clarity&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By doing this, we no longer expose the properties involved in the "today" logic publicly. The work is relegated to the &lt;code&gt;ActivityFilter&lt;/code&gt; class itself. If the set date happens to be today, the class makes note of it internally.&lt;/p&gt;

&lt;p&gt;Now, let's move on to the &lt;code&gt;ActivityDate&lt;/code&gt; public &lt;code&gt;get&lt;/code&gt; method.  Here, we can check the value of &lt;code&gt;isActivityDateSetToToday&lt;/code&gt;. If it's true, then &lt;code&gt;ActivityDate&lt;/code&gt; will return today. Otherwise, it will return the date of the last stored activity date:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ActivityFilter&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="n"&gt;activityDate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;isActivityDateSetToToday&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="n"&gt;ActivityDate&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;get&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// If last set date was that day, return 'today'&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isActivityDateSetToToday&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;activityDate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;set&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;today&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;setDate&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="c1"&gt;// Note if the date set is 'today'&lt;/span&gt;
            &lt;span class="n"&gt;isActivityDateSetToToday&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;today&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;setDate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;activityDate&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;/// Hiding the other properties in this post for clarity&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's rewind and run through the revitalized &lt;code&gt;ActivityDate&lt;/code&gt; property. &lt;/p&gt;

&lt;p&gt;When the property is set, the &lt;code&gt;ActivityFilter&lt;/code&gt; object not only sets an internal property to that day, but also notes whether that day is, in fact, today. When the property is retrieved, the &lt;code&gt;ActivityFilter&lt;/code&gt; object hands back the date that it was last set to, &lt;em&gt;unless&lt;/em&gt; it had been set to that day. In this case, it will hand back whatever "today" is.&lt;/p&gt;

&lt;p&gt;But, does fighting this anemia make the codebase noticeably &lt;em&gt;better&lt;/em&gt;? The beauty of this encapsulation comes to fruition when we refactor the original code that sets and gets the activity date.  First, the code that originally handled the extra logic now need only set the activity date:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;onActivityDateChanged&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="n"&gt;selectedDate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_CachedActivityFilter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ActivityDate&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;selectedDate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly, the code that retrieves the date to then query for the right activity simply needs to retrieve the value &lt;code&gt;_CachedActivityFilter.ActivityDate&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;We've now tucked away the activity date logic into the object who owns the data surrounding that logic. Whereas previously both the code that set the date &lt;em&gt;and&lt;/em&gt; the code that retrieved the date needed to know about the nuanced logic around "today", now they don't. They also aren't holding onto multiple responsibilities anymore. &lt;/p&gt;

&lt;p&gt;These objects are now responsible for processes they should rightfully own. In the end, we've built a better story around our code by developing our characters more properly.&lt;/p&gt;

</description>
      <category>oop</category>
      <category>antipatterns</category>
    </item>
    <item>
      <title>The dichotomy of writing and reading object-oriented code</title>
      <dc:creator>Ka Wai Cheung</dc:creator>
      <pubDate>Sat, 07 Jan 2017 05:02:21 +0000</pubDate>
      <link>https://forem.com/developerscode/the-dichotomy-of-writing-and-reading-object-oriented-code</link>
      <guid>https://forem.com/developerscode/the-dichotomy-of-writing-and-reading-object-oriented-code</guid>
      <description>&lt;p&gt;I've spent most of my twenty year career writing object-oriented code. Even though I've been at it for so long, I still find myself stuck with a particular roundabout habit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I usually don't &lt;em&gt;start&lt;/em&gt; writing code in an object-oriented way. Instead, I often refactor into object-orientedness as part of my editing process.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here's a very simple example. Suppose I have a class called &lt;code&gt;User&lt;/code&gt;. It looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;FirstName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;LastName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;FirstName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;LastName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In some other place in my application, far from the &lt;code&gt;User&lt;/code&gt; class definition, I have an instance of the &lt;code&gt;User&lt;/code&gt; object and output some information. Perhaps, I want to return a statement exclaiming a user has finished a task. Here's what I'd write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;GetTaskResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="n"&gt;myUser&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; 
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;myUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FirstName&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" "&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;myUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LastName&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" has completed the task!"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When I need to assemble some logic using the data within an object, I tend to assemble that logic at the location that currently &lt;em&gt;needs&lt;/em&gt; the logic. For instance, if I'm working in a view class that displays a user's full name, I'll scribble out that bit of logic in the view class &lt;em&gt;first&lt;/em&gt;. &lt;strong&gt;I do the work in the place where the work needs to be done&lt;/strong&gt;. This approach feels most natural to me. But, it is also not a particularly object-oriented style of thinking.&lt;/p&gt;

&lt;p&gt;After I've completed this phase, I then hunt for where I can break this logic apart. I investigate whether I've duplicated some logic that already exists in another method to keep my code DRY. I also figure out where I can extract logic and replace them with more expressive methods within the class I am working in.&lt;/p&gt;

&lt;p&gt;Back to our example, I might extract the portion of the string that creates the user's full name into a new method, still living in the place where I'm doing the work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;GetTaskResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="n"&gt;myUser&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; 
   &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;fullName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getFullName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myUser&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fullName&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" has completed the task!"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;getFullName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="n"&gt;myUser&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;myUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FirstName&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" "&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;myUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LastName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Up until now, though, I've simply written and refactored out code in a procedural way. My next move parks this method into the object it rightfully belongs to. In this simple case, &lt;code&gt;getFullName()&lt;/code&gt; has an obvious home. It feels more appropriate in the &lt;code&gt;User&lt;/code&gt; class itself. And, because it need only inspect the elements it owns, I can turn this method into a readonly property. &lt;code&gt;FullName&lt;/code&gt; is now just another property of a &lt;code&gt;User&lt;/code&gt; instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;FirstName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;LastName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;FullName&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;get&lt;/span&gt; 
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;FirstName&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" "&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;LastName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;FirstName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;LastName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This also pretties up the original method I was working in as well:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;GetTaskResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="n"&gt;myUser&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; 
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;myUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FullName&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" has completed the task!"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a simple example like this, I've gone through this mental dance enough times to skip right to the end result. But, as the logic around features gets increasingly entangled and complex, I go through this dance a lot more deliberately. The refactorings aren't so obvious. &lt;strong&gt;For me, object-oriented code is the end result of a fair amount of contemplative code editing.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The funny thing is, I read code in much the same way. Procedural code feels far more approachable to me at the outset. If I'm on the lookout for a specific piece of logic, I can probably hunt down its whereabouts by driving down a procedural codebase far more quickly than by hopping around an object-oriented one. &lt;/p&gt;

&lt;p&gt;If reading or writing object-oriented code feels strange to me, then why program this way at all? Because, to me, object-oriented design wins out in the long run. The merits of OOP pay off the longer an application lives and grows.&lt;/p&gt;

&lt;p&gt;An object-oriented codebase paints a far more consumable mental model of the &lt;em&gt;entire application&lt;/em&gt; than a procedural codebase. But, consuming the whole thing naturally takes time. The trade-off I make with OOP is the immediate understanding of one particular piece of the puzzle for a slower, more methodical understanding of the application as a whole.&lt;/p&gt;

&lt;p&gt;Keeping a clean, expressive, and well-designed object-oriented codebase is hard work. It requires persistent re-evaluation and discipline. The leap of faith is that it is &lt;em&gt;in this re-evaluation&lt;/em&gt; where you cement a far better understanding of what you are actually building.&lt;/p&gt;

</description>
      <category>refactoring</category>
      <category>oop</category>
    </item>
    <item>
      <title>How about a refactorthon?</title>
      <dc:creator>Ka Wai Cheung</dc:creator>
      <pubDate>Sun, 01 Jan 2017 21:06:41 +0000</pubDate>
      <link>https://forem.com/developerscode/how-about-a-refactorthon</link>
      <guid>https://forem.com/developerscode/how-about-a-refactorthon</guid>
      <description>&lt;p&gt;Refactoring. &lt;/p&gt;

&lt;p&gt;It's one of those concepts most of us talk about a lot more than we actually get to do. Software budgets rarely grant stretches of time for developers to reshape code without any visible outcome. No client is willing to pay for that. &lt;/p&gt;

&lt;p&gt;Instead, we have to figure out ways to refactor-while-we-write. Refactor early and refactor often—that's the answer! Yet, still, software cruft is as certain as death and taxes. Theory usually meets harsh reality. Getting the damned thing to work before the next deadline usually usurps writing elegant code. All those little tradeoffs in favor of &lt;em&gt;now&lt;/em&gt; manifest as the tangled, ambiguous, directionless mess of code we have to maintain later. &lt;/p&gt;

&lt;p&gt;And besides, you might not know what the &lt;em&gt;proper&lt;/em&gt; refactoring ought to be until the codebase smells enough. Early-and-often refactorings can make for a pretty set of shrubs on the front lawn, but you might step back one day and realize what you really needed were a set of lawn chairs on the back patio.&lt;/p&gt;

&lt;p&gt;At some point in a codebase's life, enough cruft builds up where the gears of progress begin to stall. We can plod onwards, pushing our way through the molasses of technical debt. Or, by some miracle, attempt to convince our stakeholders that we've squeezed all we could out of &lt;code&gt;V1&lt;/code&gt; and it's due time to rebuild it all over again. Neither feels like an optimal approach.&lt;/p&gt;

&lt;p&gt;A handful of times in my career, I've felt the overwhelming urge for the "big refactoring." I've thrown caution to the wind and barged my way into the IDE after hours and on weekends—whatever chunk of time would allow me to completely focus on my personal vendetta against the offending codebase. A covert operation is sometimes the only viable approach.&lt;/p&gt;

&lt;p&gt;There is always a moment during these sessions where the investment finally pays off. At some point, you know the hardest work is behind you and the fruits of your labor lie directly in front of you. The final Tetris piece falls into place. The abscess can be obliterated. The smell is gone. The code no longer runs on black magic.&lt;/p&gt;

&lt;p&gt;That moment, for me, is &lt;em&gt;the most satisfying part of programming&lt;/em&gt;. I know many others feel the same way. In my experience, a monumental amount of good can be done in an intense weekend session of refactoring. It's a shame that this often has to happen under the proverbial cover of night.&lt;/p&gt;

&lt;p&gt;Here's a new idea: &lt;strong&gt;A refactorthon&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;Hackathons are usually geared toward the rapid development of nascent ideas, with groups of people that just met, on an overabundance of caffeine and pizza, coding for a day or two on new technologies without formal breaks. Oh you know...&lt;em&gt;just the kind of environment conducive to code in critical need of a refactoring&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Our industry bends too far forward these days. The carrot dangled in front of us is to build whatever is new, and to do it fast. But, the more critical need in programming today isn't yet another single-page mashup app using the JavaScript framework flavor-of-the-week sitting on top of the newest structureless database. Rather, it should be to take all the technical stuff that's proven useful for society and make sure it continues to stay useful for the long run.&lt;/p&gt;

&lt;p&gt;So, what if, instead, we turned the idea on its head? What if we assembled groups of programmers together for a weekend to refactor existing production code? &lt;/p&gt;

&lt;p&gt;On day one, each participant would receive the same real-world, working codebase and a thorough explanation of what it does. Perhaps, the development team who actively works on the codebase could explain where the biggest pain points live and be on-hand to answer questions &lt;em&gt;(Sure, depending on the codebase, there could be NDAs and other papers to sign but stay with me for a moment)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Individuals would then have time to review the codebase. At some point, teams would form and work would begin solely focused on refactoring. No new feature additions. No ideas to make the app more marketable. The room's energy would be entirely devoted to improving the working codebase, head to toe. In a couple days, every team would be able to significantly improve code in some way. &lt;/p&gt;

&lt;p&gt;At the end of the refactorthon, teams would present what they refactored. Why did they choose a certain approach? How did it improve the codebase? How much code were they able to remove? What makes the code more readable now? The active development team could choose the refactorthon winner. &lt;/p&gt;

&lt;p&gt;Imagine how many great ideas and discussions would circle a room when a few dozen bright folks all tackle the same objective for two days—better code. Maybe a refactorthon is the counterweight our industry needs to align what's cool with what's desperately needed right now.&lt;/p&gt;

</description>
      <category>refactoring</category>
    </item>
    <item>
      <title>Make good decisions</title>
      <dc:creator>Ka Wai Cheung</dc:creator>
      <pubDate>Tue, 20 Sep 2016 21:46:31 +0000</pubDate>
      <link>https://forem.com/developerscode/make-good-decisions</link>
      <guid>https://forem.com/developerscode/make-good-decisions</guid>
      <description>&lt;p&gt;My alma mater, Northwestern University, holds the unfortunate distinction of being the only school in a major athletic conference to have never qualified for the men's NCAA basketball tournament. It's become so bad that our fans have come up with a simple slogan for the team. It simply reads:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Make shots.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Though it sounds like we're just poking fun at our own team, I've always found this slogan to be more poignant than funny. And, deep down inside, I think everyone else in our fan base feels the same way.&lt;/p&gt;

&lt;p&gt;You can strategize all you want. Study film. Hit the weight room. Practice your jumper a thousand times a day. Prepare to your heart's content. But, as cruel as it sounds, you will only be judged by the shots you make and don't make during a game. You don't get a free pass because of all the hard work you put into a missed shot.&lt;/p&gt;

&lt;p&gt;And so, if I had to sum up all of my programming experience into only one piece of advice, it would be something similar:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Make good decisions.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The best programmers I've ever worked with always do this one thing &lt;em&gt;consistently&lt;/em&gt;. It's not that they knew a certain language or specific pattern or were the fastest to come up with a clever solution to an intricate problem. It was that, when faced with a challenge, they somehow always executed their solution beautifully. They made good decisions.&lt;/p&gt;

&lt;p&gt;The tricky part about making good decisions is you don't know you've made them until you see the result. Just like you don't know you made a shot until it goes through the net. But, this is where repeated experience comes into play. The more attempts you try, the better you can assess yourself.&lt;/p&gt;

&lt;p&gt;Experience isn't the only indicator though. The programmers that make good decisions also seem to master these traits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They treat small problems with as much deference as larger ones.&lt;/li&gt;
&lt;li&gt;They take justifiable shortcuts and clean up their debts appropriately afterwards.&lt;/li&gt;
&lt;li&gt;They take worthwhile risks and make sure they are as un-risky as possible.&lt;/li&gt;
&lt;li&gt;They look at any decision as a trade-off.&lt;/li&gt;
&lt;li&gt;They add more code while maintaining clean code.&lt;/li&gt;
&lt;li&gt;They know what's most important to customers, clients, and the codebase and find the right balance in between.&lt;/li&gt;
&lt;li&gt;They permanently plug code leaks rather than repeatedly mop up wet floors.&lt;/li&gt;
&lt;li&gt;They estimate delivery times with &lt;em&gt;relative&lt;/em&gt; accuracy.&lt;/li&gt;
&lt;li&gt;They communicate their intent (both in code and to humans) clearly.&lt;/li&gt;
&lt;li&gt;They are enjoyable and reliable people to work with, particularly in the heat of the battle.&lt;/li&gt;
&lt;li&gt;They don't simply “take the blame” when something goes wrong. They own the problem.&lt;/li&gt;
&lt;li&gt;They're able to adjust course if small roadblocks get in the way.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even with all of these traits, there still is no guarantee that a programmer will make a good decision every time. Just like the best basketball player will still miss a shot occasionally. There is always a small ounce of luck involved in any decision. But, as the Roman philosopher Seneca once said, “luck is what happens when preparation meets opportunity.”&lt;/p&gt;

</description>
    </item>
    <item>
      <title>There are rockstars and there are bands</title>
      <dc:creator>Ka Wai Cheung</dc:creator>
      <pubDate>Sun, 07 Aug 2016 02:09:29 +0000</pubDate>
      <link>https://forem.com/developerscode/there-are-rockstars-and-there-are-bands</link>
      <guid>https://forem.com/developerscode/there-are-rockstars-and-there-are-bands</guid>
      <description>&lt;p&gt;Somewhere, sometime ago, someone came up with the term rockstar programmer. Perhaps like most catchy terms in our industry, it started out as an innocent idea, was bastardized by just the right people, and ultimately became the &lt;a href="http://www.hanselman.com/blog/TheMythOfTheRockstarProgrammer.aspx"&gt;marketing ick&lt;/a&gt; that it is today.&lt;/p&gt;

&lt;p&gt;Programming isn't about one-person wrecking crews, save for those pet projects you're just dabbling with on the side. Yet, some businesses still look for that mystical rockstar programmer to right all their existing wrongs. They have a heap of work to do, that heap is likely on fire right now, and they need someone to &lt;em&gt;f**ing rock the s**t out of it! How y'all doing Deeeeetroit?!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I've never seen good, solid software created with this kind of mentality. The work that goes into writing good code is arduous. It takes time. It takes contemplation and cooperation. More experienced programmers might know where more of the traps exist, but they still need time to think the problem through. Anyone can build something that appears to work for a short while, but the real work lies in making it work (or reliably adjust it to work) for the long-term. Otherwise, the business just goes into a perpetual game of “Who wants to be the next David Lee Roth for awhile?”&lt;/p&gt;

&lt;p&gt;Even more importantly, good software &lt;em&gt;teams&lt;/em&gt; can't be built around one-person shows. When I think of people that build good software, I think of a rock star's musical antithesis: the band itself. The best teams are small (say 2-5 members). And, they stick together. They know each member's tendencies because they've worked together for a long time. They know when to leave each other alone to nurture their piece of the product, and when to (yes), “get the band back together” at the right times. To me, that's the easiest way to guarantee a hit product: Create a tightly-knit group that's willing to stick it out for the long term, &lt;em&gt;together&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The best part about building software with a small, loyal team is that it absolves you from having to apply a myriad of processes–those that are otherwise essential for a group of technical individuals unfamiliar with each other to function at all. When teams are real small and have worked together for years, “people processes” like formalized sprints, scrums, or complex version control strategies are overkill. All of these tactics are meant to impose a consistent influx of ritualistic order onto an impending chaos. And, impending chaos happens to teams that are constantly turning over team members–whether or not there's a rockstar amongst them.&lt;/p&gt;

&lt;p&gt;Granted, small, long-lasting teams are not immune to marching down the normal dark paths of programming. Codebases still gets crufty. The forces of change still push code into unwieldy shapes. But, in these teams, getting out of the muck is much easier. The mindshare of what the intentions were, what tradeoffs were made, and how the realities came to be likely still exist in the minds of its team members. The methodical route to elegant code comes with less friction because you've all been in the battle together.&lt;/p&gt;

&lt;p&gt;Long-lived programming teams are rarely heralded in our industry. Similarly, cohesion and camaraderie amongst coders is severely underrated. What we have, instead, is a culture which champions the individual and focuses on forcing process to minimize the impact of the inevitable churn of a team's developers.&lt;/p&gt;

&lt;p&gt;If, alternatively, we championed the aging band instead of the rockstar, perhaps we'd also indirectly extinguish the perceived need for the mythical rockstar.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Republished with permission from &lt;a href="http://lifeimitatescode.com/there-are-rockstars-and-there-are-bands"&gt;Life Imitates Code&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The psychological battle of big refactorings</title>
      <dc:creator>Ka Wai Cheung</dc:creator>
      <pubDate>Sun, 24 Jul 2016 18:25:55 +0000</pubDate>
      <link>https://forem.com/developerscode/the-psychological-battle-of-big-refactorings</link>
      <guid>https://forem.com/developerscode/the-psychological-battle-of-big-refactorings</guid>
      <description>&lt;p&gt;We usually talk about refactoring code with the same kind of pedantic approach we do with all other kinds of software writing. We come up with recipes to abstract, break apart, and clarify. We fold these techniques together into larger ideas and catchier names like the Mikado method, the Big Bang approach, divide and conquer, or strangulation. OK, maybe not all of them are catchy.&lt;/p&gt;

&lt;p&gt;But, with all these strategic tools in our belt, a big refactoring still requires a tremendous amount of mental stamina and perseverance. In fact, what really makes it difficult has more to do with our own psychology than it does with the shape of the code itself.&lt;/p&gt;

&lt;p&gt;In most big refactorings, we don’t have the luxury of a complete rewrite. Features need to be built; bugs need to be squashed. Our only option is to push in-flight production code toward a new direction gradually. We make small changes continuously, seizing opportunities to remold portions of a system when the time is right.&lt;/p&gt;

&lt;p&gt;And therein lies the rub. Rehabbing code that still needs to serve its customers often requires some extra weight to allow the new code in, while still holding onto the old code we’ve yet to clean up.&lt;/p&gt;

&lt;p&gt;A refactoring might necessitate creating ephemeral objects and methods solely so we can fit the old temporarily with the new. While these extra pathways are being created, the code will feel like it’s bulging at the seams—because it &lt;em&gt;is&lt;/em&gt;. A big refactoring is rarely as hygienic as swapping an ugly piece for a pretty piece. It often means putting in a whole lot of intermediate structures; the ugly-but-necessary scaffolding to keep our patient able to work on his daily chores while still under the knife.&lt;/p&gt;

&lt;p&gt;In any big refactoring, you have to cope with two dissonant ideas: trying to make a codebase better and the reality that—in the midst of it, the code may actually feel a whole lot worse. This is, perhaps, the real reason that the whole process feels daunting. Every decision in a refactor weighs the short-term pain with the future payoff. And, often, the short-term pain convinces us that today is not the day to begin.&lt;/p&gt;

&lt;p&gt;However, once you’ve accepted this, a big refactoring becomes a lot more tolerable. You aren’t fighting the devil on your shoulder who wants to scold you for the off-course moves you’re making now to get to tomorrow’s pot of gold. Eventually, we reach that glorious day where the old abscesses can be completely removed and our new code is in full control. But, until then, the battle is as much in our minds as it is in our code.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Re-published with permission from &lt;a href="http://lifeimitatescode.com/the-psychological-battle-of-big-refactorings"&gt;Life Imitates Code&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
