EM Business Products Corp.
  • Services
  • Case studies
  • Blog
  • Connect with us
EM Business Products Corp.
  • Services
  • Case studies
  • Blog

07/31/2018

You are terrible at planning your software development tasks

#essentials
#tech-strategy
You are terrible at planning your software development tasks

A work breakdown structure is overlooked often...

You, 5 hours earlier...

I've been given a new feature to add -- can't wait to jump into the code!

Planning you say? Oh, no, it's fine, I've done this a thousand times, and I already have it mapped out in my head. Plus, I did look at the client's task description a couple days ago after all. It's so simple. It's time to get things done and impress my client about how fast I finished. I got this!

Unexpected suprises? No problem -- I'll just deal with them as they come along -- I'm a coding ninja after all. I can code with one eye shut, and half my left brain pointed at Youtube :) :)

You, 5 hours later...

All done, and with unit tests 🔥🔥

I must be like, in the top 3% of coders. Nobody has my work ethic. I'm just plain awesome, and I smell good 😎

My client is going to freak out when he sees how fast I finished!

Wait, before I do, I should just check the task description to make sure all is ready. Oh, wait, I missed a small edge case...

Here we go...

Wait, I totally missed this one sentence at the end. This task has 3 separate use cases, and I only programmed for one. And actually, some of what I wrote won't work for the other cases.

Wait, did I just do 3 hours of work for no reason? These 2 other use cases are really complex, what happens when the user does this? Wait, this is going to take 3 times longer than I thought. Actually, I'm not even sure how long, I don't have enough information to really know what I'm getting into. I need to ask someone about this, and this. How do I even begin to work through this? There's a lot of API calls going on here. I'm feeling...overwhelmed...

🤮🤮🤮

Cry me a river

Welp, you tried, and you failed miserably. Now you are left with a pathetic feeling of regret and disgust in yourself. Yes, cry, because you should have known better than to forget your training and rush off into the dark expanse of programming without a conquer strategy, grass-hoppa.

One Does Not Simply Program

Patience is worth its weight in gold

Let me start by saying I have lost count of the amount of times I've been in your situation. I read the task, and jump into the code all eagerly, foaming at the mouth, that is until my fantasy is suddenly interrupted by the inevitable effects of impatience. Impatience is costly. It will quickly eat away at your time as you undo and redo work, rethink and replan.

A little thought into exactly what you need to do and how, upfront, will go a very long way. With patience and planning, you will not only better understand what you need to do, but how the feature works as a whole, as well as how your work needs to be architected. Most importantly, you will complete nearly as fast, but with a much much higher quality of work right off the bat, and with less bugs and back-and-forth with the client.

Work Breakdown Structure FTW

I want to write about how to make use of a structure for breaking down your tasks, which will help you better understand them, organize your tasks in a logical order, bring up questions about the work, and keep yourself from becoming overwhelmed with way too much complexity.

So, is this way of planning a "thing"?

Yeah, it is. Out there, in the world outside, they call it a work breakdown structure. There's software out for this, but for the context I'm writing about (day to day software development tasks) it's probably overkill. I will be sharing how I do it, with a simple hierarchical list which you can write on paper or on your favorite note taking app.

Let's work with an example

Before I explain how I plan, let's first introduce a real-world example for a project I had. Let's take a look at what this example task requires from a product perspective, and how we can begin to understand and break this task down into easy chunks to work with. After that, we can think about how to plan for it.

The task

Program search filtering controls based on provided UI components, and have controls modify the search results on the page. Only items matching the filter controls should display to the end-user.

Controls include:

  • Filter by date range
  • Filter by document age
  • Filter by industry
  • Filter by author

Yeah I know, planning stinks

I know how you feel, planning is a chore. It feels like you are wasting time over-planning instead of actually getting any work done. The problem is, you think you know the task and your mind map tells you everything you need to know. But when you force yourself to look at each step closely and think about exactly how you should accomplish a task, you will begin to unravel problems in ways you had not yet thought about. These are little suprises that don't come till later and are waiting to make your day horrible.

The product description usually touches on how it should work as how a user interacts with it, and doesn't touch on all the moving parts behind the scenes. So now that you see this planning can be useful, the first thing you must do is stop, take a deep breath and clear your mind. You are going to dial back on your need to code up a storm, and take it slow.

Now, get up -- yes you. Go to the kitchen and make yourself a nice cup of tea or coffee. If you have one already, then good you can stop reading right now and move ahead on this post, you highly caffeinated dev you.

Notes and to-dos

So, let's talk about writing notes!

Channel your younger college self

Remember in college when we all cared a lot and took notes? Yeah, let's bring that back. This is the first component for tackling a task. Before we can fix or build we need to know how it works and why it works that way.

Now, it's important for me (for my own sanity) to make notes that are clear and concise. I also am aware that any notes I take are personal -- meaning, nobody else needs to understand them but me. It is my own personal plan for tackling a task.

I also know, that I can't trust myself in remembering what I wrote an hour ago let alone 3 days ago, so I can't assume I will remember what I was talking about in my notes. I have to write descriptively not only explaining the what, but also the where, how, and why. Clear and concise does not == short and vague. If short explanations don't always work, write long and make sure you have written in a way that reminds you of the context, and describes things in detail so you will remember what you wrote at a later time. This is key, and without it your notes could be too vague to do their purpose.

Get your to-do lists on

Once I dump my thoughts on paper or whatever note app I'm using, what I do is make a butt-ugly bullet point list, for to-do items I need to list out. You got a fancy to-do list you like to use? That's wonderful. I just want to write things down and not get bogged down by to-do list features and other nonesense.

I use bullet points to help in readability (I can read things easier like this), and if I want to do certain steps in order I use numbered lists to keep organized. As I complete an item I put an X at the beginning of the line. I told you, it's ugly. It's just fine for me. Use what you want to use :)

Step 1: Take notes of how things work now, before you make the changes

OK, let's go back to our example. Our little search filter task seems simple enough, but how does it all work right now? The very first step looks obvious, take the app for a test run.

From running our fictitious app, we can see that right now we have search results and there is no filtering functionality at all.

OK, now we know how it works -- wait, no we don't. We still have no clue how this works under the hood. How is the code architected to control filtering and display these search results?

These are notes that can be very useful, as many features out in the wild can be very complex. Sometimes you just understand them for like, an hour, and then you need to remind yourself again. Therefore, without any notes you will need to run the app again to get a handle of how it comes together. If you haven't experienced this in your work, trust me, you will eventually -- because some work is THAT complicated.

After digging into the code, and running through it, we have found some things. Here are the notes:

How it works now

  • The app is built in React, and uses Redux to store its state
  • The app uses Redux Saga for handling asynchronous operations
  • Page loads, apps immediately displays any previous search results that were persisted
  • User inputs search term, hits submit
  • Submit calls search Redux action
  • Action invokes Redux saga that makes the search API call
  • API call is made, providing search term
    • Example: http://www.thesearchapi.com?term=fashion
  • Search results are returned unordered and saved into the Redux store
    • The search results formatting is:
{
  "results": [
    {
      "name": "Latest Fashions",
      "body": "article body goes here",
      "date": 1532001248,
      "age": 2016,
      "industry": "fashion",
      "author": "Luke Duncan"
    }
  ]
}
  • The search results data does not provide the value options for filters
  • The data is stored as-is into the Redux store
  • Prior to rendering, the results data must be transformed by the search results component into something the results components can render
  • The results render unordered
  • The search results are persisted
  • There is no code implementation for filters at all
  • The app does not have any filter controls available to use

This is great. We learned a lot about the app by taking some time to see the flow of things. We learned how the app is architected to get and process the info, and we learned the data is persisted. That's an important point to know about the app because that tells us we may need to persist the filters selection. This exercise also allowed us to make a quick note on how the search results data looks like. This could be a good reference point in case we need to check against it while coding. We are starting to get a better picture of how things work, and we can now possibly form better questions to our client/team that we would have otherwise done before.

Step 2: Write down questions that need to be answered before proceeding

From the bit of code review we did, some questions come to mind. Here are my notes:

What to ask

  • How are the filter values populated? Is there a separate API to use?
  • What is the format for sending the filters to the search call?
  • Should the filter selections be persisted?
  • Do the results need sorting?
  • Is there a set of controls I should use?
  • Do the controls need particular styling? Do we have designs?

After talking to the back-end guys and project lead, I got some answers. Let's write the answers right under each question:

What to ask

  • How are the filter values populated? Is there a separate API to use?
    • Yes there is a separate API: http://www.thesearchapi.com/filters
    • Filters are returned in JSON format:
{
    "date": ["array", "of", "timestamps"]
    "document": ["array", "of", "titles"]
    "industry": ["array", "of industries"]
    "author": ["array", "of", "names"]
}
  • What is the format for sending the filters to the search call?
    • Example: http://www.thesearchapi.com?term=keywords&filters=filtername%3Afiltervalue%2Cfiltername%3Afiltervalue
  • Should the filter selections be persisted?
    • Yes, the app should remember the last filter selections between sessions
  • Do the results need sorting?
    • Results should be sorted by relevance first (result score), then title, alphabetically
  • Is there a set of controls I should use?
    • Yes UX has created a UI kit, with pre-made UI elements which include the controls
  • Do the controls need particular styling? Do we have designs?
    • Yes, UX provides a default styling in their UI kit, but must be modified for this project
    • Designs can be found at http://www.client.com/designs/search-designs

Sweet, the answers helped and now I can look at the designs. I see that each filter control is different, and each is populated differently. I'll just make a note of that to document to myself, under my styling question, since that sorta make sense to me:

  • Do the controls need particular styling? Do we have designs?
    • Yes, UX provides a default styling, but must be modified
    • Designs can be found at http://www.client.com/designs/search-designs
      • Date Range control uses a range slider, requires min,max,and value
      • Document Age control uses a histogram control, needs min, max, and selected range
      • Industry control uses a picker. It requires an array of possible industries
      • Author control uses a list of checkbox options. Requires an array of possible authors

This is perfect, I'm starting to form a plan in my mind about how to go about doing some of the work, but we have a lot of moving parts right now -- I need to organize my plan.

Step 3: Break large problems down into steps

So, there's a few things going on in our task. Let's continue creating this mental map on paper, err on screen in our case. I think we KNOW enough about what is going on, and what we need to do at a high level.

Let's get this high-level plan written down so we see where we stand by creating our actual work breakdown list, writing down what we know we must do so far. Here's the initial list:

Tasks

  • Lay out components into screen
  • Style components per designs
  • On page load, make a call to filters API
  • Populate controls with filter data
  • Send selected filters along with search request
  • Render search results
  • Persist filter selections
  • Modify page load logic to grab filter selections if they exist

Not bad for an overview of what needs to be done, overall tasks are separated which is nice. We can still dig deeper though. I want a more detailed plan.

Step 4: Break high-level tasks down further, into sub-tasks

We should think deeper, and break down each task by sub-tasks. Let's start from the 1st and 2nd task, since they are related, and work our way down.

Tasks

  • Lay out components into screen
    1. List controls vertically with default styling
      • 100% width into left page column
  • Style components per designs
    1. Style Date Range control
      • track color: #0062ff
      • thumb color: #bcd6ff
      • set mouse cursor to pointer
    2. Style Histogram (for document age)
      • bar color: #0062ff
      • range selection color: #fa00ff
    3. Style Picker control (for industry)
      • tag color: #0062ff
      • x button color: #0e142d
    4. Style Checkbox list (for authors)
      • checkbox color: #0062ff

This is very detailed. It seems so unnecessary

Well, it is detailed, but you are essentially writing down what you already are keeping track of in your mind anyway. This just gives you a more tangible map that you can refer to, add to, revisit later, and cross out tasks as you move forward. Because of this, it becomes really hard to forget your plan, your concerns about your plan, or to get confused as to what you should do next, because it is written in order from what you should do first to what you should do last. You are doing all that planning up-front, and don't need to think about it with as much effort again. It puts your thoughts on auto-pilot, kinda.

The goal is to note tasks at one or two levels deeper than the top-level tasks. The goal here is not to write every single tiny step you must do -- just what makes sense to you to write down, that is convenient to note, and that is something you might forget that you want to track.

Let's work with the rest of the tasks. We will use the info from our answered questions to get some of these broken down, and we'll write other important details too:

  • On page load, make a call to filters API
    1. Write Redux action unit tests
    2. Write filters saga unit tests
    3. Write filters reducer unit tests
    4. Create FILTERS_GET action type
    5. Create action creator for FILTERS_GET
    6. Create filters reducer
    7. Create getFilters saga
      • http://www.thesearchapi.com/filters
      • Handle error response
      • Store data as-is into filters reducer
  • Populate controls with filter data
    1. Write unit tests
    2. Populate date range
      • Transform data as needed
    3. Populate document age
      • Transform data as needed
    4. Populate industry picker
      • Transform data as needed
    5. Populate author checkbox list
      • Transform data as needed
  • Send selected filters along with search request
    1. Write Redux action unit tests
    2. Write Redux reducer unit tests for filter selections
    3. Create a FILTERS_SET action type
    4. Create action creator for FILTERS_SET
    5. Create reducer for filters selection
      • Add null/empty value check logic
    6. Wire up submit button
      • Create submit handler
      • Get filter selections from controls
      • Dispatch filtersSet action
    7. Modify search saga to select the selectedFilters reducer data
    8. Transform selection data to the appropriate API format
      • Example: http://www.thesearchapi.com?term=keywords&filters=filtername%3Afiltervalue%2Cfiltername%3Afiltervalue
    9. Handle error response
  • Render search results
    1. Get filtered results data from search results
    2. Sort data by score and title alphabetically
    3. Feed to search results components
  • Persist filter selections
    • Modify Redux persist to include filterSelections reducer
  • Modify page load logic to grab filter selections if they exist
    • Check if reducer has selections stored, if so set selections to controls

We have a decent list of tasks laid out.

Before moving forward, take a minute to compare the list we have created, and what we had to go by in the original task description. It's a huge difference!

We can now finally start working?

Mark step as complete and move forward

As we start to complete items. Simple add an X at the beginning like I do, or just cross them out:

  • Lay out components into screen
    1. X List controls vertically with default styling
      • ~~100% width into left page column~~

If new bugs are found after you have completed something, simply make not of it as an extra step:

  • Lay out components into screen
    1. X List controls vertically with default styling
      • ~~100% width into left page column~~
      • Bug: 100% width affected the width of the right widget column

If questions pop up at this stage, I like to make a note of the question, as a sub item of the task:

  • Lay out components into screen
    1. X List controls vertically with default styling
      • ~~100% width into left page column~~
      • Bug: 100% width affected the width of the right widget column
        • Question: Does the widget column need to share the width class?

Once your question is answered, you can convert it to a sub-task, or write the answer under it. I do both of these, depending on what makes most sense:

  • Lay out components into screen
    1. X List controls vertically with default styling
      • ~~100% width into left page column~~
      • Bug: 100% width affected the width of the right widget column
        • Split classes that affect the width of both columns

Once the bug is squashed, just X it or strike it through:

  • Lay out components into screen
    1. X List controls vertically with default styling
      • ~~100% width into left page column~~
      • X Bug: 100% width affected the width of the right widget column
        • X Split classes that affect the width of both columns

Conclusion

That about does it for this post. I hope it is useful to you in your daily work as it is to me. I would not work any other way now ?

Like this article? Cool! You may like these:

CONNECT WITH US

Full Name

Email address

Message

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.