Singleton Architecture Troubles

I understand that the app uses Singleton pattern. I also understand that it is a controversial pattern. Some people like it and some people don’t. I like the discussion justifying the use of Singleton at the end of the chapter for the more curious. I’m not totally sold but I’m going to try to go with the flow and use Singleton.

What if the app has a SQLite database containing all the crimes. The crime list view can pull the crimes from the database and possibly allow a bunch of sorting and filtering options for the user to fiddle with in the UI. The user’s sorting and filtering choices are state of the crime list fragment and applying them to the list of all crimes might be a time-consuming process. When the user taps on a crime in the list and switches to the pager view in chapter 11, the pager view’s list of crimes needs to match the list shown in the crimes list. The crime list fragment can pass the list of the user’s sorting and filters choices to the pager view as bundle arguments. Then the pager view can get the full list of crimes from the Singleton (getting them from the database) as shown on page 220 and then apply the sorting and filter options to the full list of crimes. This seems quite wasteful and will result in a slow user experience because applying the sorting and filtering options is time-consuming. I suppose that the crime list view could make its sorted and filtered list of crimes available in some global store and then the pager view could pull it out but that is getting well into the bad kind of singleton.

What to do in this situation?

Also, I was taught to avoid the Singleton for the unit testing reason mentioned on page 180. It says “Android developers usually solve this problem using a tool called a dependency injector.” I would have loved to see a code snippet right there that would show how to inject a dependency into an activity and/or fragment. Not using a library like Dagger. Just show how the injection would happen.

Thanks.

One option is to have the singleton accept sorting and filtering options as parameters. That way, you can keep the data modifying code in one place and potentially optimize it at that level. For example, if you’re using a SQLite database, it should be faster to sort and filter with a database query rather than doing it all after you have the results. The Singleton could potentially cache things if performance becomes more of a problem. In any app that I’ve worked on, this kind of approach has been completely reasonable from a performance perspective.

This scales well to data on a web server too. You pass in the query params to the singleton and the server performs the sorting and filtering. The singleton can just cache the result of that call. When you move to the next screen in the app, you’ll get a cached result back.