Chapter 4 - The next iteration
Let’s summarize what we have so far. We have some issues, a basic MVP of a project and a statement that estimation done right can solve our problems with time, complexity and budget. Now we will expand on the project to see how.
Our client is happy that two days after the initial meeting we showed them something. Now they see their visions clearer. Remember, while you are talking over a paper, you don’t have the same view with the clients. You need to have visuals, wireframes but better a working prototype they can click through. The user experience will guide everyone to a better solution. And by the time we finish the requirement analysis, you will have a working application at our hands that requires only some polishing.
This is what Agile and Lean have in common to my understanding.
So, the client is happy, and they want to move forward at the same pace. They want us to extend the tasks with the fields: details, created, modified. The other requirement they want in the next demo is the introduction of projects that will encapsulate tasks. They also want a better look for the status change as it looks a bit messy right now and we agree to that.
The next demo is in another two days. Can we make it?
Of course. We have the best team in the world with “top 5%” developers willing to do whatever it takes. Does it have to take that much? It depends on the strategy the team’s technical lead will choose. Because, just like for any problem, there is an endless number of possible paths, and the lead will have to pick wisely.
All three requirements demand changes to the existing tasks codebase. This can easily turn up as a never-ending code merge issue. And we still don’t have a large code to take care of.
Let’s see a strategy I would do.
The first requirement is about introducing 3 new fields. It’s tempting to do as one go but beware as the complexity of the problem will become higher that way. What do we need to do to add only one field?
On the frontend side add the field to the
component with the form
component template with the form
component validation logic
component template with the list
On the backend side add the field to the
class containing the model properties
API where you insert the task
API where you list the task
API where you update the task
When looking at the update line, we realize, that we need a way to load the data back into a form, to be able to update it. As a simplification skip the update. We will do it in the next iteration, and we’ll be able to introduce the update for summary as well.
One might ask, what’s the purpose? I could have spent this time better by starting with the code right away. I’m not sure I’ve lost that 5 minutes I’ve invested in this list. Let’s take another step and estimate each item in the list:
What we can see from this table is if we wish to add a new field to the tasks and it requires us to touch every single layer, it will take a bit more than an hour. The field “details” is one great example of this. But not all will behave the same. The created and modified timestamp fields have nothing to do with the form on the UI. And they work differently on the backend side.
Going forward with our estimation let’s create another table for each field:
What does this table tell us? Having any random new field requirement, we have a way to control the requirement analysis by answering a few simple questions like: “Do I want this field to be present on the create-form?” or “Do I need to save this field to the database?”. While this latter might seem a bit odd, remember that most user registration or password change forms contain two password fields to validate the hidden value, while we store only one in the database.
Still, why did we spend 10-15 minutes compiling these tables? Because we can reuse them from now on. The work required to add a new field to the tasks is always the same and can be represented as above. Whenever the analyst comes back with a new requirement, we don’t need to rely on our memory regarding how much work is required, we have a blueprint and as so, we can delegate the work to anyone in the team. Also, it’s a tool for business to estimate how much time is required for this kind of work, without having to ask the team every time. Nice, huh?
And what if I tell you that we already had these tables? We created them when we were working on the summary and status field, we just haven’t presented it. And the estimates are a compilation of experience not just based on gut feeling.
Now move on to the next requirement. Introduce a new concept “project” and categorize tasks based on project id. After a short discussion with the analyst, we agree that the project has the same properties as the task. These are summary, details, created, modified, status.
“Hey”, someone shouts, “Why don’t we just add a parent field to the task and reuse it? Tasks with no parent will be handled as projects.”
“While I see your point”, the technical lead goes, “Tasks and Projects are semantically not the same concepts. Though I admit they are similar, but not the same. And I know the next question would tackle with refactoring common pieces into an abstract parent class. We don’t need it right now. First, because we are working on a prototype collecting as much information as possible while making the prototype useful. Second, we’ve seen many times how our codebase turns into a hell of a class hierarchy.”
Having said that, let’s investigate what’s required for introducing the concept of projects.
Create a component for collecting project data
Create the component files
Add FormGroup to the component class
Add FormControl to the FormGroup
Implement the template
Add generic layout as card
Add form tags to the card
Add field to the form
Modify styles, so that our form looks nice
Wait for a moment! Haven’t we seen this before? Maybe the developers were right? We can hear both DRY, KISS and YAGNI ringing their bells.
KISS says, keep it simple and stupid. That means just copy-paste over the task code and replace the references of task with project.
When we hear the word “copy-paste” is when DRY starts shouting out loud. If you create a similar structure it means we will have to maintain the same bugs in two places. It increases the maintenance overhead significantly.
That is when YAGNI calms you down. We are working on a proof of concept for the client. It doesn’t need to be perfect; it just needs to showcase that the ideas coming from them work or not as software. With the experience, we gained we can tell that the only thing different from the tables above is preparing the empty project skeleton files. After we have them, we can calculate the time required by including the summary and status fields as an extra. Or we can just simply copy them over.
We’re still duplicating but we are in a pioneering phase of the project. We don’t have a maintenance problem, as the developers will continuously revisit the code, and remove any duplication in a later phase when creating the product.
So, we have 2x3 hours so far, plus 1 hour to prepare the skeleton. The last task we have is to reorganize the UI for the status update. We remember that a basic Kanban board can be more suitable for this purpose, so we do a quick search and acknowledge that Material Angular has a complete demo of this problem in the drag and drop section. So, it should not take more than an hour to implement and it requires only UI changes.
That’s 8 hours total. For one person.
It can be done for the next meeting and we will have enough time to test it a bit. After the short meeting, one of the developers wants to talk with us for a short moment. He says he has an idea of how we could be even faster. He asks for two days to work on something and promises, it’s going to worth it.
We can hardly wait to see.