15 Work Together to Practice, Step by Step Guide You in Breaking Down Tasks

15 Practicing Together: Breaking Down Tasks Step by Step #

Hello, I’m Zheng Ye.

Earlier, when discussing TDD, we mentioned that task breakdown is crucial for TDD. However, this is still a subjective understanding. Today, let’s use a more concrete example to show you the extent to which task breakdown can be done.

The example is the simplest user login. The requirement is simple: users log in with a username and password.

I believe that implementing this functionality is not difficult for everyone. I suspect that many people have already started writing code in their minds when I mentioned this topic. Today, the main purpose is to guide you through the process of task breakdown, to see how to break down a requirement into specific and executable tasks.

To complete this requirement, the most basic task is for users to log in by entering their username and password.

The task of logging in with a username and password is simple, but as we discussed in the first part, by simulating the process, we can easily see that this is not a complete requirement.

Where do the username and password come from? They could be set by the user or by the system administrator. Let’s simpify it and assume that they are set by the user. In addition, when a user logs in, there is usually a logout function as well. Alright, this is a simple and complete requirement. We will not further extend the requirements.

So, the list of requirements we need to complete looks like this:

- Let’s assume that we are the programmers who received this list of requirements and are going to develop it. First, we need to analyze what needs to be done, which is task breakdown. Here, you can take a break and try to break down the tasks yourself, and then compare it with the task breakdown I provide later to see how much difference there is.

Okay, let’s continue.

First, let’s decide on the technical solution and use the simplest method to create a table in the database to store user information. Once we involve a database table, it will involve database migration. Therefore, we have the following tasks.

- At this point, we need to determine if you know how to do these two tasks. Designing the table is something that people familiar with SQL generally know how to do. As for database migration, it may involve technology selection. Different database migration tools have slightly different syntax, so we will add it to the task list as something that is not yet clearly defined.

- With the database content ready, it’s time to prepare for writing the code. We will use a common REST service to provide external access. Here, we will use the conventional three-tier architecture, so we generally need to write the following:

  • Domain objects, which here means the user.
  • Data access layer, called DAO (Data Access Object) in some projects inherited from the J2EE era, called mapper following Mybatis. I now prefer to use the term “repository” from domain-driven design.
  • Service layer, which provides external application services and completes business processing.
  • Resource layer, which provides API interfaces, including validity checks for external requests.

Based on this structure, we can further break down our development tasks.

I don’t know if you have noticed, but the tasks listed on my task list are arranged in the order of implementing a complete requirement.

For example, the first part is a complete user registration process: first, write the User class, then the save method of UserRepository, then the register method of UserService, and finally the register method of UserResource. After this requirement is developed, we move on to login and logout.

Many people may prefer to write one class at a time, but I have to say that it is better to follow the process of implementing one requirement after another, so that tasks can be paused at any time.

For example, even with only half the time, I can deliver a complete registration process, while using the class-by-class approach would result in no completed requirements at all. These are just two different ways of arranging tasks, and I prefer to follow the order of requirements.

Let’s continue discussing task breakdown. At this point, we need to see which of these tasks are not easy to implement. Registering is just a process of storing an object in the database, so no problem there, but what about login and logout?

Considering that we are developing a REST service, which may be deployed on multiple machines, and any machine receiving a request should provide the same service, we need to share login information.

Here, we will use the most common solution: sharing data with Redis. If a login is successful, we need to store the user’s session information in Redis, and if a logout occurs, we need to remove the session information. Since session does not appear in our task list, we need to introduce the concept of a session. The tasks are adjusted as follows.

If we use Redis, we also need to decide on the method of storing objects in Redis. We can use native Java serialization, but in general development, we tend to choose a text-based method that is easier to maintain. Here, we choose the commonly used JSON, so two tasks are added.

At this point, the basic login and logout functionality has been implemented. But we need to ask a question: is this enough? Usually, the purpose of logging in is to restrict