There are many ways to take a Feature and break it into workable unit of Tasks. Measuring “breakdown quality” is being ignored most of the time, as it’s very elusive to define “good breakdown”. The ability to break something into smaller pieces is one of the biggest signs of an experienced craftsman, so you should definitely challenge yourself by asking: am I known for predicting work effort well? detecting edge-cases early? Communicate progress to my boss clearly? being able to work with others on the same thing smoothly?
Introducing a Feature
Before we can play with breaking Feature into tasks, we need to have an example of a Feature in front of us. Let’s pretend that our desired Feature is “Signup and Sign-in” where to goal is to allow users to register and sign-in to the system. Next, here are the flows:
1. User can enter the signup page, if she’s not currently signed-in (else – redirect to homepage).
2. User can enter his details and signup.
3. User details will be validated, by [rules]. If failed – user will be asked to fix and re-send.
4. User will need to confirm her signup via email, before signing-in.
5. User can sign-in only after confirming her signup, if pending – show message.
6. User can sign-in in case she’s not signed-in already, using her credentials.
7. User can sign-out, only if she’s currently signed-in.
8. Page header needs to show relevant links, according to whether or not the user is currently signed-in.
9. If user fails to login multiple times (configurable), deny login for X minutes
[a few mockups here, a few technical/business notes there regarding URL structure, SEO to have in mind, analytics requirements, etc]
Breaking by Layers, the common way
A very common way is to break Feature by “application layers”:
1. Adjust database schema.
2. Create Data Access code to allow persistence of user (details, credentials encrypted etc) and retrieval of information.
3. Create Business Layer logic to validate credentials, confirm signup, perform sign-in.
4. Add signup and sign-in pages, alter header according to user state.
You can imagine that each task here will be a priced as 10-15 hours or even more, according to the implementer and the exact details. If the implementer founds an edge-case, it might mean that the every one of the layers here will be affected by it, making the estimation even less reliable.
Breaking by Verticals
A different approach will be using the flows above to form the tasks:
* create readConfiguration helper method
* create validateUserDetails method for server side
* create generateConfirmationNumber(userDetails) method
* create(/use) email sender provider
* create validateUserDetails for client-side
* create signup(userDetails) – schema to store user details, Data Access and Business to validate information and activate generateConfirmationNumber for sending confirmation email.
* create signup page (using validateUserDetails, signup method)
* create signin(credentials) method – schema to store number of login attempts, Data Access and Business to validate information, blocking user due to multiple attempts.
* create confirmUser method – Data Access and Bussiness to validate confirmation
* create signup confirmation page.
* create signin page
* create isLoggedIn method
* change header links according to status (via isLoggedIn)
* redirect user on entering signup page when currently signed-in (via isLoggedIn)
It’s not a 1:1 match between Task and flow, sometimes one flow will require multiple Tasks, but the flows drive the breakdown. No doubt, all of the tasks here are much smaller, each will take around 1-4 hours and very self-explanatory.
Why should you prefer Verticals breaking?
Confidence in achieving progress: if you strive for small tasks (up to 3-4 hours), it means that you’ll need to understand exactly what is needed to be done before committing to it. Every time you’ll finish a task, you’ll feel better that you’re moving on the right path. Because tasks are small, you will enjoy this feeling a few times during a day, which is important. You need to run away from “I wrote some code today, but I’m not sure if I’m on track”, poor planning will make you feel unproductive for long time.
Provide complete context to allow sharing workload: what happens if you need someone else to assist you? If you work by layers, it’s hard to understand “what is done”. The context is the entire Feature, which is too big to share easily. By working on vertical tasks, the context is much smaller as flows are smaller unit of execution. If you’re stuck, you can raise the flag and ask someone to assist you by taking a few vertical tasks and make them happen. They’ll have no trouble understanding what needs to be done.