foens
foens

Reputation: 8672

Difficulties implementing Model-View-Presenter in Android

Model-View-Presenter (MVP) is a well known design pattern for GUI applications. For Android, implementing the business logic in a plain Java module facilitates testing without requiring an Android emulator.

However, I am having difficulties implementing the pattern on Android because of special requirements to the GUI of Android applications:

I have read the blog post MVP for Android and looked at the example source code. The end goal I am trying to achieve by using the MVP pattern is to be able to translate all business logic to Objective-C using the transpiler j2objc, such that the business logic can be reused while implementing the same app on iOS.

Is there anyone that have implemented the MVP pattern for Android successfully, and in that case, what am I missing?

Upvotes: 8

Views: 3018

Answers (2)

olerass
olerass

Reputation: 420

I find that the MVP variant Android is built around is a step in the right direction for isolating the business logic in a app. However, if you want to achieve a better separation of concerns, and as a result more reusable domain/business logic, I recommend using the Presenter First pattern (which you briefly mention yourself in the comment). Aside from decreasing coupling it lends itself well to TDD and allows you to unit test all your business logic.

I recently started a GitHub repo with Presenter First examples for Android. Due to the complexity of the Android architecture it's not straightforward to implement the pattern The views tend to be "fatter" than what seems to be acceptable in a normal Presenter First app, mostly because of the activity lifecycle and other oddities as you mention yourself. I've done my best to decouple the business logic from the platform but there's definitely room for improvement. You can find the examples at:

http://github.com/olerass/presenter-first-android

Maybe you can use some ideas from there? Or even better contribute some of your own.

Upvotes: 1

tball
tball

Reputation: 2044

I suggest implementing the MVP component without involving Activity, perhaps conceptually thinking about what would be useful on both Android and GWT. Create the component using test-driven-development with a mocked View interface, adding tests until the business logic is fully implemented and verified. TDD helps keep the component's API lean (why write tests for stuff you don't need?), which makes porting the component easier.

The Activity requirements you describe can be generalized to be platform-independent: the component should be serializable (small 's', not specifically Java serialization), and needs to accept lifecycle state events. Those, too, can be fully tested using mocks for system features. As you go through this step, you'll likely notice that few of the Activity requirements are necessarily Android-specific, and may be useful on other platforms. Avoid creating huge service APIs; to support serialization, for example, all that's needed are store/load methods, not something like the Parcel API. I've found describing such service APIs to another developer on a whiteboard to be a great way to find unnecessary fluff.

Next, port the component to Android, perhaps by creating an Activity that delegates to the component and provides Android-specific implementation classes for the mocked interfaces. It should all "just work" the first time, but in reality, some requirements may have been missed, so add them to the platform-independent part and repeat.

When you're ready to port to iOS, reimplement those previously mocked interfaces. If these interfaces are lean, it will probably be easier to create them directly in Objective-C, importing the protocol headers generated by j2objc. For example, j2objc's NSDictionaryMap class implements java.util.Map with an NSDictionary implementation -- no need to write and translate a Java version since its just using iOS APIs.

Upvotes: 4

Related Questions