<?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>DEV Community: Harry Dennen</title>
    <description>The latest articles on DEV Community by Harry Dennen (@hdennen).</description>
    <link>https://dev.to/hdennen</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%2F48070%2F70f510d1-2956-484c-96cd-1096e17ad6c9.jpeg</url>
      <title>DEV Community: Harry Dennen</title>
      <link>https://dev.to/hdennen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hdennen"/>
    <language>en</language>
    <item>
      <title>On Readability</title>
      <dc:creator>Harry Dennen</dc:creator>
      <pubDate>Thu, 29 Aug 2019 11:52:47 +0000</pubDate>
      <link>https://dev.to/hdennen/on-readability-4j75</link>
      <guid>https://dev.to/hdennen/on-readability-4j75</guid>
      <description>&lt;p&gt;None of this is new and I don’t know that it’s possible to follow these 100%. But if these are your targets then your code will be a pleasure to work with.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Function Does Not Rely on Hidden Cleverness
&lt;/h3&gt;

&lt;p&gt;Language peculiarities around order of interpretation for type coercion are confusing. Yes it’s fun to explore them, but leveraging them in production is effectively setting a landmine for the next developer who touches that code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--U0qQsrt5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/828/1%2AR7aLiky3T7mArMRCxwQ3zw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--U0qQsrt5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/828/1%2AR7aLiky3T7mArMRCxwQ3zw.png" alt=""&gt;&lt;/a&gt;Javascript favorite language comic&lt;/p&gt;

&lt;h3&gt;
  
  
  The Function Makes Sense in Isolation
&lt;/h3&gt;

&lt;p&gt;The reasons why a function was constructed are apparent from the title and contents of the function, without the need for additional context of the caller or any internally called functions.&lt;/p&gt;

&lt;p&gt;If a developer needs to read anything other than the function to understand what it’s doing, it’s not readable. The ultimate first prize is to convey precise meaning with the function name alone.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Function Assumes Knowledge of the Language
&lt;/h3&gt;

&lt;p&gt;Yes the semantics of Promises and methods like .reduce are cumbersome. Yes closure and context take effort to initially get your head around. Yes you still need to be comfortable with all of that.&lt;/p&gt;

&lt;p&gt;The one caveat here is to be careful not to fall into leveraging hidden cleverness.&lt;/p&gt;

&lt;h3&gt;
  
  
  Consistency Trumps Comfort
&lt;/h3&gt;

&lt;p&gt;So much of bug reduction boils down to eliminating surprises. If you join a front end team of ex-backend devs who are all writing functions like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function makeThingsHappen()
{
  // things happening
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;or they’re using / not using semicolons, or they’re using spaces / tabs, or [insert your pet peeve here], just bite the bullet and join in. Get some auto-formatting and let go of your petty preferences, they truly do not matter. Your ability to become comfortable in environments that go against your personal preferences is a professional quality — develop it.&lt;/p&gt;

</description>
      <category>readability</category>
      <category>programmingtips</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>Maintaining an Internal Library: Learning What I Thought I Already Knew</title>
      <dc:creator>Harry Dennen</dc:creator>
      <pubDate>Wed, 06 Feb 2019 15:59:59 +0000</pubDate>
      <link>https://dev.to/hdennen/maintaining-an-internal-library-learning-what-i-thought-i-already-knew-24of</link>
      <guid>https://dev.to/hdennen/maintaining-an-internal-library-learning-what-i-thought-i-already-knew-24of</guid>
      <description>

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cj9z9twu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/576/1%2ABE7_w7J42VQaQ82CzoljlQ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cj9z9twu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/576/1%2ABE7_w7J42VQaQ82CzoljlQ.gif" alt=""&gt;&lt;/a&gt;&lt;a href="http://www.smbc-comics.com/?id=2475"&gt;&lt;/a&gt;&lt;a href="http://www.smbc-comics.com/?id=2475"&gt;http://www.smbc-comics.com/?id=2475&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The product I work on needed to support window messaging with some company specific standards so I thought it would be nice to separate the transport from the main system entirely. That way we could give it to our customers to ease integration and use it in our other products to coerce a single standard.&lt;/p&gt;

&lt;p&gt;Also, it was also something I could experiment on without ten other devs pushing commits. 😅&lt;/p&gt;

&lt;p&gt;As it matured from a single file to a full library with a build / release / deployment pipeline I bumped into some &lt;em&gt;less obvious whys&lt;/em&gt; behind development best practices. Here they are.&lt;/p&gt;

&lt;h3&gt;
  
  
  Branching Strategy (gitflow)
&lt;/h3&gt;

&lt;p&gt;It is only faster to smash out commits on master if you ignore all the time costs that are not writing code.&lt;/p&gt;

&lt;p&gt;We know these to be true: You will change your mind. You will make mistakes. You will forget things. You will make poor decisions.&lt;/p&gt;

&lt;p&gt;The cost of these things is not just the backtracking and amending process, it is just as much if not more the &lt;strong&gt;building of mental context necessary to backtrack and amend&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Put a timer on the next time you take a week away from some code and see how long it takes to get back into that head space.&lt;/p&gt;

&lt;p&gt;Of the many, many benefits of gitflow, I found this to be the biggest time saver: Well kept branches keep mental context cordoned off and cohesive. If the branch has too many conceptual changes in it, the benefit goes away. &lt;strong&gt;One idea, one branch.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Updating a library is easy, updating dependency chains is not.
&lt;/h3&gt;

&lt;p&gt;We have a small helper library we ship which depends on my library, it also includes a demo site that needs to have the latest version. Our main client also depends on my library, and there is a partner repo that stores the helper library for live pickup. Simple. 😐&lt;/p&gt;

&lt;p&gt;Each of those external facing codebases are subject to a release process.&lt;/p&gt;

&lt;p&gt;It did not take long to discover that &lt;strong&gt;if coordination is key, then Automation is cornerstone.&lt;/strong&gt; Maybe it’s just me, but having more than a couple moving parts to coordinate meant that I almost always forgot some small piece.&lt;/p&gt;

&lt;p&gt;Also, a good project manager is worth their weight in gold.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://github.com/conventional-changelog/standard-version"&gt;Standard Version&lt;/a&gt; is Great!
&lt;/h3&gt;

&lt;p&gt;Honestly, spitting out an auto generated changelog with version bumping and a nice chore commit is fantastic. We already follow Angular commit guidelines on my main project so this was an easy transition. It’s not so practical on our main project due to the sheer volume of commits, but it &lt;a href="https://www.youtube.com/watch?v=9AvWs2X-bEA"&gt;sparks joy&lt;/a&gt; for this smaller stuff.&lt;/p&gt;

&lt;h3&gt;
  
  
  UNIT TESTS
&lt;/h3&gt;

&lt;p&gt;I have never been able to maintain TDD for very long. I am honestly not entirely sure it is a practical approach to modern JS applications. That said, well considered unit tests are 100% absolutely necessary.&lt;/p&gt;

&lt;p&gt;Well considered is the operative phrase here. We’ve all seen high coverage of unit tests that effectively test nothing. What I am talking about are tests that ensure a given public method is going to perform as expected under any state conditions. The easiest way to achieve this: use &lt;a href="https://en.wikipedia.org/wiki/Unary_function"&gt;unary&lt;/a&gt; &lt;a href="https://en.wikipedia.org/wiki/Pure_function"&gt;pure functions&lt;/a&gt;. Wrangle some state into an object, pass it to the function, get a return value. Test the wrangling; test the return.&lt;/p&gt;

&lt;p&gt;There are many other ways to assemble and test code. In my experience this is the simplest and most maintainable. And at the very least it will encourage you to abide by the &lt;a href="https://en.wikipedia.org/wiki/Law_of_Demeter"&gt;Law of Demeter&lt;/a&gt;.&lt;/p&gt;


</description>
      <category>unittesting</category>
      <category>javascript</category>
      <category>gitflow</category>
    </item>
    <item>
      <title>How File Structure Informs the Programming Model</title>
      <dc:creator>Harry Dennen</dc:creator>
      <pubDate>Thu, 10 May 2018 07:47:30 +0000</pubDate>
      <link>https://dev.to/hdennen/how-file-structure-informs-the-programming-model-29p0</link>
      <guid>https://dev.to/hdennen/how-file-structure-informs-the-programming-model-29p0</guid>
      <description>&lt;p&gt;We've recently put our application through a restructuring exercise to try and ease some pain points when the next major set of features come down the line.&lt;/p&gt;

&lt;p&gt;Two observations have come out of this process:&lt;/p&gt;

&lt;p&gt;1) The file structure of the application informs the decisions a developer makes about how to organize their logic.&lt;/p&gt;

&lt;p&gt;2) If the structure reflects poor organization, or categorization without intent, the code written in that structure will be poorly organized and categorized without intent.&lt;/p&gt;

&lt;h4&gt;
  
  
  Categorization Without Intent
&lt;/h4&gt;

&lt;p&gt;Consider the separation of logic and model. Where should that decision be made? At an application level or a feature level? Should it be made at all?&lt;/p&gt;

&lt;p&gt;Maybe we separate them at an application level. When building a feature we end up with a directory featureName in both the logic directory and the model directory. We have duplicate naming, but the directories map 1-to-1 with each other and we can make logic changes separate from the model.&lt;/p&gt;

&lt;p&gt;Ok.&lt;/p&gt;

&lt;p&gt;But what about the things we haven’t considered? The lines between system api, business domain, framework, and presentation? If those lines don’t exist in the file structure they won’t exist in the code.&lt;/p&gt;

&lt;p&gt;This is how logic grows to couple disparate system concerns. This is a painful place.&lt;/p&gt;

&lt;h4&gt;
  
  
  Drawing Lines
&lt;/h4&gt;

&lt;p&gt;The file structure should prescribe, at least at a high level, separations of functionality that move in one direction.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Things that run the app 
 → things that run the business domain 
 → things that present the business domain
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this organization, things that deal with the domain do not know about things that present it and vice versa, and they both use things that run the app.&lt;/p&gt;

&lt;p&gt;Let’s consider two scenarios, one with a type categorized file structure and one with a separation prescriptive file structure.&lt;/p&gt;

&lt;h4&gt;
  
  
  Type Categorized File Structure
&lt;/h4&gt;

&lt;p&gt;A developer is tasked with building a feature that has a slim and full version depending on the device spec. The developer (because they’re good at their job) abstracts out the system concern of device detection, then sets about building this dual type feature.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;device detection
 → feature model 
 → feature logic(arg: deviceType)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then business comes a month later and says “we want a medium spec version of this feature”. The developer is now in a position to either:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;a)&lt;/strong&gt; untangle the logic for feature version selection from the logic for running the feature&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;b)&lt;/strong&gt; add more if statements&lt;/p&gt;

&lt;p&gt;If they opt for A, the system will be more robust but business will ask why it takes so long. If they opt for B, they will have added more technical debt to burn them when anything else in that area changes but business will be happy with the turn around time.&lt;/p&gt;

&lt;p&gt;You could argue that if the developer really was a good developer they would have seen this coming. Ok. What if they develop 100 features? What’s the acceptable error rate? Why add the cognitive overhead of more problem anticipation when you can bake this one into the structure?&lt;/p&gt;

&lt;p&gt;In this case there is no protection from future change without a prescriptive file structure.&lt;/p&gt;

&lt;h4&gt;
  
  
  Concern Prescriptive File Structure
&lt;/h4&gt;

&lt;p&gt;Again a developer is tasked with building a feature that has a slim and full version depending on the device spec. The developer looks at the file structure of system -&amp;gt; domain | presentation and can organize the logic accordingly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;device detection
 → feature version functionalities - type[full, slim]
 → feature presentation(type[index])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here the structure has forced the distinction between running selected logic and defining selectable business logic to run.&lt;/p&gt;

&lt;p&gt;Then when business asks for the medium version of the feature, the solution is straightforward to implement.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;device detection
 → feature version functionalities - type[full, slim, medium]
 → feature presentation(type[index])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  How Does This Help Me?
&lt;/h4&gt;

&lt;p&gt;It’s easy to miss all the ways our environment influences our productivity, and I’m not talking about open plan offices 😒, I’m talking about the code bases we work in.&lt;/p&gt;

&lt;p&gt;Think of the times you’ve spent too long building mental context of a feature just to add a small tweak, or fix a bug. Or when business asks why something is taking so long and you respond with dissertation on quantum mechanics just to establish a starting point to describe how fucked everything is.&lt;/p&gt;

&lt;p&gt;A well organized code base can ease that pain.&lt;/p&gt;

&lt;p&gt;Designing and building software isn’t just about constructing things in a way that makes sense, it’s also about constructing things in a way that puts the developer in stronger position to handle what’s coming next.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>How 3 Lines of Code Reduced CPU and Memory Consumption by 13%</title>
      <dc:creator>Harry Dennen</dc:creator>
      <pubDate>Thu, 26 Apr 2018 20:17:20 +0000</pubDate>
      <link>https://dev.to/hdennen/how-3-lines-of-code-reduced-cpu-and-memory-consumption-by-13-m85</link>
      <guid>https://dev.to/hdennen/how-3-lines-of-code-reduced-cpu-and-memory-consumption-by-13-m85</guid>
      <description>&lt;p&gt;Or how assumptions can ruin the performance of your app.&lt;/p&gt;

&lt;p&gt;We have a fairly large Angular app using PixiJS for a lot of the rendering. Due to animations and constant updates to the canvas area, we’ve had to optimize as much as possible to keep the app running reasonably well on tablets.&lt;/p&gt;

&lt;p&gt;The standard optimizations have all been applied.&lt;/p&gt;

&lt;p&gt;Almost all components are set to &lt;code&gt;ChangeDetectionStrategy.onPush&lt;/code&gt;, async and broadcasts use &lt;code&gt;runOutsideAngular&lt;/code&gt;, logging is suppressed in production, etc.&lt;/p&gt;

&lt;p&gt;We’ve leveraged PixiJS texture cache and don’t make any &lt;code&gt;.update()&lt;/code&gt; calls on any display objects, and the &lt;code&gt;render()&lt;/code&gt; call on &lt;code&gt;requestAnimationFrame&lt;/code&gt; is run outside angular.&lt;/p&gt;

&lt;p&gt;One oversight is size of certain call stacks when major data changing events occur, but other than that things seem fairly contained.&lt;/p&gt;

&lt;p&gt;And yet we still had users noticing performance issues.&lt;/p&gt;

&lt;p&gt;Lots of ideas for this. Use web workers for transport, distribute chunks of functionality across separate call stacks to reduce frame drop, make absolutely all components use &lt;code&gt;ChangeDetectionStrategy.onPush&lt;/code&gt;, detach components and reattach for updates…&lt;/p&gt;

&lt;p&gt;A number of investigations into Angular and PixiJS performance issues were made.&lt;/p&gt;

&lt;p&gt;Then, while investigating the memory and timing costs of angular binding, RxJS subjects, and Angular bound subjects, I created a quick Angular CLI app. After setting everything up I checked a performance recording and noticed a distinct shortage of change detection runs.&lt;/p&gt;

&lt;p&gt;I should mention here that in order to keep our app’s frame rate decent we use &lt;code&gt;requestAnimationFrame&lt;/code&gt; on a loop to render the PixiJS stage. What we didn’t realize was that each RAF call was triggering change detection.&lt;/p&gt;

&lt;p&gt;But why?&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding How Your Tools Work is Important
&lt;/h3&gt;

&lt;p&gt;Enter Zone.js. I challenge any Angular developer to explain how Zone.js works and how Angular leverages Zones.&lt;/p&gt;

&lt;p&gt;Here’s the short version: Zone.js changes the prototypes of all async calls in the browser api (&lt;code&gt;setTimeout&lt;/code&gt;, etc.) so that a) context can be shared across call stacks and b) that hooks can be emitted at the end of micro, macro, and event tasks.&lt;/p&gt;

&lt;p&gt;Cool. And Angular?&lt;/p&gt;

&lt;p&gt;Angular creates (forks) a new zone called &lt;code&gt;NgZone&lt;/code&gt; which is a child of the root zone. This way when those end-of-task hooks are emitted, angular can run change detection on the off chance that a call has resulted in something, somewhere, changing. Which is great when you don’t have a ton of components. Not so much when you have lots.&lt;/p&gt;

&lt;p&gt;And I’m not knocking Angular’s change detection. given the size of our app it was actually doing an impressive job running.&lt;/p&gt;

&lt;p&gt;This issue is with the memory allocations required to run it. We ended up getting 12Mb garbage collections every 900ms.&lt;/p&gt;

&lt;p&gt;Ok, and PixiJS?&lt;/p&gt;

&lt;p&gt;Any event listener you register to a PixiJS object doesn’t hit the browser api. It hits PixiJS’s custom handling of events via their &lt;code&gt;InteractionManager&lt;/code&gt;. And it’s the &lt;code&gt;InteractionManager&lt;/code&gt; that registers a &lt;code&gt;pointermove&lt;/code&gt; event to the document… which has been patched by Zone …which has been forked by Angular.&lt;/p&gt;

&lt;p&gt;Ok. So our third party library is triggering change detection in our framework on mouse move — another problem — but that still doesn’t explain what’s triggering CD on every animation frame.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;side note update: we resolved this using `&lt;/em&gt;&lt;em&gt;Zone_symbol&lt;/em&gt;&lt;em&gt;BLACK_LISTED_EVENTS`&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Seriously Now, Understanding How Your Tools Work is Important
&lt;/h3&gt;

&lt;p&gt;PixiJS has a nice way of handling the scenario of a &lt;code&gt;DisplayObject&lt;/code&gt; animating past your mouse. Under normal conditions you wouldn’t get a &lt;code&gt;mouseover&lt;/code&gt; event because the mouse didn’t move, ergo no event.&lt;/p&gt;

&lt;p&gt;PixiJS is clever though. It’s using that &lt;code&gt;pointermove&lt;/code&gt; event to cache the last pointer event. Then on the next tick of pixi’s event loop it will check a moving &lt;code&gt;DisplayObject&lt;/code&gt;’s position against the cached pointer event’s location, and fire a &lt;code&gt;mouseover&lt;/code&gt; event if the display object is under the mouse.&lt;/p&gt;

&lt;p&gt;Ok, next tick of Pixi’s event loop though?&lt;/p&gt;

&lt;p&gt;Turns out in order to animate all their &lt;code&gt;DisplayObjects&lt;/code&gt; they have a shared ticker running … wait for it … as a callback in &lt;code&gt;requestAnimationFrame&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So now we not only have our render loop happening 60 times a second, we also have Pixi’s ticker triggering change detection 60 times a second. Not awesome.&lt;/p&gt;

&lt;p&gt;First prize is to get PixiJS to run in the root zone instead of Angular’s &lt;code&gt;NgZone&lt;/code&gt;, but in the meantime these 3 lines of code stop all the unnecessary change detection runs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ticker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Pixi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shared&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ticker&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="nx"&gt;ticker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;autoStart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="nx"&gt;ticker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We now have 1/3 of the garbage collections as before.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>angular</category>
      <category>pixijs</category>
      <category>performance</category>
    </item>
    <item>
      <title>How do you structure your app?</title>
      <dc:creator>Harry Dennen</dc:creator>
      <pubDate>Mon, 23 Apr 2018 09:48:17 +0000</pubDate>
      <link>https://dev.to/hdennen/how-do-you-structure-your-app-1jed</link>
      <guid>https://dev.to/hdennen/how-do-you-structure-your-app-1jed</guid>
      <description>

&lt;p&gt;We have a fairly large app currently organized at a high level into view, logic, model, communication, and utils. All files are aliased and we have scripts to handle any moves. For the most part we follow grouping by purpose, but it's still a bear to find things sometimes.&lt;/p&gt;

&lt;p&gt;This is the second time our team has taken a shot at reorganizing so I'd love to hear about everyone's experience with this.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example:
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;|-view
  |-engine
    |-core
    |-animation

  |-feature
    |-featureName
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;




</description>
      <category>webapp</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Opinions on externally controlled promises?</title>
      <dc:creator>Harry Dennen</dc:creator>
      <pubDate>Tue, 17 Apr 2018 07:50:31 +0000</pubDate>
      <link>https://dev.to/hdennen/opinions-on-externally-controlled-promises-1pef</link>
      <guid>https://dev.to/hdennen/opinions-on-externally-controlled-promises-1pef</guid>
      <description>&lt;p&gt;It's become a convenient pattern on my team to store resolve functions on an external object when coordinating some async work. Does anyone else use promises like this? Maybe there are some unforeseen pitfalls?&lt;/p&gt;

&lt;p&gt;For instance, let's say we're loading images and doing some canvas draws with them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CatPichurs&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// promise control&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;felix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolveFelix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;cheshire&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolveCheshire&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;garfield&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolveGarfield&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;resolve&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="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;felix&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cheshire&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;garfield&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;promise&lt;/span&gt;
    &lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;allTheCats&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;allTheCats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// some big reveal logic&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="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ExternalImageMagic&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cats&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;felix&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cheshire&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;garfield&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// load some pictures and draw&lt;/span&gt;
    &lt;span class="nx"&gt;cats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolveFelix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;felix&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// load more pictures and draw&lt;/span&gt;
    &lt;span class="nx"&gt;cats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolveCheshire&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cheshire&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// and a couple of Garfield to draw&lt;/span&gt;
    &lt;span class="nx"&gt;cats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolveGarfield&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;garfield&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;someCats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CatPichurs&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;imageStuff&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ExternalImageMagic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;someCats&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While this example makes no sense, you can see how this pattern is handy for keeping the cat rendering in one place and the image manipulation in another while ensuring both of them are coordinated.&lt;/p&gt;

&lt;p&gt;What does the dev community think?&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>es6</category>
      <category>discuss</category>
      <category>patterns</category>
    </item>
    <item>
      <title>Rolling Out Microsoft Teams — Lessons Learned</title>
      <dc:creator>Harry Dennen</dc:creator>
      <pubDate>Mon, 09 Apr 2018 10:03:18 +0000</pubDate>
      <link>https://dev.to/hdennen/rolling-out-microsoft-teams--lessons-learned-maf</link>
      <guid>https://dev.to/hdennen/rolling-out-microsoft-teams--lessons-learned-maf</guid>
      <description>

&lt;p&gt;When we introduced MS Teams as a trial run in my division we ran into a few problems some weeks in that proved to be rather painful and hurt adoption. We’re now rolling out to the entire company and this is part of our attempt to improve.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt; : Low visibility due to too many Teams — We ended up with every scrum team, dev team, and test team having an MS Team. While it seemed ok to begin with, these teams would change or disappear completely, people would leave and join, different scrum teams would need to communicate on a project, and project managers would end up in a million MS Teams… It got unruly quickly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt; : Teams should be tied to products, business units, or societies, NOT people. I know that sounds weird, (people are teams right?) but people move around and work on many different things.&lt;/p&gt;

&lt;p&gt;For example, we have a Team called Business Unit X¹ with channels for the scrum teams, releases, job roles, alerts, etc. That way project managers have good visibility, one scrum team can ask a question in another scrum team’s channel, and every member of the business unit has full visibility of what’s being talked about regarding the daily operations around products. In my opinion that visibility is a huge — if not the biggest — benefit of team chat and should be guarded.&lt;/p&gt;

&lt;p&gt;Outside of that we Product X client devs have our own client dev Team, which is useful for tracking our style guide, pull requests, team building, and anything else that is really only relevant to the Product X client developers.&lt;/p&gt;

&lt;p&gt;The rule of thumb here is: “will anyone outside of this group need to interact with us in this context?” If the answer is yes, then it’s probably a channel and not a Team.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt; : High noise to signal reducing visibility due to too many channels — Once we put all our channels into one Team, we now had the noisiest Team ever. Not awesome.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt; : Channel naming conventions. We prepend the channel name with the product, ie [Product X] Scrum Team X. Following the department we add a label, ie [Product Y] Project — Project Name Z.&lt;/p&gt;

&lt;p&gt;That way we add organization to the noise which makes it easier to parse signal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt; : Missing important information due to the synchronous nature of chat — you come in after being sick for a day and literally everything is bold or has numbers in red circles. Ain’t nobody got time for that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt; : Recognize the limits of persistent chat and that email still has a place. Team chat is great for real time conversation about certain things or broadcasting quick notices. But when something needs real consideration or focus on a single topic, then email is still the king. The main issue with team chat is &lt;a href="https://m.signalvnoise.com/is-group-chat-making-you-sweat-744659addf7d"&gt;the lack of a subject line&lt;/a&gt;. Email is also asynchronous, so you respond when ready. Team chat not so much, be wary of that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt; : Lack of adoption — the devs thought it was magic and the Business Analysts felt like they now had more work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt; : Put something that is specifically useful to an individual’s job in there. Just saying “we can all talk in a channel now!” is not an inherent benefit, and for some it’s actually a hurdle. We have tried to nail down clear benefits for individual job roles, but it’s tough. One that does work is ad hoc channels for things that cross cut job roles and have a short life span. Request for Change? New channel with a dev, a tester, a BA and the service manager in there. About to deploy? New channel. Great for visibility and once we can archive channels it’ll be even better.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt; : I didn’t know that channel existed. — Once it gets busy it’s easy to miss things.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt; : When creating a new channel always @mention all relevant people. That will notify them to join in. Also add and intro with a lifespan, it’s helpful to know what you’re getting into.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt; : What do I do now? — the noob guide. Lots of people get signed in, look at the interface blankly, then close it never to open again.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt; : Have a place for noobs to go. Slack nailed this, MS Teams has failed miserably. There’s no onboarding tooltip sequence or fun bots to show you around so we had to figure something out.&lt;/p&gt;

&lt;p&gt;First was to have an MS Team that everyone joins. We added a Random channel and a Help channel and when we got people signed in we walked them through joining and following those channels. That way they were in something and could participate immediately. The Random channel was actually the biggest draw card, turns out when someone’s first experience with something is fun they’re more likely not to hate it. Who knew?&lt;/p&gt;

&lt;p&gt;I’m sure there are more problems, but these were the ones that caused us pain the last few months. I hope your team can avoid making the same mistakes me and my team made last year.&lt;/p&gt;

&lt;p&gt;PS Outlook automagically creates a mailing list for any MS Team you’re in which will be delivered under groups in the left panel. Surprise.&lt;/p&gt;

&lt;p&gt;¹ Names changed to protect the guilty.&lt;/p&gt;


</description>
      <category>agile</category>
      <category>microsoftteams</category>
      <category>slack</category>
      <category>mattermost</category>
    </item>
    <item>
      <title>4 Regular Life JavaScript Code Smells (with RxJS)</title>
      <dc:creator>Harry Dennen</dc:creator>
      <pubDate>Wed, 14 Mar 2018 12:49:37 +0000</pubDate>
      <link>https://dev.to/hdennen/4-regular-life-javascript-code-smells-with-rxjs-5d0c</link>
      <guid>https://dev.to/hdennen/4-regular-life-javascript-code-smells-with-rxjs-5d0c</guid>
      <description>

&lt;h3&gt;
  
  
  The Public &lt;code&gt;init&lt;/code&gt; Method
&lt;/h3&gt;

&lt;p&gt;This is usually, but not always, a result of sequencing issues regarding a subscription.&lt;/p&gt;

&lt;p&gt;Example: if a service is subscribing to a ReplaySubject, but needs to actually get data that may not be ready yet, the subscribe call is often put into an init method to ensure &lt;code&gt;.subscribe()&lt;/code&gt; is called after the first &lt;code&gt;.next()&lt;/code&gt; is called.&lt;/p&gt;

&lt;p&gt;While this solves the immediate sequencing issue, it does nothing to remedy why the sequencing was an issue to begin with. Why is there a possibility that it subscribes to the ReplaySubject before the first &lt;code&gt;.next()&lt;/code&gt; is called? Why does that break things? Why is the observable a ReplaySubject at all?&lt;/p&gt;

&lt;p&gt;Another cause of this smell is a sibling or inter-level dependency.&lt;/p&gt;

&lt;p&gt;Example: service A notifies service B and service C, but service C needs a resulting object of service B’s response to service A. Therefore service C’s subscribe call is put in an init method and Service A’s Observable is made to be a ReplaySubject. ¯\_(ツ)_/¯&lt;/p&gt;

&lt;h3&gt;
  
  
  Property Checking
&lt;/h3&gt;

&lt;p&gt;99% of the time this is to account for the scenario where a method is called when it should not be called.&lt;/p&gt;

&lt;p&gt;Example: &lt;code&gt;.unsubscribe()&lt;/code&gt; is called on a property but there is no subscription on the property.&lt;/p&gt;

&lt;p&gt;Adding a property check will stop any stack traces, but it does not solve the underlying design problem. Why is it possible that &lt;code&gt;.unsubscribe()&lt;/code&gt; could be called before anything has been subscribed to? Is that a symptom of an underlying structural problem?&lt;/p&gt;

&lt;h3&gt;
  
  
  Flags
&lt;/h3&gt;

&lt;p&gt;While Angular has lured us into believing that flags are ok with their &lt;a href="https://angular.io/api/common/NgIf"&gt;NgIf directive&lt;/a&gt; , there are no other cases where this will not end badly (and that one might too).&lt;/p&gt;

&lt;p&gt;Flags do not scale. If you add a second flag, you now have not two, but four potential states to influence branching logic. O(n²) for cyclomatic complexity.&lt;/p&gt;

&lt;p&gt;Flags need to be toggled at the right time. Time being the operative word there. Flags introduce another level of sequencing to control flow, and while it might be trivial in the beginning, it can spin out of control quickly.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Early Return
&lt;/h3&gt;

&lt;p&gt;This one might get some push back. Yes it’s handy. No it doesn’t cause any direct harm. But why was the function called in the first place if all it was going to do was nothing?&lt;/p&gt;

&lt;p&gt;This usually indicates a deficiency in, or the absence of, upstream branching logic.&lt;/p&gt;

&lt;p&gt;Example: Subject A has subscribers X,Y,Z. A’s payload in the &lt;code&gt;.next()&lt;/code&gt; call is boolean. X,Y, and Z’s response methods return early if the boolean is true, false, true respectively.&lt;/p&gt;

&lt;p&gt;Let’s say Subject A is broadcasting on .interval of 200ms and every minute the payload is false. While that results in a ton of unnecessary calls, it also creates a pattern where it’s OK to subscribe to something when you only need to be notified a fraction of the time.&lt;/p&gt;

&lt;p&gt;The issue isn’t with the early return itself, the issue is what it can hide. Much like property checking, it will hide stack traces but it will not resolve or illuminate any structural problems.&lt;/p&gt;


</description>
      <category>rxjs</category>
      <category>typescript</category>
      <category>javascript</category>
      <category>codesmells</category>
    </item>
    <item>
      <title>On State Dependence and Coupling</title>
      <dc:creator>Harry Dennen</dc:creator>
      <pubDate>Wed, 20 Dec 2017 13:37:59 +0000</pubDate>
      <link>https://dev.to/hdennen/on-state-dependence-and-coupling--5af9</link>
      <guid>https://dev.to/hdennen/on-state-dependence-and-coupling--5af9</guid>
      <description>

&lt;p&gt;Any function in your application depending on the state of a mutable object === a bad time.&lt;/p&gt;

&lt;p&gt;What is so bad about depending on the state of a mutating object for a function to work correctly every time?&lt;/p&gt;

&lt;p&gt;Everything. Here is an abridged list of all of the things.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Things will break when something goes wrong in the mutating object. Notice I said when, I’ll get to that, but for now you’re screwed because the dependent function will behave in ways that may or may not be correct. And this is worse than wrong, because things that are sometimes wrong can make it to production. Awesome right? This highlights the problem with non deterministic functions.&lt;/li&gt;
&lt;li&gt;Not only do you have two objects tightly coupled, but the coupling is implicit. Because the mutable state has no explicit tie to the dependent function, a developer has no way of knowing that any mutations or functional changes to said mutable object might alter the function of the system in seemingly unconnected ways. Congratulations, you planted a land mine. This highlights the importance of single responsibility principle and separation of concerns principle.&lt;/li&gt;
&lt;li&gt;Something will go wrong because land mines get stepped on when code is iterated upon. This highlights the importance of adhering to principles as justification for why you do things instead of “I had to because [insert contextual and shortsighted reasoning here]”&lt;/li&gt;
&lt;li&gt;The problem you didn’t solve in the first place will become apparent when the dependent function goes wrong, and solving it now may require serious refactoring. The thing about decisions is that they stack and branch. If you make a bad one early on, then any good decision downstream is compromised. This highlights the importance good planning and design as well as the open closed principle.&lt;/li&gt;
&lt;li&gt;RACE CONDITIONS! Not only is the function dependent on the state of the mutable object, but it’s also dependent on the timing between when the dependent function is called and when the object is mutated. The best part about this is that you can now make a change in a completely unrelated area of the system and cause this race condition to exhibit. This highlights the impact of state altering control flow and how class cohesion (or lack of it) impacts maintainability.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So how do we avoid this? There are lots of ways, but ultimately every situation is different and good principles are a great guide (just like real life!). Also, look into function purity.&lt;/p&gt;

&lt;p&gt;Choosing domain specific heuristics is also a good idea. Things like: tend toward flat structure, prefer long descriptive names over short ambiguous ones, try to push branching logic up the call stack, and anything else that can add a bit of direction to a given situation when you’re not sure what to do. Which for me is most of the time.&lt;/p&gt;


</description>
      <category>javascript</category>
      <category>softwaredevelopment</category>
    </item>
  </channel>
</rss>
