I have an Android
application that is using an EventBus
architecture with publishing and subscribing events. Usually this is from Controllers
(Activities
) to a "Manager" class that handles all the subscriptions.
Here is an example:
Controller Class
public abstract class EventBusActivity extends Activity {
protected Bus mBus;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBusFailureEventListener = createBusFailureListener();
mBus = getBus();
}
@Override
public void onPause() {
super.onPause();
mBus.unregister(this);
}
@Override
public void onResume() {
super.onResume();
mBus.register(this);
}
}
public class ActivityController extends EventBusActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_controller);
initViews();
sendEvent();
}
private void initViews() {
// Initialize views
}
private void sendEvent() {
mBus.post(new UpdateEvent());
}
@Subscribe
public void onOtherStuff(OtherStuff otherStuff) {
String someString = otherStuff.getOtherString();
Intent i = new Intent(this, SecondActivityController.class);
i.putString("some_string", someString);
startActivity(i);
}
}
Manager Class
private class Manager {
private Client sClient;
private Bus mBus;
private Context mContext;
private Manager(Context context, Bus bus) {
this.mContext = context;
this.mBus = bus;
this.sClient = Client.getInstance();
}
@Subscribe
public void onUpdateEvent(UpdateEvent updateEvent) {
Callback<ModelObject> callback = new Callback<>() {
@Override
public void onSuccess(ModelObject model, Response response) {
mBus.post(new OtherStuff(model.getString());
}
@Override
public void onFailure(Error error) {
// Handle error
}
};
sClient.updateEvent();
}
// Other Subscription methods....
// Example
@Subscribe
public void onLoadUserEvent(LoadUserEvent loadUserEvent) {
Callback<User> callback = new Callback<>() {
@Override
public void onSuccess(User user, Response response) {
mBus.post(new LoadedUserEvent(user));
}
@Override
public void onFailure(Error error) {
// Handle error
}
};
sClient.getUser();
}
}
Client Class
public class Client {
private static String API_URL = "http://api.com"
private static Client mClient;
private RestAdapter mAsyncRestAdapter;
private Client() {
mAsyncRestAdapter = RestAdapter.Builder()
.setEndpoint(API_URL)
.build();
}
public void updateEvent() {
IUpdate update = mAsyncRestAdapter.create(IUpdate.class);
update.updateEvent();
}
// Other implementation methods
// Example
public void getUser() {
IUser user = mAsyncRestAdapter.create(IUser.class);
user.getUser();
}
}
Event Classes
public class UpdateEvent {
// Empty class to just trigger event
}
public class OtherStuff {
private String mOtherString;
public OtherStuff(String otherString) {
this.mOtherString = otherString;
}
public String getOtherString() { return mOtherString; }
}
// Other Event Classes...
// Example
public class LoadUserEvent() {
// Empty class to just trigger event
}
public class LoadedUserEvent {
private User mUser;
public LoadedUserEvent(User user) {
this.mUser = user;
}
public User getUser() {
return mUser;
}
}
API Interfaces
public interface IUpdate {
@PUT("http://api.com/update")
void updateEvent(Callback<ModelObject> callback);
}
// Other API Interfaces...
// Example
public interface IUser {
@GET("http://api.com/getUser")
void getUser(Callback<User> callback);
}
So to just recap, my ActivityController classes post events to the Bus, since the Bus is handled in the Manager class all published events from Controllers end up there, the Client is then activated to return something from an API in a callback and then a new Event is posted back to the Controller. The event bus is name space specific, an Event only gets triggered if its name matches the parameter in the subscription method (you can see how this might create some issues).
I am trying to follow clean architecture in my application using this diagram:
Problem:
What's starting to occur is that my manager class is getting bloated with a lot of subscription events, and my Client class is also getting bloated with implementations.
How would I go about reducing bloat in these classes? I have a few thoughts:
- Implement a factory pattern on the events, but then how should I handle threading? For example some events share similar traits like loading a user but need to be subscribed to different subscription methods in the current application I've built. I would like to be reusing classes instead of creating event classes that duplicate code
- Create a
Service
class that handles these events dynamically? - Create a presentation layer between controller and manager?
A diagram showing what I mean by presentation layer:
- Implement
Promise
s?
Would appreciate any thoughts on how to best tackle this.