In the previous article, I introduced the software design questions and gave some scattered examples of the various questions. In this article, I will present a fictional business and try to apply the questions on it as a practical example.
Before I begin, I would like to thank Atheer Alfawaz for her suggestion of the business idea and for workshopping this post with me.
Our business is going to be a gig economy-based vehicle services platform. We will expand on the details in the next section.
The Business Context
Here, we will answer the following four questions: What do we do? Who are we serving? What is our goal? How are we trying to reach it?
What do we do? We connect service providers to customers.
Who are we serving? For our first iteration of the products, we will only provide non-urgent car services (e.g., car wash, oil change, etc.). So, the assumption is that our customers are going to be med-to-high-income car owners, and they will book beforehand.
What is our goal? To be an all-in-one vehicle services platform.
How are we trying to reach it? Our first iteration will focus on providing non-urgent car services like car wash and changing engine oil. We will have two types of services: at-home and in-store.
Design Cycle
Before I start proposing designs, I want to explain our procedure to doing that. I call this procedure: the sketch, mock, evaluate, enhance, and iterate cycle.
In this sketching step, we will write down our current conception of the system – we will specifically focus on the data model. Then, the mocking steps involve testing our design against assumed business use cases (including near-future ones). Then, we evaluate if this design is good enough or lacking. Also, this is where we evaluate the complexity of our design. If it is lacking or too complex, we will proceed to the enhancement step. Here, we may add to our design, remove something from our design, or even start from scratch. And we start over.
First iteration
Our main entities are going to be Provider, Customer, Service, and Request.
Sketch
So, my first iteration of the data model would be as follows:
-
Service:
- Name
- Category
- Description
- Price? <– Keep this one in mind
-
Provider:
- Name
- Description
- Services (from the Service entity)
- type: in-store/at-home
- Price?
-
Customer:
- Name
- Phone number
- Location
-
Request:
- Service
- Provider
Now, we have a question that we need to ask ourselves. Should the price be set per service or per provider per service? And this is where we go back to discussing with the product managers to make our first tradeoff. Are we letting providers set their own prices, or are we setting one price for each service? If we were to let the providers set their own prices, what would we do when we get to on-demand services (remember, our first iteration is non-urgent services)? We ask that because our vision is to become an all-in-one vehicle services platform, so we need to ensure that we do not shoot ourselves in the foot. This is a tradeoff between flexibility and consistency.
Also, from a business perspective: if providers got used to being able to set their own prices, would later enforcing a fixed price be perceived positively?
Let's say we decided to let them set their prices, and this marks our first baking assumption. Our design would be like so:
-
Service:
- Name
- Category
- Description
-
Provider:
- Name
- Description
- Services (from the Service entity)
- type: in-store/at-home
- Price
-
Customer:
- Name
- Phone number
- Location
-
Request:
- Service
- Provider
Mock
We have the following business questions inferred from the assumed UI and flow:
- What are the available providers of a certain service at home?
- Who are the busy providers?
Evaluate
Now, does this design answer our mock questions? For the first one, we can filter the list of services at-home and list the providers. That could work, but "available" means that they are not busy at the moment. Meaning, we need to tell if they are busy and remove them from the available list. Our current design does not support that. And that is also the same issue we will face with the second question.
Enhance
To fix our issue, we need to add two things a booking time and a status. Status can be: initiated, in progress, completed, or canceled. So the Request would look something like this:
Request:
- Service
- Provider
- Status
- Booking Time
But if we read a little bit into the future. We realize that we can tell who is busy but not how long they would be. So, we need to also add an "average" booking duration in each service.
Second Iteration
After the three enhancements added in our last iteration, our new sketch would look as follows:
Sketch
-
Service:
- Name
- Category
- Description
-
Provider:
- Name
- Description
- Services (from the Service entity)
- type: in-store/at-home
- Price
- Duration
-
Customer:
- Name
- Phone number
- Location
-
Request:
- Service
- Provider
- Status
- Booking Time
Mock
We will keep our previous two questions, and we will add the following:
- When will a certain provider be free?
- What are all the requests of customer x?
Evaluate
For our original two questions, we now can tell who's available based on booking times and their service type. Likewise, we can use the booking times to see who's currently busy. For the two new cases, the first question is easy. We can, again, use the booking time and add it to our average service duration. As for our last question, this is something that seems like we overlooked. Our Request
entity does not have a customer :)
Enhance
This time we will simply link our requests to their customers by adding a customer to the Request, like so:
Request:
- Service
- Provider
- Customer
- Status
- Booking Time
Final Design
-
Service:
- Name
- Category
- Description
-
Provider:
- Name
- Description
- Services (from the Service entity)
- type: in-store/at-home
- Price
- Duration
-
Customer:
- Name
- Phone number
- Location
-
Request:
- Service
- Provider
- Customer
- Status
- Booking Time
Note that it is "final" in the sense that we would build this, but it does not mean we will not change it. New cases may come up that would make us go back to the drawing board and start over with this design.
Some Pointers
- Try to keep your designs as small as possible (that usually corresponds to being simple), and add to them as needed. Removing is generally more challenging than adding.
- Stay away from database jargon – that is not what we are designing for at this step. Notice that I have not mentioned anything about databases. Yet, this design can mostly map nicely to your database schema.
Exercise Questions
I will add more mock questions to challenge the design and leave it to you to improve the design based on these questions.
- Can a provider serve multiple customers simultaneously (e.g., car wash stations)? How can we limit the number of customers?
- What are the working hours of a provider?
- What is the coverage of at-home services (i.e., what areas are served by a provider)?