Way back in my very first post I mentioned I would cover structuring http request calls. Not quite a year later and I’m finally getting around to writing the post. YaY!
Down to business I see 3 basic parts to the request call: making it asynchronous, requesting the payload, and parsing the payload into a useable format.
Everyone knows that design patterns (like MVC) are a part of object oriented programming, but OOP is more than just a collection of patterns. Design patterns are just common solutions to common problems. These patterns are built upon design principles and it’s the Open/Closed Principle that I keep in mind when structuring my network calls. This principle states that your classes should be open to extension but closed to modification.
But why is this important and what does that mean in a practical real world sense?
One of the concepts for building flexible software is to encapsulate areas that are likely to change. Remember, the only constant is change. Things will change. They will. They will! In a lot of the apps I make a high-risk area of change is the service calls. Imagine you’re working on an app for the popular dating website OkCupid. This app needs to browse user’s pictures, send messages to other users, and read your own message. For this data, you’re going to need to make service calls to a backend. So you begin writing the OkCupid class and it has methods like OkCupid.sendMessage(userId, message) and OkCupid.getMessage( messageId) and OkCupid.blockUser(userId). After some testing and adding nice graphics, you box up the application and ship it. Well done, sir! Because you did such a good job and your app is extremely popular, you now need to make an update. You need to add the ability to unblock a user. So what do you do? You open up the OkCupid class and add another method called OkCupid.unblockUser(userId). Do you see what just happened here? You just opened the class to modify its behavior. This OkCupid class is not open to extension nor is it closed to modification. This approach doesn’t adhere to the Open/Closed Principle.
What can we do about it?
First, let me say that the above hypothetical OkCupid approach is not necessarily bad. It’s perfectly reasonable to open a class and add a method if it’s needed, and if I were releasing a Twitter library I would consider using this approach for it’s simplicity. However, there are times when this isn’t the best way. I recently worked on a news aggregator app for a major media company. Going into the project it wasn’t possible to have access to all the APIs I would need or documentation, or even a clear picture of the entire app. Based upon the lack of scope, the one thing I did know was that I would have to build the app as flexible as possible to easily accommodate the changing needs of the client. The approach we’ll be discussing provides this kind of flexibility.
Here’s the overview of how I make network request calls. Typically
- The controller is responsible for sending the request call.
- I use a version of AsynTask to make the call asynchronous and apply the business logic.
- AsyncTask uses a command for making the actual request to the endpoint
- That command parses the server’s response into a useful data object.
- AsyncTask updates the model with the current data.
That’s the idea from a high level. It’s pretty simple and follows the Open/Closed Principle. If you were paying attention, you might have noticed I said the word “command.” Over the next 2 post, we’ll cover the Command Pattern using the Open/Closed Principle and explore a sample RSS reader app. Feel free to go ahead and check out the sources.
Sources: Get the sources here!