Building mobility services is one of our main areas of expertise at Jimmy Technologies. Together with our clients, we pioneer brand-new solutions that aim to provide flexible, cheaper, and comfortable on-demand transportation while reducing the traffic in the city and the suburbs. How to build a viable demand-responsive transport system? Discover our takeaways, lessons learned, and insights we gained while creating the DRT platform for our client.
How to choose a language and why we went for Flutter
Two mobile applications are the essential parts of the product in our case study. One serves passengers, the other is for drivers. Our client wanted to target iOS and Android users, so we had to choose a technology that would serve both groups flawlessly. We love using a multiplatform solution when the delivery doesn't require a different approach to each operating system. This was the case, and so we decided to pick Flutter. Why? Flutter is our number-one choice for multiplatform mobile development because you can build iOS and Android versions from one codebase. Also, the performance is unmatched, it's more mature and allows you to implement native features if necessary. All these features matter for DRT systems where you need to respond to real-time events, process location data, render maps, and potentially use navigation.
Does Flutter have any drawbacks? The support from service providers could be better. We encountered issues while implementing maps from MapBox, a common solution in mobility software. We tried unofficial libraries but ultimately chose an alternative rendering engine based on Leaflet that fetched data from MapBox.
One domain that still lies ahead of us is navigation. Navigation is complicated, and you need to test a few proofs of concepts to verify that the technology fits your needs. It might even work in one country but not the other. Therefore, try it in the streets where the service will operate.
The drawbacks of Flutter are more pressing if you have a small team. For our experienced squad that follows proper practices and carefully designs the architecture, it works great.
Reduce complexity by sharing the codebase
Managing the complexity is crucial in any project because you never have unlimited resources. In our DRT case study, we anticipated that the passengers' and drivers' apps would have much in common – a similar design system and logic. Therefore we decided to deploy one shared codebase for both of them, which helped us remarkably reduce the complexity.
Flutter offers you the so-called flavours. With them, it's relatively straightforward to tweak the building process as you need. Nevertheless, agile software development is all about flexibility, so keep in mind that even though you have a shared codebase at one point, it doesn't mean you can't split it in the future if things change.
Have a strategy for thorough testing
Automated testing is the most straightforward practice to provide feedback on your work and reduce the probability of an error. At Jimmy, we don't end with that. We use test-driven development that makes testing an integral part of the delivery, not something you do as a post-development activity.
This approach pays off greatly when building DRT systems. You have multiple stages of interaction where anything can go wrong, but it shouldn't because that ruins user satisfaction. Firstly, users request a ride, then you allocate a vehicle, confirm, pick up passengers, and drop them off. Additionally, you need to handle cancelations and payments. There is no excuse not to have things automatically tested to ensure that the customer gets his ride when he rushes to work.
We spend most of our time behind the desks – coding, researching, or designing but hitting the streets and testing the solution in real life is also an essential part of the development process. Only then you find out how unreliable location tracking can be. What looks great in mock-ups can be a nightmare when you try it in unfavorable surroundings, on a cheap and old device with an outdated OS. So test, test, test!
Be sure that third parties will work
Mobility services are heavily dependent on third parties. For example, you might want to use an external allocation algorithm that will empower your fleet. That's completely fine but make sure you test it in advance. Otherwise, it can blow up your whole product.
One common opinion is you should not test third parties as it's their responsibility. I partially agree, but remember that you are responsible for the final delivery. You won't explain to your client that some integration you chose doesn't work. The good news is that you usually use just a tiny fraction of the external services relevant to your problem, which makes testing faster.
Testing third parties manually or semi-automatically in advance helps you to gain confidence that they solve what you need. It's crucial for informed development decisions before the integration. Discovering any drawbacks at the beginning is always cheaper than finding out later.
Know your domain and language
Domain-driven design is gaining a lot of attention, and while we didn't fully implement it during the DRT system development, one concept was indispensable. Which one? Ubiquitous and precise language. Naming things as close to the real world as possible will make the development more transparent and the code more accessible.
Let the passengers, drivers, cars, rides, and others be the actual entities in your codebase. Keeping the terminology aligned with the business will ensure smoother development. Always consult the domain expert if you need clarification.
Forgetting about the ubiquitous language means losing focus. That comes at a price because you need to fix it later to keep the software under control. Such takeaways reminded us of this practice as well as the importance of having the English dictionary within the development toolbox.
Automate what you can
When you work on software in a team, and there are more applications, think about automating as many repetitive tasks as possible. The DRT platform has apps for passengers and drivers, both for iOS and Android. Then there is a server-side application and a dashboard where you can see what's happening. Building, testing, and releasing multiple parts of the ecosystem can get repetitive and tedious, bringing errors. How to avoid it? Automate!
Many steps in the development lifecycle can be automated and reapplied to different environments. It also makes it easier for the stakeholders to give you feedback more often, accelerating the whole process.
Learn and improve continuously
Jimmy's team has already built and launched a few mobility services, but there is always room for improvement. Analyzing what went smoothly and what didn't is essential to reshape the best practices. I hope our insights will help you navigate tricky parts of the DRT development.
Reach out to get more information.