<?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: Ted M. Young</title>
    <description>The latest articles on Forem by Ted M. Young (@jitterted).</description>
    <link>https://forem.com/jitterted</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%2F9891%2F19a7fb1b-f2b9-4fe6-b121-e1ab73d762ff.jpg</url>
      <title>Forem: Ted M. Young</title>
      <link>https://forem.com/jitterted</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/jitterted"/>
    <language>en</language>
    <item>
      <title>Remote Learning Ensembles (Mob Programming)</title>
      <dc:creator>Ted M. Young</dc:creator>
      <pubDate>Sat, 15 Jan 2022 21:14:31 +0000</pubDate>
      <link>https://forem.com/jitterted/remote-learning-ensembles-mob-programming-15ej</link>
      <guid>https://forem.com/jitterted/remote-learning-ensembles-mob-programming-15ej</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;See updated version of this article &lt;a href="https://ted.dev/articles/2022/01/15/remote-learning-ensembles/"&gt;here.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;2022-03-22: Updates since I first wrote this can be found as bracketed &amp;amp; italic remarks inline.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  How I Run Remote Learning Ensembles
&lt;/h1&gt;

&lt;p&gt;The Ensemble (mob) Programming sessions that I've been running for the past few months are centered around improving developer skills in test-driven development (TDD), domain-driven design (DDD), and Hexagonal Architecture, with a focus on taking small, safe steps and frequent refactoring. Since the codebase is Java, it's turned out that all attendees are using IntelliJ IDEA, so an additional focus has been learning its shortcuts and the less common automated refactorings (such as Move Method).&lt;/p&gt;

&lt;p&gt;Since the focus is on learning skills and not getting "work" done, I stay out of the rotation, observing and providing guidance and advice along the way. I also serve as the "customer" providing direction on the features being developed. [&lt;em&gt;However, if there's only 2 attendees, I'll drop into the rotation.&lt;/em&gt;]&lt;/p&gt;

&lt;p&gt;Below you'll find information on how I currently run the Learning Ensembles (much of this was gathered from various sources, some adapted, and some learned by trial and error).&lt;/p&gt;

&lt;p&gt;I've found that using GitHub-based hand-offs, with the awesome command-line tool &lt;a href="https://mob.sh"&gt;mob.sh&lt;/a&gt;, to work better than other mechanisms that I've tried. It allows people to use their own computer and IDE, which means they're not only comfortable using tools that they're used to, but building skills (such as shortcut keys) in their "natural" environment. The downside is that there's a bit of disruption during the hand-off, mainly around the new Driver taking over and possibly having to rearrange editor windows and open up files, though this tends to be less of a problem after a complete cycle of turns.&lt;/p&gt;

&lt;h2&gt;
  
  
  Roles
&lt;/h2&gt;

&lt;p&gt;We call the person at the keyboard (and sharing their screen) the "Driver" and the person directing them the "Navigator". I've gone back and forth about the role names (e.g., typist, director), and have found that metaphor of getting to a destination with a "Driver" and "Navigator" to be well-suited.&lt;/p&gt;

&lt;h3&gt;
  
  
  Driver
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;When starting your turn, clearly state that you're ready for the Navigator with an "I'm Ready". This is needed so the Driver can do the &lt;code&gt;mob start&lt;/code&gt; command (to get the latest code on their machine) and arrange the IDE windows as needed. [&lt;em&gt;We've standardized on a split screen, with the test code on the left, feature code on the right.&lt;/em&gt;]&lt;/li&gt;
&lt;li&gt;Driver carries out the Navigator's intent—there is only one Navigator, otherwise the Driver can get confused.&lt;/li&gt;
&lt;li&gt;If the Driver is unsure what to do next, they ask the Navigator for clarification.

&lt;ul&gt;
&lt;li&gt;It's often helpful for the Driver to offer choices "do you want me to extract the whole block, or just line 24?"&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Avoid "Runaway Driver" where the Driver does more than (or different things from) what was asked.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Navigator
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Declares intent at the highest level, only providing more detail if the Driver asks.

&lt;ul&gt;
&lt;li&gt;Start with intent: "extract the loop to a new method named Process Transactions"&lt;/li&gt;
&lt;li&gt;Provide more detail: "select lines 24 thru 28, use Refactor then Extract Method.&lt;/li&gt;
&lt;li&gt;Even more detail: "click on the word 'for' on line 24, press the expand selection key a few times, now click on..."&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Avoid micro-managing ("backseat driving") the fixing of syntax errors or typos.&lt;/li&gt;
&lt;li&gt;It's important that the Navigator correct the Driver if the Driver didn't do what was desired, due to either confusion by the Driver, or a mistake by the Navigator.

&lt;ul&gt;
&lt;li&gt;Communication is hard, and the only way a Navigator knows that they were understood is if the Driver did what was desired.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;When the turn is over, inform the next Navigator of what you had in mind. However, it's up to that Navigator to either continue down that road, or try something else.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Onboarding New Participants
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Get their GitHub username

&lt;ul&gt;
&lt;li&gt;Add the username as collaborator to the repository that will be used for the Ensemble&lt;/li&gt;
&lt;li&gt;They'll need to accept the invite, so do this enough in advance&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Participants will need to install and verify that these work:

&lt;ul&gt;
&lt;li&gt;The mob.sh tool (which requires &lt;code&gt;git&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Zoom, especially share screen privileges

&lt;ul&gt;
&lt;li&gt;Do audio check, video check is optional&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Whatever IDE they're comfortable with

&lt;ul&gt;
&lt;li&gt;Increase font size of IDE to at least 16px for screen sharing readability (sometimes 18px is needed!)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Correct version of Java (11 or later)&lt;/li&gt;
&lt;li&gt;Clone the repository via SSH if possible (this makes it easier to push)&lt;/li&gt;
&lt;li&gt;Build and run all of the tests&lt;/li&gt;
&lt;li&gt;Do a test &lt;code&gt;mob start&lt;/code&gt; and &lt;code&gt;mob next&lt;/code&gt; to ensure privileges are set up correctly &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Facilitator Preparation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Fill out names in the Mob timer

&lt;ul&gt;
&lt;li&gt;We use &lt;a href="https://mobti.me"&gt;https://mobti.me&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Make sure to rotate so folks aren't always in the same order or are navigating the same driver&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Verify participants have accepted GitHub repo invitations&lt;/li&gt;
&lt;li&gt;Verify repository has the latest code (all changes since last session pushed)&lt;/li&gt;
&lt;li&gt;Review retrospective and Mission notes from prior sessions

&lt;ul&gt;
&lt;li&gt;I keep these notes in the same repository as the project code&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Ensure goals (I called this the "Mission") for the upcoming session are clear&lt;/li&gt;
&lt;li&gt;Send a link to the Zoom that we'll be using (even if it's the same one, people like/need the reminder)

&lt;ul&gt;
&lt;li&gt;[&lt;em&gt;I use my Ensembler tool to handle this: see &lt;a href="https://dev.tothe%20MobReg%20repository"&gt;https://github.com/jitterted/mobreg&lt;/a&gt; for more.&lt;/em&gt;]&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Session
&lt;/h2&gt;

&lt;p&gt;This is based on my experience with 90-105 minute-long sessions [&lt;em&gt;I've found 105-115 minutes—just under 2 hours—better for groups that only get together once a week, or less, in order to remember and/or understand the context&lt;/em&gt;]. We cap the size to 5 active participants, with turn times of 5 minutes each.&lt;/p&gt;

&lt;p&gt;We have two main roles: Driver and Navigator (as described above). When the turn is over (after the 5-minute timer has expired), the Navigator becomes the new Driver and the Driver goes back into the general crowd. [&lt;em&gt;We now go the other way: Driver becomes Navigator, and Navigator returns to the crowd, as the Driver has the code already in their head/fingers.&lt;/em&gt;]&lt;/p&gt;

&lt;h3&gt;
  
  
  The Huddle
&lt;/h3&gt;

&lt;p&gt;[&lt;em&gt;Added details on The Huddle&lt;/em&gt;]&lt;/p&gt;

&lt;p&gt;The starting Huddle is a way for the group to sync up and understand where things are and what the next task is. This is important as people haven't seen the code for a week or more (or never!). Once the first Navigator agrees that they have a sense of what to do, the Huddle ends.&lt;/p&gt;

&lt;p&gt;During the Ensemble, people can get lost, can disagree on which way to go, etc., and so anyone can call for a Huddle. The timer is stopped and discussion starts. It's important to get back to the code, so if the discussion becomes too detailed (or too abstract!), it's time to see if there's enough understanding to take the next step, without worrying about the steps after that. As the saying goes, "discuss in code" (i.e., writing actual code) is better at demonstrating what approach is better/worse than just talking about it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Agenda
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Introduce anyone who's new&lt;/li&gt;
&lt;li&gt;Provide the mob timer link (if a separate one like &lt;a href="https://mobti.me"&gt;mobti.me&lt;/a&gt; is used)&lt;/li&gt;
&lt;li&gt;Remind folks of any Code of Conduct

&lt;ul&gt;
&lt;li&gt;At a minimum, remind them that this is a learning experience and to be compassionate and curious&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create (or update) a &lt;code&gt;participants.txt&lt;/code&gt; file with the date and start a list with the facilitator's name as the 0th entry. For example:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Session #10 - Friday, May 28, 2021
----------------------------------
0. Ted (@JitterTed)
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;[&lt;em&gt;I stopped putting my name as facilitator, and now it starts with the first participant. Twitter name is optional.&lt;/em&gt;]&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Do one rotation by having each participant do the steps below when it's their turn. The purpose of this exercise it to ensure everyone can share their screen, update their local copy of the repo, and push changes to the repo, as well as an check of their audio and font size. Doing it at the beginning means that it won't interrupt the Ensemble's flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Share their screen (I make sure that Zoom allows participants to "steal" the screen sharing from the current sharer)&lt;/li&gt;
&lt;li&gt;Execute a &lt;code&gt;mob start&lt;/code&gt;, once it completes...&lt;/li&gt;
&lt;li&gt;Type their name in the &lt;code&gt;participants.txt&lt;/code&gt; file (if it doesn't show up, or is missing other participants, you know something's not quite right), e.g.:
&lt;/li&gt;
&lt;/ol&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Participants from Ensemble #50 on March 4, 2022
   -----------------------------------------------
   1. Hoffman
   2. Moxie
&lt;/code&gt;&lt;/pre&gt;



&lt;ol&gt;
&lt;li&gt;Execute a &lt;code&gt;mob next&lt;/code&gt; and once it completes...&lt;/li&gt;
&lt;li&gt;Announce "Ready for next DRIVER"&lt;/li&gt;
&lt;li&gt;Next driver takes over and repeats from step 1 until everyone has had a turn&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;Explain/review the mission for the session&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I keep this in a text file in the same repository as the project code&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Team does a "huddle", where they discuss the mission, make sure they understand it, and define the next task or two.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;The first Driver shares their screen, does a "mob start" and when complete declares "I'm ready"&lt;/p&gt;

&lt;p&gt;[&lt;em&gt;Usually they'll start by running all the tests&lt;/em&gt;]&lt;/p&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Navigator provides instructions to the Driver&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;When the turn is over (the timer has gone off), the Navigator relays their intent (what they were trying to achieve) to the next Navigator&lt;/p&gt;

&lt;p&gt;[&lt;em&gt;If the Navigator/Driver are almost done with a task, I'll usually let them finish it before moving to the next person.&lt;/em&gt;]&lt;/p&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Things that need to be done (delete that test, rename that class, fix that flaky test) are dropped into chat&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Side-comments about the work are also dropped into chat&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;After each full cycle (everyone has taken their turn once), the facilitator runs a "mini-retrospective", if the ensemble feels that things are in a good flow, the mini-retro can be skipped.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Often the 2nd time around, folks feel the need to mini-retro to regroup and gain perspective.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;[&lt;em&gt;With a more experienced group, I've not found this necessary, as folks seem to learn to call for a Huddle as needed&lt;/em&gt;] &lt;/p&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The final turn ends when there's 15-20 minutes left in the scheduled ensemble time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Conclude with a retrospective, where each person in the rotation provides thoughts, observations, things they learn, etc., until everyone has run out of things to say. Then, things to do more or less of, what went well/not so well, etc., are noted in an outline or mind map.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Facilitator shares observations (the more specific and concrete, the better), such as "I noticed it took 3 turns to finally get from red to green" or questions, such as "how did it feel to leave have that test continue to be flaky", or "was anyone uncomfortable with the poor code formatting in that method?"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Session ends with cleaning up of the pending tasks, collecting undone ones from chat, checking off those that are done, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Everyone waves goodbye!&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;Note that we have changed how we run the Ensembles over time, because of things brought up in our Retrospectives. I'll follow up with a post on what's changed since the above was written. One non-trivial change was the order of Driver-Navigator. When we swapped that order, we found less of a need to "hand off" intentions.&lt;/p&gt;

&lt;p&gt;Stay tuned!&lt;/p&gt;

</description>
      <category>learning</category>
      <category>mobbing</category>
      <category>ensemble</category>
    </item>
    <item>
      <title>My Favorite IntelliJ IDEA Plugins</title>
      <dc:creator>Ted M. Young</dc:creator>
      <pubDate>Wed, 21 Apr 2021 23:30:28 +0000</pubDate>
      <link>https://forem.com/jitterted/my-favorite-intellij-idea-plugins-4o1b</link>
      <guid>https://forem.com/jitterted/my-favorite-intellij-idea-plugins-4o1b</guid>
      <description>&lt;p&gt;As an instructor and experienced &lt;a href="https://www.jetbrains.com/idea/"&gt;IntelliJ IDEA&lt;/a&gt; user (some might say fanatic), I'm often asked about the plugins that I use. To be honest, I don't use a lot of plugins, I find myself mostly focused on improving the quality and testability of code by using IntelliJ IDEA's powerful automated refactorings, along with its Live Template and Postfix features. However, there are some very useful plugins that are "standard equipment" for me when I install it on a new machine. Note that I use many of the built-in plugins from JetBrains that I'm not including in this list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Git
&lt;/h2&gt;

&lt;p&gt;For better or worse (I think worse, but that's a separate rant), Git is the de facto standard for version control. IntelliJ IDEA's support for Git is great, but the plugin &lt;strong&gt;GitToolBox&lt;/strong&gt; makes it even better. I rarely find myself using Git from the command line anymore, which I'm very happy about.&lt;/p&gt;

&lt;h2&gt;
  
  
  PlantUML
&lt;/h2&gt;

&lt;p&gt;I love drawing diagrams, but I hate using visual drawing tools, because I spend so much time fiddling with the little things. I've been using &lt;strong&gt;&lt;a href="https://plantuml.com/"&gt;PlantUML&lt;/a&gt;&lt;/strong&gt; for years to draw sequence, class, and state machine diagrams by describing it in a text file. Having it as a plugin in IntelliJ IDEA makes it that much more valuable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Presentation Assistant
&lt;/h2&gt;

&lt;p&gt;Pretty much what it says in its description: "shows name and Win/Mac shortcuts of any action you invoke". As an instructor and live coder, I always have this installed and activated. I like how it shows both the Mac shortcuts (I use a Mac) as well as the Windows &amp;amp; Linux shortcuts so those who are watching can learn the shortcuts for their platform. It's also helpful when I'm writing how to use the shortcuts since I don't have to search for the shortcuts for the other platforms, I just hit the keys and &lt;strong&gt;Presentation Assistant&lt;/strong&gt; shows me the keys for Windows/Linux.&lt;/p&gt;

&lt;h2&gt;
  
  
  Floobits
&lt;/h2&gt;

&lt;p&gt;The holy grail of synchronous editing of a project by multiple people has not quite been solved, but of the tools I've tried out (Floobits, CodeTogether, Code With Me, and GitDuck), &lt;strong&gt;&lt;a href="https://floobits.com/"&gt;Floobits&lt;/a&gt;&lt;/strong&gt; has come closest to what I want: the ability to use the full power of IntelliJ IDEA, and let the other people use whatever tool they want. It's not perfect and sometimes things get out of sync or just don't sync in the first place, but when it works, it's great. In the Mob Programming groups that I lead, though, I have shifted to using &lt;a href="https://mob.sh/"&gt;mob.sh&lt;/a&gt; as it's much more reliable.&lt;/p&gt;

&lt;h2&gt;
  
  
  SonarLint
&lt;/h2&gt;

&lt;p&gt;Last and, yes, least, is &lt;strong&gt;&lt;a href="https://www.sonarlint.org/"&gt;SonarLint&lt;/a&gt;&lt;/strong&gt; an open-source project. It's not that it's not a powerful tool (it is), it's just that I find myself constantly telling it to stop bugging me about things that I turn it off when teaching, and then forget to turn it back on when I'm just coding. Perhaps some more fine-tuning would get it to the right level of nudging, but I'm not there yet. However, it has saved me from some silly mistakes, so it's worth installing and trying out.&lt;/p&gt;

&lt;h2&gt;
  
  
  What About You?
&lt;/h2&gt;

&lt;p&gt;What plugins do you find &lt;strong&gt;indispensable?&lt;/strong&gt; Let me know as a comment below, or on Twitter, where I can be found as &lt;a href="https://twitter.com/jitterted"&gt;@JitterTed&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>java</category>
      <category>intellij</category>
      <category>plugins</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Top Five "Forever" Books for Coders</title>
      <dc:creator>Ted M. Young</dc:creator>
      <pubDate>Tue, 16 Jun 2020 00:39:01 +0000</pubDate>
      <link>https://forem.com/jitterted/top-five-forever-books-2m9</link>
      <guid>https://forem.com/jitterted/top-five-forever-books-2m9</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;On my &lt;a href="https://JitterTed.Live"&gt;live coding stream&lt;/a&gt;, the question often comes up: "what books would you recommend?" about various topics. Since it's such a common question, I decided to set aside time on my stream to pull together my recommendations and discuss them with my viewers. At first, I was going to write one of those standard "Top 10" lists, but I realized my recommendations are more nuanced than that (and that I have way more than 10 that I want to mention), so I'm dividing the "top" list into several, more focused lists. As we were discussing the book candidates on the stream, I realized there are "classics" that I think are required reading for any coder who wants to really step up their ability to write more maintainable and testable code, so those are the books in this first list: the "Forever" Books.&lt;/p&gt;

&lt;p&gt;This list has books that have been around for 15-20 years and will likely apply for 15-20 more. They came out during the "golden" period of 1995-2005 when Design Patterns, Refactoring, and eXtreme Programming broke through and started becoming well-known. Future lists will cover more recent books on developer testing, object-oriented design, and tech-specific books (e.g., Java, Spring framework, etc.).&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Read
&lt;/h3&gt;

&lt;p&gt;Instead of just listing the books, I provide a recommendation on how I'd read the book, since some of them, like the 883-page xUnit Test Patterns book, are quite large (and heavy if you have the physical book), and you don't need to read every page. Even if they're not that long, not all of these books are meant to be read cover-to-cover and serve as cookbook-like references. These books also have quite a bit of code and I tend to skip over most of that on my first read-through. Unlike most people it seems, I actually enjoy reading the Preface and Introduction chapters of books and since they often provide their own "how to read this book" advice, it's worth taking the extra time to read. &lt;/p&gt;

&lt;p&gt;If you can, read these books as part of a Study Group. I was lucky to be part of a group (the Silicon Valley Patterns Group) that met weekly to discuss these books (and many more), chapter by chapter, and followed the patterns described &lt;a href="https://www.industriallogic.com/blog/pools-of-insight-study-groups/"&gt;here&lt;/a&gt;. We were also lucky enough to get access to the in-progress books (such as WELC and DDD) and provide feedback to the authors.&lt;/p&gt;

&lt;h3&gt;
  
  
  Disclaimer
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;This list has affiliate links where I might make a few cents on your purchase, but in addition to the typical Amazon links, I've included links (IndieBound) that would help support local and independent bookstores, without which the world would be a poorer place. I look forward to the day when I can leisurely and casually browse my local bookstores again. If the indie bookstores in your area aren't yet open (e.g., for curb-side pickup or drop-off), you can buy from indie bookstores online by following the link to BookShop.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Forever List
&lt;/h2&gt;

&lt;p&gt;And now, on to the list! These are my Top 5 "forever" (aka "classic") books that I strongly recommend folks buy and have on their shelf. They are not in any particular order, so I'm not numbering them. Except for &lt;em&gt;eXtreme Programming eXplained&lt;/em&gt;, they're not books that are meant to be read linearly all the way through, but contain a catalog of recipes to be slowly learned over time.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;"Working Effectively with Legacy Code"&lt;/em&gt; by Michael Feathers
&lt;/h3&gt;

&lt;p&gt;This is the book that most people reference when discussing dealing with legacy code, which, let's be honest, is probably all of us. Usually referred to by the &lt;em&gt;initialism&lt;/em&gt; WELC.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read Chapters 1-4&lt;/li&gt;
&lt;li&gt;Skip Chapter 5 (Tools)&lt;/li&gt;
&lt;li&gt;Read Chapter 6 (I Don't Have Much Time and I Have to Change It)&lt;/li&gt;
&lt;li&gt;Skim the rest of the book, that way you're aware of techniques to use when you run into those situations. Or maybe you're already in those situations? If so, read on!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://www.indiebound.org/book/9780131177055?aff=jitterted"&gt;Buy WELC on IndieBound&lt;/a&gt;&lt;br&gt;
&lt;a href="https://amzn.to/2UMIoep"&gt;Buy WELC on Amazon&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;"xUnit Test Patterns"&lt;/em&gt; by Gerard Meszaros
&lt;/h3&gt;

&lt;p&gt;This book's subtitle is "Refactoring Test Code", but I think it's much more than that, as it got me to really think about how I write and structure automated tests.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read Introduction through Chapter 6. No really, read the Introduction.&lt;/li&gt;
&lt;li&gt;Skip Chapter 7 if you know JUnit/xUnit etc.&lt;/li&gt;
&lt;li&gt;Skip Chapters 8, 9 on Fixture Management -- I don't think it's as important as other chapters.&lt;/li&gt;
&lt;li&gt;Read Chapter 10 for how to verify (assert) -- you might be surprised what you learn from this chapter.&lt;/li&gt;
&lt;li&gt;Read Chapter 11 at least twice(!) about "Test Doubles"

&lt;ul&gt;
&lt;li&gt;Forget everything you knew about mocks and learn this terminology.&lt;/li&gt;
&lt;li&gt;Eventually this will become second-nature, but if you overuse mocks in your current codebases, learning the different kinds of Test Doubles will help you wean off of them.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Skip Chapters 12-14, unless you're really not sure how to organize your tests. Not that it's not important, it's more that this isn't the main problem that I see in teams that I coach and train.&lt;/li&gt;
&lt;li&gt;Skim the rest of the Chapters for Test Code Smells (Chapter 15ff) and Test Strategy Patterns (Chapter 18ff).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://www.indiebound.org/book/9780131495050?aff=jitterted"&gt;Buy xUnit on IndieBound&lt;/a&gt;&lt;br&gt;
&lt;a href="https://amzn.to/2YAWBfy"&gt;Buy xUnit on Amazon&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;"Refactoring: Improving the Design of Existing Code"&lt;/em&gt; by Martin Fowler
&lt;/h3&gt;

&lt;p&gt;There are two editions of this book: the First Edition, from 1999, uses Java, whereas the Second Edition came out in 2018 and switched to JavaScript for the code examples (as well as being tailored towards JavaScript idioms, such as using &lt;em&gt;function&lt;/em&gt; instead of &lt;em&gt;method&lt;/em&gt;). There are obviously more significant changes than just the code, as described by Martin &lt;a href="https://martinfowler.com/articles/refactoring-2nd-changes.html"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So which edition to buy? If you're not a Java developer, then the Second Edition is what you want. However, if you &lt;strong&gt;are&lt;/strong&gt; a Java developer, then maybe both? The First Edition is available used for around US$15-20 used, and the Second Edition is about US$30, so I don't think that's too much to spend on one of the most valuable books you can get. The First Edition is nice to have available to see the refactorings in a more familiar language, and the Second Edition has improved and updated the "code smells" and principles text.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read Chapters 1, 2&lt;/li&gt;
&lt;li&gt;Skim Chapter 3 (identifies code smells)&lt;/li&gt;
&lt;li&gt;Can skip Chapter 4 (Test)&lt;/li&gt;
&lt;li&gt;Skim through list of Refactorings (Chapter 6 through to the end) -- this is the refactoring "catalog"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://www.biblio.com/9780201485677"&gt;Buy Refactoring 1st Edition on Biblio&lt;/a&gt;&lt;br&gt;
&lt;a href="https://amzn.to/2UMAl13"&gt;Buy Refactoring 1st Edition on Amazon&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.indiebound.org/book/9780134757599?aff=jitterted"&gt;Buy Refactoring 2nd Edition on IndieBound&lt;/a&gt;&lt;br&gt;
&lt;a href="https://amzn.to/2B7ZFHY"&gt;Buy Refactoring 2nd Edition on Amazon&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;"Domain-Driven Design"&lt;/em&gt; by Eric Evans
&lt;/h3&gt;

&lt;p&gt;I use the patterns and the principles from this book &lt;strong&gt;all the time&lt;/strong&gt;. If you've ever heard me speak in person or on stream, you'll hear me use terms such as "ubiquitous language" and "context boundary" and "repository pattern" quite a bit. This is not the easiest book to understand, not because it's poorly written, but because there's a lot packed into it, and it's written in a certain Pattern Language style that can take a bit of getting used to. The main point that you should take away is thinking about your applications Domain First (what should the system be &lt;em&gt;doing&lt;/em&gt;) instead of Data[base] First (what &lt;em&gt;data&lt;/em&gt; are we keeping track of). The more you try to use these concepts and patterns, the more you'll start to see ways of applying them -- it's a virtuous cycle.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read all the way through&lt;/li&gt;
&lt;li&gt;On your second read-through, start with Part IV "Strategic Design" and work your way, Part by Part towards the beginning of the book.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://www.indiebound.org/book/9780321125217?aff=jitterted"&gt;Buy Domain-Driven Design on IndieBound&lt;/a&gt;&lt;br&gt;
&lt;a href="https://amzn.to/3e6Gc8X"&gt;Buy Domain-Driven Design on Amazon&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5. &lt;em&gt;"eXtreme Programming Explained"&lt;/em&gt; by Kent Beck
&lt;/h3&gt;

&lt;p&gt;This book (also known as XP Explained) had such a huge impact on the way I, and soon enough the teams I worked with, developed software. The idea of pair programming was mind-blowing for me, and the emphasis on developer testing, something I was doing anyway, was reassuring. The flattening of the "Cost of Change" curve was also surprising as it went against what I had learned about project management of software development projects: earlier is better, later is badder. That assumption is wrong and is the cause of premature flexibility (You Ain't Gonna Need It, aka YAGNI) that makes software &lt;em&gt;less&lt;/em&gt; flexible rather than more.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The links are for the 2nd Edition, which is almost a full rewrite of the 1st, but retains the overall thrust of XP:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;XP is a style of software development focusing on excellent application of programming techniques, clear communication, and teamwork which allows us to accomplish things we previously could not even imagine.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Read the whole thing&lt;/li&gt;
&lt;li&gt;Discuss with your colleagues&lt;/li&gt;
&lt;li&gt;Read it again&lt;/li&gt;
&lt;li&gt;Repeat on a regular basis&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://www.indiebound.org/book/9780321278654?aff=jitterted"&gt;Buy eXtreme Programming Explained 2nd Ed. on IndieBound&lt;/a&gt;&lt;br&gt;
&lt;a href="https://amzn.to/3hwyBTn"&gt;Buy eXtreme Programming Explained 2nd Ed. on Amazon&lt;/a&gt;&lt;/p&gt;

</description>
      <category>classic</category>
      <category>coding</category>
      <category>learning</category>
      <category>books</category>
    </item>
    <item>
      <title>Stop Trying to Outsmart the Java Compiler</title>
      <dc:creator>Ted M. Young</dc:creator>
      <pubDate>Thu, 23 Jan 2020 17:11:55 +0000</pubDate>
      <link>https://forem.com/jitterted/stop-trying-to-outsmart-the-java-compiler-1876</link>
      <guid>https://forem.com/jitterted/stop-trying-to-outsmart-the-java-compiler-1876</guid>
      <description>&lt;p&gt;When Java 9 was (finally) released, it was considered a disappointment, or a disaster, depending on who you talked to. Lost among the debates about Project Jigsaw (the Java Module System) was a big improvement to the way strings are concatenated.&lt;/p&gt;

&lt;p&gt;When I talk to even seasoned Java coders, many aren't aware of the changes that &lt;a href="https://openjdk.java.net/jeps/280"&gt;JEP 280&lt;/a&gt; (JEP is the "Java Enhancement Proposal", part of the process of bringing new features into Java) brought to the world. Unfortunately, the title of that proposal: "Indify String Concatenation" didn't exactly help. (For what it's worth, indify here means using &lt;code&gt;invokedynamic&lt;/code&gt;, which doesn't help if you don't know what that means either.)&lt;/p&gt;

&lt;p&gt;I'll summarize the changes and benefits, but leave the detailed explanations and performance benchmarks to the experts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before Java 9
&lt;/h2&gt;

&lt;p&gt;When you concatenated strings, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;fullName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;the Java compiler would automatically change it to be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;fullName&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;StringBuilder&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" "&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The idea here is that &lt;code&gt;StringBuilder&lt;/code&gt; is generally more performant. The nice thing is, you didn't have to write that StringBuilder code yourself! But what happens in the future when there are new and faster ways to concatenate strings? Do we have to then replace all of our StringBuilders? (For those who remember, we did that with the move from &lt;code&gt;StringBuffer&lt;/code&gt; to &lt;code&gt;StringBuilder&lt;/code&gt; when we realized that synchronizing everything wasn't a good idea.)&lt;/p&gt;

&lt;p&gt;With Java 9 and JEP 280, the compiler doesn't try and pick the best thing (StringBuilder? StringBuffer? Plain concatenation?), it just calls out to a method that the runtime (the JVM) can replace with something optimized for the &lt;em&gt;runtime&lt;/em&gt; behavior of the code. Essentially the code above would look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;fullName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;makeConcatWithConstants&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;SPACE_CONSTANT&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;(Though that's not exactly right, because there's more going on -- read JEP 280 for the details -- it's close enough for this discussion.)&lt;/p&gt;

&lt;p&gt;As Claes Redestad says in the "String Concatenation, redux" post: "optimize the runtime, not the bytecode".&lt;/p&gt;

&lt;h2&gt;
  
  
  Not For Loops
&lt;/h2&gt;

&lt;p&gt;While the compiler is smart enough to optimize the string concatenation above, if you're in a loop, especially a very large one, you'll need to manually pull the &lt;code&gt;StringBuilder&lt;/code&gt; variable outside of the loop and use &lt;code&gt;StringBuilder&lt;/code&gt;'s &lt;code&gt;.append()&lt;/code&gt; method for the concatenation. For example, if you write&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"line ("&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;")\n"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then the compiler will only optimize the concatenation going on inside the loop, which is still not as efficient as the "manual" optimization of pulling the &lt;code&gt;StringBuilder&lt;/code&gt; outside the loop, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;    &lt;span class="nc"&gt;StringBuilder&lt;/span&gt; &lt;span class="n"&gt;lineBuilder&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;StringBuilder&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;lineBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"line "&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"\n"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lineBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;On the other hand, if your loop is guaranteed to be pretty small (like this one, with the constant of 20 lines), then I'd lean towards the more readable &lt;code&gt;+&lt;/code&gt; for concatenation than using &lt;code&gt;StringBuilder&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't Trust Me and Maybe Not Benchmarks
&lt;/h2&gt;

&lt;p&gt;You can try "micro" benchmarks on the above code (using the &lt;a href="https://openjdk.java.net/projects/code-tools/jmh/"&gt;JMH tool&lt;/a&gt;), but these days there's so many interactions between the runtime JVM, including the garbage collector and optimizer, the operating system, and the chip you're running on that it's difficult to generalize from a micro-benchmark. I'd much rather rely on higher-level measurements, such as load testing, to find bottlenecks. I often tell my Java students that you're much more likely to have slow systems because you're slinging JSON around, because you have to parse and serialize them, than because your string concatenation isn't optimized.&lt;/p&gt;

&lt;h2&gt;
  
  
  Slower in Java 11?
&lt;/h2&gt;

&lt;p&gt;While all of this (and other things) have resulted in better String concatenation performance (see Heinz Kabutz's presentations linked in the references section), not everything has been smooth. It turns out there is a performance regression (unresolved when I wrote this) in Java 11.0.2 where string concatenation might be a bit slower. See &lt;a href="https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8221760"&gt;this bug&lt;/a&gt; for details.&lt;/p&gt;

&lt;h2&gt;
  
  
  References:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://openjdk.java.net/jeps/280"&gt;JEP 280 - Indify String Concatenation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=z3yu1kjtcok"&gt;Video: "Enough java.lang.String to Hang Ourselves" by Heinz Kabutz&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.javaspecialists.eu/talks/pdfs/2018%20Oracle%20Code%20One%20in%20San%20Francisco,%20USA%20-%20%22Enough%20java.lang.String%20to%20Hang%20Ourselves%20...%22%20by%20Heinz%20Kabutz%20and%20Dmitry%20Vyazelenko.pdf"&gt;Slides from "Enough java.lang.String to Hang Ourselves"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://marxsoftware.blogspot.com/2019/01/jep-280-indify-string-concatenations.html"&gt;"JDK 9/JEP 280: String Concatenations Will Never Be the Same" by Dustin Marx&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cl4es.github.io/2019/05/14/String-Concat-Redux.html"&gt;"String concatenation, redux" from Claes Redestad&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://metebalci.com/blog/digging-into-jep-280-indify-string-concatenation/"&gt;"Digging into JEP 280: Indify String Concatenation" by Mete Balci&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>java</category>
      <category>performance</category>
      <category>compiler</category>
      <category>concatenation</category>
    </item>
    <item>
      <title>Live Coding Learnings - June 21, 2019 </title>
      <dc:creator>Ted M. Young</dc:creator>
      <pubDate>Sun, 23 Jun 2019 22:31:14 +0000</pubDate>
      <link>https://forem.com/jitterted/live-coding-learnings-june-21-2019-1ihd</link>
      <guid>https://forem.com/jitterted/live-coding-learnings-june-21-2019-1ihd</guid>
      <description>&lt;h1&gt;
  
  
  Quizdown: Episode 20
&lt;/h1&gt;

&lt;p&gt;The 20th episode of working on Quizdown, a Java+Spring-based app that uses a Markdown-like syntax to create coding quizzes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stories Implemented
&lt;/h2&gt;

&lt;p&gt;After a non-trivial refactoring (see &lt;strong&gt;No Naked Data Structures&lt;/strong&gt; below),&lt;br&gt;
I now have the ability to move back and forth between questions. The HTML generation now generates &lt;code&gt;checked&lt;/code&gt; if that choice was previously selected. Next step is to load the user's responses from the database and send that to the UI controller.&lt;/p&gt;

&lt;h2&gt;
  
  
  HTML: Use disabled Attribute for Button or Link
&lt;/h2&gt;

&lt;p&gt;When I was looking for the proper CSS class to use to display a button as disabled, I found that instead of using, say, an &lt;code&gt;is-disabled&lt;/code&gt; CSS class, HTML supports &lt;code&gt;disabled&lt;/code&gt; as an attribute on both &lt;code&gt;button&lt;/code&gt; and link (&lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt;). For example, to show the link as &lt;em&gt;disabled&lt;/em&gt; instead of:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"is-disabled"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/question/0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Previous Question&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;you would use the &lt;code&gt;disabled&lt;/code&gt; attribute like this:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/question/0"&lt;/span&gt; &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Previous Question&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  No Naked Data Structures
&lt;/h2&gt;

&lt;p&gt;One of my Java design heuristics is &lt;em&gt;No Naked Data Structures&lt;/em&gt;, which means wrapping raw data structures (&lt;code&gt;List&lt;/code&gt;, &lt;code&gt;Map&lt;/code&gt;, etc.) in a type so you can pass it around and interact with it in a way that makes sense from a domain point of view.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is similar to the &lt;em&gt;No Stringly-Typed Code&lt;/em&gt; heuristic: don't use &lt;code&gt;String&lt;/code&gt; everywhere, instead use class and interface types. For details see &lt;a href="http://wiki.c2.com/?StringlyTyped"&gt;here&lt;/a&gt; and &lt;a href="https://kamilszymanski.github.io/refactoring-stringly-typed-systems/"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When adding the feature to allow users to go back and forth through the questions, I needed to have the choices that the user made be available. Previously I was storing those choices as a &lt;code&gt;Set&amp;lt;String&amp;gt;&lt;/code&gt;, as it was straightforward and it wasn't being used in many places. However, once I needed it in more places (pushing it back up to the front-end from the database), handing around a "naked" &lt;code&gt;Set&lt;/code&gt; made the code a bit harder to read and work with. For example, with the &lt;code&gt;Set&lt;/code&gt;, figuring out if it's correct depended on the type of question (&lt;code&gt;FIB&lt;/code&gt; is a fill-in-the-blank and &lt;code&gt;MC&lt;/code&gt; is multiple-choice):&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;isCorrectFor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@NonNull&lt;/span&gt; &lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;questionType&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;FIB&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;correctChoices&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;containsAll&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;MC&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;correctChoices&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;};&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is pretty typical code, but unless you're familiar with the specifics of &lt;code&gt;Set&lt;/code&gt;, you may have to do a bit of JavaDoc reading to ensure you understand it correctly. By replacing it with a &lt;code&gt;Response&lt;/code&gt; type that &lt;em&gt;encapsulates&lt;/em&gt; the &lt;code&gt;Set&lt;/code&gt;, the code above becomes:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;isCorrectFor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;questionType&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;FIB&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;matchesAny&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;correctResponse&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;MC&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;allMatch&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;correctResponse&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;};&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, this may not be such an amazing improvement (I'm still toying with the naming), but it leads to the next step (which I haven't done yet) of pushing the behavior that's specific to the question type into a subclass of Response, e.g., a &lt;code&gt;FibResponse&lt;/code&gt; and &lt;code&gt;McResponse&lt;/code&gt;, which would look like:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;isCorrectFor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;correctlyMatches&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;correctResponse&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Completely delegating how responses are compared to the class that knows best how to do that comparison.&lt;/p&gt;

&lt;p&gt;In my training and coaching of Java developers, the use of Stringly types and Naked Data Structures is the cause for much pain when things change, so always try and encapsulate Strings into Value Objects and wrap up your data structures into its own class.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exposing &lt;code&gt;asSet()&lt;/code&gt; on Response: breaks Encapsulation?
&lt;/h2&gt;

&lt;p&gt;By encapsulating the &lt;code&gt;Set&amp;lt;String&amp;gt;&lt;/code&gt; inside of &lt;code&gt;Response&lt;/code&gt; means that when I need to display the response choices or persist them to a database (i.e., hand the response across the &lt;em&gt;domain boundary&lt;/em&gt;) I need to get those choices as a set, so the &lt;code&gt;Response&lt;/code&gt; class has a method&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;asSet&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;copyOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// return a copy of our internal field&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That returns the choices as a &lt;code&gt;Set&amp;lt;String&amp;gt;&lt;/code&gt;. I use this in the &lt;code&gt;GradedAnswerView&lt;/code&gt; class to convert it to a comma-separated &lt;code&gt;String&lt;/code&gt;:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;responseAsString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Answer&lt;/span&gt; &lt;span class="n"&gt;answer&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;answer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;response&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;asSet&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                 &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                 &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sorted&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                 &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;joining&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;", "&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You might think: &lt;em&gt;oh no, this is breaking encapsulation by exposing the set&lt;/em&gt;, but I'm not really doing that, because I'm returning a copy of my internal storage of the response choices. I never expose the field itself, so the only way to modify the internal &lt;code&gt;Response&lt;/code&gt; data is only through its methods. Modifying the copy would have no effect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Empty varargs
&lt;/h2&gt;

&lt;p&gt;I don't think I had realized this before, but calling a method defined with varargs (e.g., &lt;code&gt;createFrom(String... strings)&lt;/code&gt;) means that you can call that method with &lt;em&gt;no&lt;/em&gt; arguments: &lt;code&gt;createFrom()&lt;/code&gt;, and inside this method, the &lt;code&gt;strings&lt;/code&gt; argument would be an empty array.&lt;/p&gt;

&lt;p&gt;This means I didn't have to special-case turning varargs into an empty Set, because calling &lt;code&gt;Set.of()&lt;/code&gt; with no arguments will turn into an empty Set (technically an &lt;code&gt;ImmutableCollections.emptySet()&lt;/code&gt; as of Java 9), which is what I'd want. &lt;/p&gt;

&lt;h2&gt;
  
  
  Collaboration Tests
&lt;/h2&gt;

&lt;p&gt;Most of my tests are unit tests, in that they are testing code in a class by working with that class as closely as possible. For example, the &lt;a href="https://github.com/jitterted/quizdown/blob/7b9c120604fa3957e464b0f965fef1ab339de1fe/src/main/java/com/jitterted/quizdown/adapter/web/MultipleChoiceTransformer.java#L45"&gt;&lt;code&gt;Choice&lt;/code&gt; class&lt;/a&gt; can be directly tested without any other objects. However, the &lt;code&gt;QuestionTransformer&lt;/code&gt; can't be tested on its own as its job is mostly to collaborate with more specific transformers to do its job, i.e., its job is to integrate or collaborate with the other objects. This means that I don't need to comprehensively test all of the behavior of all of the classes that are involved, just a test or two that would ensure that &lt;code&gt;QuestionTransformer&lt;/code&gt; is &lt;em&gt;correctly&lt;/em&gt; collaborating with (in this case, propagating the response to) other objects.&lt;/p&gt;

&lt;p&gt;You can see a clip from my stream where I do this: &lt;a href="https://www.twitch.tv/videos/443315061"&gt;https://www.twitch.tv/videos/443315061&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Be sure and tune in to my next live coding stream: &lt;a href="https://twitch.tv/jitterted"&gt;https://twitch.tv/jitterted&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Want to support me? Become a Patron at &lt;a href="https://patreon.com/jitterted"&gt;https://patreon.com/jitterted&lt;/a&gt;&lt;/p&gt;

</description>
      <category>todayilearned</category>
      <category>java</category>
      <category>unittesting</category>
      <category>livecoding</category>
    </item>
    <item>
      <title>Live Coding Learnings - June 20, 2019</title>
      <dc:creator>Ted M. Young</dc:creator>
      <pubDate>Fri, 21 Jun 2019 04:42:35 +0000</pubDate>
      <link>https://forem.com/jitterted/live-coding-learnings-june-20-2019-43g1</link>
      <guid>https://forem.com/jitterted/live-coding-learnings-june-20-2019-43g1</guid>
      <description>&lt;h1&gt;
  
  
  Pure Refactoring
&lt;/h1&gt;

&lt;p&gt;I didn't stream today, but was reviewing some of my past streams (mining it for content for my Java coaching clients) and realized my coding rule that I mentioned earlier was incomplete. The rule I stated was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Do not change code unless it is to make a failing test pass (or fail better).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;However, I had forgotten that this rule doesn't apply when doing pure refactoring. In that case, the rule is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tests must pass before refactoring and remain passing -- with no changes -- after refactoring.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Some might say that this is too strict, and I'd agree, I'll bend these rules when using my &lt;strong&gt;judgment&lt;/strong&gt;, but for teaching novices, it's a good way to differentiate when you're changing code to add capabilities vs. when you're changing internals to improve the code itself. The latter is refactoring and if tests are breaking, you're either changing too much, or your tests were too &lt;em&gt;low-level&lt;/em&gt; (tied too tightly to the implementation details).&lt;/p&gt;

&lt;p&gt;For example, if I have the code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;price&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;cachedPrice&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then it shouldn't matter to tests or other code if I changed it to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;price&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt; &lt;span class="nl"&gt;item:&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In other words, whether I calculate the price when requested, or cache it (the first example), it's an implementation detail that the class should be free to change, i.e., refactor, without affecting other code.&lt;/p&gt;

&lt;p&gt;If tests are relying on one or the other behavior, then that's likely (though not always) a problem where you might want to re-think your test code.&lt;/p&gt;




&lt;p&gt;Be sure and tune in to my next live coding stream: &lt;a href="https://twitch.tv/jitterted"&gt;https://twitch.tv/jitterted&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>todayilearned</category>
      <category>java</category>
      <category>tdd</category>
      <category>refactoring</category>
    </item>
    <item>
      <title>Live Coding Learnings - June 19, 2019 </title>
      <dc:creator>Ted M. Young</dc:creator>
      <pubDate>Thu, 20 Jun 2019 02:25:55 +0000</pubDate>
      <link>https://forem.com/jitterted/live-coding-learnings-june-19-2019-3acn</link>
      <guid>https://forem.com/jitterted/live-coding-learnings-june-19-2019-3acn</guid>
      <description>&lt;h1&gt;
  
  
  Quizdown: Episode 19
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Stories Implemented
&lt;/h2&gt;

&lt;p&gt;Today I completed the implementation of handling code-fenced blocks (surrounded by three backticks) and "regular" text blocks. The differences between the two is that the code block can have embedded blank lines, but regular text uses blank lines to separate the paragraph blocks. For example, given this Quizdown text:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Here, line 2 is blank, meaning that the first line is a regular text paragraph. However, while line 8 is blank, it's inside of a code block, so it remains all one block up through line 11, where the code-fence ends. Then line 12 is a blank outside of a code block, so the final two lines (not separated by a blank line) are considered the third block (a paragraph).&lt;/p&gt;

&lt;p&gt;Getting the above correct, while also handling inline markup (e.g., asterisks and underscores to bold and italicize words) was a bit tricky, but good tests helped me get it all straight. &lt;/p&gt;

&lt;h2&gt;
  
  
  Content inside of a &lt;code&gt;&amp;lt;pre&amp;gt;&lt;/code&gt; still requires entity escaping
&lt;/h2&gt;

&lt;p&gt;Since one of the main goals of the Quizdown project is to easily include Java code into the questions and answer choices, I have to be able to show things inside angle brackets for generics, e.g., &lt;code&gt;List&amp;lt;String&amp;gt;&lt;/code&gt;. Normally things inside angle brackets are treated as HTML tags, but I had thought that if they were inside of a &lt;code&gt;&amp;lt;pre&amp;gt;&lt;/code&gt; tag, they'd be shown as-is. In fact, the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/pre"&gt;Mozilla docs for &lt;code&gt;pre&lt;/code&gt;&lt;/a&gt; say (emphasis mine):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The HTML &lt;code&gt;&amp;lt;pre&amp;gt;&lt;/code&gt; element represents preformatted text which is to be presented &lt;strong&gt;exactly as written&lt;/strong&gt; in the HTML file.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This isn't exactly true, as angle brackets still need to be escaped, i.e., the &lt;code&gt;&amp;lt;&lt;/code&gt; is replaced with &lt;code&gt;&amp;amp;lt;&lt;/code&gt;, the &lt;code&gt;&amp;gt;&lt;/code&gt; with &lt;code&gt;&amp;amp;gt;&lt;/code&gt;, etc.&lt;/p&gt;

&lt;p&gt;So, this meant I had to do HTML entity escaping on all text -- but before I turned any Quizdown into HTML (the dreaded double-encoding).&lt;/p&gt;

&lt;h2&gt;
  
  
  Prism needs &lt;code&gt;&amp;lt;code&amp;gt;&lt;/code&gt; inside of &lt;code&gt;&amp;lt;pre&amp;gt;&lt;/code&gt; for highlighting
&lt;/h2&gt;

&lt;p&gt;I use the &lt;a href="https://prismjs.com/"&gt;Prism&lt;/a&gt; library and CSS to do the syntax highlighting for the Java code fragments in the quiz. When I finished processing the code-fenced blocks, which I surrounded with a &lt;code&gt;&amp;lt;pre&amp;gt;&lt;/code&gt;, I wasn't seeing any syntax highlighting. It turns out, that Prism has the &lt;strong&gt;additional&lt;/strong&gt; requirement that any code needs to be inside of a &lt;code&gt;&amp;lt;code&amp;gt;&lt;/code&gt; element as well for it to highlight it. The docs need to be improved on this (and some other) areas, with better examples. I'll be looking into filing a pull-request for that.&lt;/p&gt;

&lt;h2&gt;
  
  
  No code changes without failing test
&lt;/h2&gt;

&lt;p&gt;Even though I've been doing TDD for many years, I &lt;em&gt;still&lt;/em&gt; fall into the habit of jumping in to fix the code first instead of a test. As a reminder (to myself, if nobody else) the rule is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Do not change code unless it is to make a &lt;em&gt;failing&lt;/em&gt; test pass (or fail better).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;By &lt;em&gt;fail better&lt;/em&gt;, sometimes a failing test is a &lt;strong&gt;success&lt;/strong&gt; if it failed as predicted and desired.&lt;/p&gt;

&lt;h2&gt;
  
  
  Regex Backreferences
&lt;/h2&gt;

&lt;p&gt;I forgot to mention in yesterday's "lessons learned" that &lt;em&gt;wietlol&lt;/em&gt; (one of my Twitch VIP viewers) taught me how to use backreferences so that I always match underscores with underscores (e.g., &lt;code&gt;_italic_&lt;/code&gt;) and stars with stars (e.g., &lt;code&gt;**bold**&lt;/code&gt;) and not a mixture (e.g., &lt;code&gt;_oops*&lt;/code&gt;). An example regex that uses backreferences is:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;([*_])(?&amp;lt;italic&amp;gt;.*?)\1(?!\1)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;which means: first, match on either a star or underscore, then some text (with a named capture group), and then match in the same way as was matched up-front. The &lt;code&gt;?!&lt;/code&gt; at the end is a &lt;em&gt;negative lookahead&lt;/em&gt; so the when I'm doing the replacement, I match against the right-most character. To see how this works, looking at the &lt;a href="https://github.com/jitterted/quizdown/blob/74932ff8ef3ab830c14a92f5c0847e14181676f0/src/test/java/com/jitterted/quizdown/adapter/InlineMarkupToHtmlTransformerTest.java#L20"&gt;Quizdown test&lt;/a&gt; might be useful.&lt;/p&gt;

&lt;p&gt;A good reference on backreferences (ha ha) is &lt;a href="https://www.regular-expressions.info/backref.html"&gt;here&lt;/a&gt; and lookahead is &lt;a href="https://www.regular-expressions.info/lookaround.html"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  In Closing
&lt;/h2&gt;

&lt;p&gt;As always, the source code for this project can be found &lt;a href="https://github.com/jitterted/quizdown"&gt;on GitHub&lt;/a&gt;, and you can watch my past streams &lt;a href="https://www.twitch.tv/jitterted/videos"&gt;on Twitch&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Tune in to my next live coding stream: &lt;a href="https://Twitch.tv/jitterted"&gt;https://Twitch.tv/jitterted&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>todayilearned</category>
      <category>java</category>
      <category>tdd</category>
      <category>livecoding</category>
    </item>
    <item>
      <title>Live Coding Learnings - June 18, 2019</title>
      <dc:creator>Ted M. Young</dc:creator>
      <pubDate>Wed, 19 Jun 2019 00:49:29 +0000</pubDate>
      <link>https://forem.com/jitterted/live-coding-learnings-june-18-2019-6nb</link>
      <guid>https://forem.com/jitterted/live-coding-learnings-june-18-2019-6nb</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Summary of what I learned in today's live coding stream at &lt;a href="https://twitch.tv/jitterted"&gt;https://twitch.tv/jitterted&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Matching newlines in RegEx
&lt;/h2&gt;

&lt;p&gt;For the text I'm working with, I want regex search and replace to work across newlines (by default matching stops at a new line). Today I learned that I need to pre-pend this: &lt;code&gt;(?s)&lt;/code&gt; to the regex String, which turns on &lt;code&gt;DOTALL&lt;/code&gt; mode and therefore the dot wildcard will match across new lines. For details, see the JavaDoc: &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html#DOTALL"&gt;https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html#DOTALL&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Example of &lt;code&gt;matches()&lt;/code&gt; using &lt;code&gt;DOTALL&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;I want to search for text that's surrounded by 3 equal signs (&lt;code&gt;===&lt;/code&gt;)&lt;br&gt;
both at the beginning and at the end. The text can span multiple lines.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Before text.
===
Text inside the equals signs.
===
Outside text.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;To search for the text, I would use the &lt;code&gt;String.matches()&lt;/code&gt; method, like this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;found&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;matches&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"(?s)===(.*?)==="&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Which returns &lt;code&gt;true&lt;/code&gt; if the pattern is found, as it would be in the&lt;br&gt;
above example.&lt;/p&gt;
&lt;h3&gt;
  
  
  Example of &lt;code&gt;replaceAll&lt;/code&gt; using &lt;code&gt;DOTALL&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;If I want to replace the triple backtick code block with a &lt;code&gt;&amp;lt;pre&amp;gt;&lt;/code&gt; tag (as I do in my live stream), then I'd do this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Which would output this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;pre&amp;gt;
public class Stock {

}
&amp;lt;/pre&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Scanner for Parsing
&lt;/h2&gt;

&lt;p&gt;I used &lt;code&gt;Scanner&lt;/code&gt; in a few places and forgot about it until I was reminded by one of my regular stream viewers (thanks &lt;em&gt;flamaddidle84&lt;/em&gt;!). Today, I wanted to parse some text and split the lines whenever there was an empty line between two non-empty lines.&lt;/p&gt;

&lt;p&gt;For example, given this text:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Block one.
Still part of block one.
Yep, still part of block one.

Block two here.
Still part of block two.

Last block here.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;I want to end up with three pieces of text. Using the &lt;code&gt;Scanner&lt;/code&gt; class and the fact that the delimiter can be specified, this is all I needed:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Scanner&lt;/span&gt; &lt;span class="n"&gt;scanner&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;Scanner&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;useDelimiter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"\n\n"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Then, all I had to do was use the &lt;code&gt;scanner.tokens()&lt;/code&gt; method (only available starting in Java 9) to give me a stream of these blocks, e.g.:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;scanner&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tokens&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
       &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"&amp;lt;p&amp;gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"&amp;lt;/p&amp;gt;\n"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
       &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Which uses &lt;code&gt;replaceAll&lt;/code&gt; on each block to surround it with the HTML &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; (paragraph) tag. Here's a full code example:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;When run, it results in this output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;p&amp;gt;Block one.
Still part of block one.
Yep, still part of block one.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Block two here.
Still part of block two.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Last block here.
&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Watch Me Live Code on Twitch
&lt;/h1&gt;

&lt;p&gt;If you want to see how I use TDD to code in Java and Spring, and learn with me, tune in to my daily stream at &lt;a href="https://twitch.tv/jitterted"&gt;Twitch.TV/JitterTed&lt;/a&gt;. I'm usually streaming from 12pm PDT (1900 UTC) for around 3 hours. You can also chat with me on &lt;a href="https://discord.gg/9XDfBSZ"&gt;my Discord&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>todayilearned</category>
      <category>livecoding</category>
      <category>java</category>
    </item>
  </channel>
</rss>
