Question

I am trying to restructure a project to make components reusable and clearer.

Consider the following scenario:

A WakefulBroadcastReceiver (in my case called SimpleWakefulReceiver) will start my LocationService. Once a new GPS fix has been received, the client should transmit this to a server and the server response should be shown to the user.

Implementation attempt:

I have two other classes:

  • HttpManager
  • NotificationManager

The LocationService creates an anonymous reference and calls a method like this:

new HttpManager(this).sendGps(longitude, latitude, accuracy, utcTime);

The constructor of the HttpManager class

public HttpManager(Context context)
{
    this.context = context;
}

After receiving a response from the server, I do practically the same as above within the HttpManager class:

new NotificationManager(context).sendNotificationToUser(resultData);

The problem:

When the job is done, an error has occurred or other conditions, the WakeLockshould be released and the service should be stopped.

Therefor I often call the methods

  • context.stopService(new Intent(context, LocationService.class));
  • SimpleWakefulReceiver.completeWakefulIntent(new Intent(context, LocationService.class));

within the NotificationManager and the HttpManager class which seems like a code smell.

I'm looking for a structure where I don't have to call these methods often. I'm also not sure if it is very elegant with these anonymous references or maybe implementing a ResultReceiver or IntentService would be the better way.

Question

  • How can I structure the project to remove this code smell?
Was it helpful?

Solution

Your SimpleWakefulReceiver should not be making direct references to HttpManager. An HttpManager manages your communication with the server. It's purpose answers the question: "How do I communicate with the server?" You need another class to answer the question What do I communicate to the server?"

The Single Responsibility Principle states:

In object-oriented programming, the single responsibility principle states that every class should have responsibility over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated by the class. All its services should be narrowly aligned with that responsibility.

...

Martin defines a responsibility as a reason to change, and concludes that a class or module should have one, and only one, reason to change.

Try to restructure your classes with this behavior in mind. Do not be afraid to add more classes. Your classes should be small and nimble.

In your specific case, you can create a class that is responsible for wrapping the ability to send the GPS data to the server and processing it's response. Then you should only call these service startup and shutdown procedures in that one place. The rest of your code should not have to worry about these tasks, as those classes have other responsibilities.

Licensed under: CC-BY-SA with attribution
scroll top