Refactoring to Understand

I’ve been working on a large front-end application for the past several months. The code base is mature and has its own unique style. I started out on the project adding new features, following the patterns already established. I didn’t consider the architecture much — partly because I didn’t need to, and partly because it was overwhelming. After I became familiar with it I began to understand some of the patterns, but still could not grasp the entirety of it.

It wasn’t until I had the chance to refactor some pieces that it finally clicked. Looking at the code with the ‘refactoring’ mindset opened up my view. When writing a new feature, writing new code, it’s easy to get tunnel vision — follow existing patterns because they’re understood. The release deadline is close, this piece is blocking the next task, whatever — they’re all reasons to focus small. Refactoring made me think about abstractions over specifics, which forced me to reason about the system.

A refactoring mindset pushed me focus on why a function or module was written as it was. The reasons for focusing small don’t exist. Were there assumptions that proved to be false? Does this function serve its original intent? Same question, but for the entire module? Does following existing patterns negatively affect how this function was written? It also exposes bad testing — if I refactor the implementation of a function and tests fail, were those tests just noise? Again, it pushes focus to the why, rather than tunnel vision on how.

I haven’t spent much time thinking about it besides this — I had a spark of insight and decided to write it down. I could see the argument that code reviews should catch those why questions, or that architectural concerns should always be in mind when writing new code. They aren’t always though, and looking at code with refactoring in mind helps me read it differently — and better.

Task management, planning, and monthly logs

 

I work in a role where I am largely self-directed. I do not have a technical lead or manager, I report to our creative director. That puts me in a unique role, especially as my work requires a breadth of development responsibilities. I set up servers, do back and front end development, and meet with clients to discuss everything my role touches. Without formal technical direction, planning work is as much my responsibility as actually doing it.

Since I want to be good at my job, I had to figure out the best system to manage and plan tasks, keep a record of my progress, and organize any notes I take. I needed to make something efficient but also platform independent. I’ve burned myself getting too attached to a service (cough, Evernote, cough), that made switching take a lot of time and effort.

I’ve followed the GTD system for a while, and that informed some of the decisions I made about how to structure my own system. I added what extra I needed and de-emphasized the pieces that are less applicable to me. I use the theory, if not the direct methods.

Since this system works for me, and has for a sustainable amount of time, I thought it was worth sharing. There are two components, the structure and the workflow.

Structure

The entire system relies on text — which lets me move between editors, cloud syncing providers, platforms; it can go anywhere I need it. I make one exception for Trello, since it’s so versatile and I can export my entire account to JSON should I need to. The following are the tent-poles of the system:

Trello

Trello is where tasks are kept, categorized, prioritized, shared, and completed. Every task has a board where it should go — either an individual project or some non-specific board for things like internal initiatives.

notes/

This is the root directory where all the text files are. I keep it in Dropbox, but it could easily be any other cloud storage provider.

notes/inbox.txt

This is a text file where I quick-capture anything I think of that needs done or needs referenced. I use the iOS app Drafts to quick append to it with a timestamp and any text I want.

notes/todo.txt

This is my low-level, nitty gritty to do list. It is granular enough to remind me exactly what I need to do. I fill and empty this list every day.

notes/work/monthly-logs/

This is a directory of text files named for each month. Each one contains a daily log of what I did, and what I need to work on next.

notes/work/clients/

Here each client I work with has a directory, with a sub-directory for each project. This is where I keep meeting notes, reference notes, project estimates — anything that I need to keep around that doesn’t fit into a task-based setting.

Workflow

At the beginning of the day I check my inboxes — email, Slack, and the inbox.txt. I follow the GTD method here, checking which items are actionable, which items need done first, and which items only need kept as reference. If something is actionable and takes only a few minutes, I do it right away. Otherwise it ends up on a list in Trello.

Trello is where tasks flow from new to complete. I use a simple structure, cribbed from examples like this one from thoughtbot. Most new tasks created from inbox items go straight to the ‘Backlog’ list.

After inboxes are organized and processed, I pick the two to three most important things I need to do — either from the Next Up list on the Trello board or existing items from the Next list in my daily log — these go into my todo.txt. Then, I pick one of those things to do. Sometimes I pick based on urgency, sometimes by which seems more fun, and often by how much uninterrupted time I have available. Keeping my todo.txt lean is important here — picking an item here must be quick. Of course, some days priorities change. Because the system is lean, I can react to that — Trello cards get bumped to a lower priority list, I leave myself a few ‘what to do when I return to this’ notes, and update my todo.txt.

When I finish a task, I make a small note in the current month’s log file. The note is simple, with minor context — the adjacent notes provide extra context. I started this habit for a few reasons. One, I need to be able to account for my time. Git commit history is a good way to look at what code I wrote or how long a specific feature took, but sometimes I need to know what I did besides write code. Two, it serves as a great way to review previous days, weeks, and months. I often end a week by looking back through these notes, and occasionally look back to what I was doing 6 months or a year ago.

At the end of the day I write down some notes on what I started but didn’t finish, and some ideas for what I should do tomorrow. I put those notes directly under my completed task list in the monthly log. This is what primarily drives my to do list for the next day. I write as much context as I need for how to resume the task. When I take the note, I am most aware of the task — and those notes let me jump right back into it. I’ve learned that this is the greatest benefit to the system — I don’t waste time trying to recall my thoughts, I can even pick a task up several days later.

Here’s an example of what an entry in this log looks like:

// notes/monthly-logs/september.markdown

# Tue 2017-09-12
- Continued work on Top Secret Application
 - Finished custom fetching logic
 - Began drag and drop sorting feature
- Meeting with Top Secret Client for Top Secret Application design review

Next:
- Update sort order on back end based on API request
- Finish UI for drag and drop

This system is tailored to my needs, but I don’t think it is so obscure that it is useless for others. I have to give much credit to David Allen’s Getting Things Done – it’s the framework for how I think about projects and tasks, everything I do in this system is a modification or elaboration on what he already made. I tried plenty of apps and combinations of apps, and only landed on this after months of trial and error. It has worked out well for me; I have more awareness of what I need to do at any time, and I can get into ‘work mode’ quicker than I used to. If you’re struggling with that, give it a try.

Estimating Client Work, and my Unexpected Buffer Time

 

Note: I use the word ‘component’ a lot in this article. By that, I mean a vague term for a small chunk of UI and functionality. Some frameworks and libraries use Component as a class, I’m not referring to any of those specifically.

When doing work for clients, you have to provide an estimate. They need to get budgets ready, plan for release dates, have people ready to use the new site or application to give feedback and report early bugs. Estimating the work that goes into a software project is, by large, a matter of experience. Over time, a developer will build up an understanding of how to guess the effort a single component will take and what effort goes into connecting that component to other parts of the application.

Once you have a model, you can decompose it into components. You’ll need to discover the mathematical rules that describe how these components interact. Sometimes a component contributes a single value that is added into the result. Some components may supply multiplying factors, while others may be more complicated.

Andrew Hunt, Dave Thomas: The Pragmatic Programmer

To estimate a component, you need to be able to see all the parts. If you can’t see all the parts, the component is too big and needs broken down. For example: a client has a document sharing application and needs to add searching functionality. That can’t be estimated with any accuracy, so we need to break it apart. What does searching include? A search form, sure. How much time does it take to add a new page, or add a field to a persistent piece of UI (like a header)? That’s one part. How much time to create a route and controller for the search form to submit data? That’s another. On and on, until each piece is broken down into a manageable chunk. This makes it easier to grasp and guess ‘roughly how much time to build this?’

Sometimes, estimating a component’s effort means actually creating a roughed out version of what you need to build. Back to the search example, if you’ve never built a filter for a list of results before, it might be a good idea to try a quick example. Don’t solve every piece of it, that’s a waste of time. But if it takes you thirty minutes to scratch out a decent working example with some static data and an ugly UI, it’s possible that thing won’t take more than a few hours total. Otherwise, if thirty minutes barely scratches the surface go ahead and assume days, not hours.

One understanding that comes with experience is the general level of complexity that the component has — and based on that level of complexity, how much extra time needs factored in. When I build estimates, I call this my “unexpected buffer” time. Back to the search filter example again: The client is fine with a full page refresh whenever some new filters are added. Simple to build, not a lot of complexity. Now, let’s assume the filtering and sorting needs to be instant, but that entire search result needs to have a shareable URL. This is a level of complexity that can introduce unforeseen problems. We still give both components an estimate according to the effort — but each one also receives a buffer time. Low complexity, add 10% to the estimate. Maybe 20%. Highly complex, add 50%. I’ve gone so far as to double my estimates.

The buffer is the unsung hero of my estimating process. It keeps launches on time and saves everyone’s sanity. And, if you don’t use it — your client gets an early delivery, which I guarantee they will love.

Long Reading vs. Short Reading

I recently had a realization that, over the past few years, the time I spend reading has changed dramatically. I used to read a book every month, along with a good mix of blogs and news. Now my reading has strayed to Twitter and news, with some technical articles sprinkled in. The shift was gradual, and I hadn’t paid attention to it. I was busy with life and didn’t notice the change. That’s not to say I read less — rather, the style and length of things I read is different.

I went on vacation this July, and brought a book with the intention of reading only this book and leaving the other stuff behind. I was halfway successful in that I finished the book — but I could not keep myself away from Twitter and the news that followed. It gave me pause. I would even have the urge to check Twitter while I was reading my book! Why was it so difficult to take a break for a measly two weeks? It made me feel sad about how few books I read anymore. So, while I was otherwise enjoying vacation, I tried to answer a few questions. Why do I spend so much time reading short pieces, and why do I feel bad about that? What can I do to move back in the other direction? This is what I came up with.

Why short reading took over

The reason my reading patterns changed was not hard to figure out. The time I have free does not lend itself to long reading. I have two young kids, and I can’t glance at a book before they need me elsewhere. I could spend 30 minutes trying to get through a single page. Put that together with the other things I need to do and there isn’t a big gap of time where I could get deep into a book.

There are, however, plenty of short breaks where pulling my phone out to catch up on an article I saved is no problem. I can read a few hundred to a few thousand words on near anything — and if I need to put the article down for a few minutes, it’s simple to pick back up where I left off. And in the case that its a detailed article, backing up a paragraph or two is not going to take long.

Twitter is even easier. I have two minutes while waiting for water to boil? Check Twitter. There’s a meeting soon and nothing to do? Check Twitter. A commercial during a show on one of these streaming services that still has commercials? Check Twitter. Now, I can’t read anything long during those times. It would be a complete waste. But when it all adds up — I can’t help but consider how I could have used that time better.

What’s so bad about that?

On its own, nothing. I really do like Twitter. The people I follow give me insights into topics I otherwise wouldn’t have, and I’m convinced it helps me see the world with a wider perspective. Journalism, both reporting and opinion, is important too. I want to stay up to date on a lot of topics and I cherish how simple that is.

The problem lies when I do short reading to the exclusion of anything else. Let’s say I read 1200 tweets a day and 5 short-ish articles. That must be in the range of ten to twenty thousand words. If that was devoted to a book, I’d be through it in about a week.

It’s not completely equivalent. It ignores time constraints. It ignores context. One reason I find short reading less satisfying is that there is less context to understand. Reading a book, especially non-fiction, requires memory, supplemental reading, and re-reading. So it is more difficult to do an equal amount of long reading as short reading. But it also stays in your memory longer — especially if you take notes while reading. I forget most tweets minutes after I see them. Short articles, if I don’t bookmark them to save long-term, are usually out of my memory within days.

That’s why I am unsettled by the imbalance of my reading. Pursuing depth on a subject is equally important to me as a breadth across many.

Plan to change

I’m going to re-balance my reading time gradually over the next few months. I don’t want or need to cut anything out entirely, but I do need to change priorities. I unfollowed about a third of my Twitter follow list. I stopped trying to be a completionist — if my unread tweet count gets too high, I skip to the top. If something is important enough it will always come up again. I’m quicker to purge unread articles from my reading list, especially if they’re topical. I’m more selective with the ‘save for later’ buttons.

I admit these are small changes — but hope they will pay off long term. Next time I have twenty minutes to read, I won’t spend it catching up on news articles from last week. I don’t know if it will turn out this way — if not, I will need to make bigger changes to see the results I want.

Writing more

Writing is hard.

I would like to write more. I want to write to help process my thoughts. I want to improve how I communicate through writing. I am a private person, and I want to write to make myself more public.  These reasons are valid and good — but there is one big reason why they don’t matter.

Starting anything new creates expectations. If I start writing more I expect myself to keep it up. This expectation requires a commitment of time — if I expect myself to write more than literally once I have to carve out time in my day to do it. My days are not going to magically open up because I want them to. Of course this means I need to remove something else — maybe I stay up a little late, or get up earlier. Maybe I write at lunch rather than read. Maybe I stop looking at Twitter so much. No matter what it is, something has to change.

Thing is, not changing is so much easier than changing. So I’m going to come at this issue slowly. I’ll write this post and then be done for a bit. I won’t expect to write something every day, every week, or even every month. I’ll write when I need to write or when I feel like writing. Could be something personal or technical, something emotional or mundane. I’ve considered writing up my book notes, à la Derek Sivers. No matter what it is, I’m not going to expect much out of myself — only a little.