1. Escape the callback hell with Future's
On Android you have to spin off a thread for everything that needs some time until it's finished. You can't do this on the main thread, because then you would block the responsiveness of your app. This work could be e.g. a call to a REST server to fetch or post some data.AsyncTask from the Android library helps Android Java developers with this problem. But it uses callbacks as soon as the task completes. This doesn't sound so bad if you only do one thing, but just think about dependent async calls: First fetch user data, then fetch the avatar whose link has been contained in the returned user data. Now you have to nest callback handlers which really leads to ugly code. If you're not convinced read "Callbacks are the modern gotos".
Fortunately functional languages like Scala have a very nice solution for this problem and they are called Monad's. In our concrete case of async execution the Monad to use is Future. You just have to return a Future of your return type instead of returning it directly. The nice thing is now that you can combine Future's very easily using a for comprehension:
With that mechanism you may combine several inter dependent async calls and they nearly look as simple as synchronous code.
2. Use concise functions instead of verbose anonymous listener classes
Android's UI code makes heavy use of the Listener concept like several other Java based UI frameworks like Swing. Every java developer knows the extreme amount of boilerplate code that is needed to write an anonymous listener class:(Yes I know, this is already Scala, but it still uses the standard android listener)
You may now simply define a function that wraps the ugly listener concept or simply use Scaloid which already supplies you with one:
If you prefer not to use Scaloid you just have to use the "Pimp my library" Pattern of Scala and enrich every Android View with a method that accepts an "on click" handler function:
Now you simply import the implicit class and you may use e.g. button.onClick() like shown above.
3. Concise Scala code vs verbose Java boilerplate
Java is still ultra verbose and you as a developer need powerful IDE's to generate hundreds of boring code lines like this:In Scala the above is simply done with:
Case classes generate everything for you: equals, hashCode, getter's, toString. No setter's since Scala case classes teach you to favour immutability. But Case class have clever copy methods if you need to create an altered version of an object.
4. Use compile time checked dependency injection with the cake pattern
You don't need Spring's Dependency Injection facilities or Guice with Scala. You'll have something more powerful without the need to use an external library. Just learn and use the Cake pattern and you are able to use Dependency injection in your Android code. And the best: It's statically checked by the compiler and not at runtime like in Spring or Guice.5. Get rid of if-cascades with Pattern matching
Checking conditions of an object in Java often leads to several if-cascades. And if you also want to extract some data out of the object you'll have to write a lot of code. Scala has it's swiss army knife for that: Pattern Matching. Here's an example:With pattern matching you have the possibility to decompose an object into it's parts.
Case classes already provide automatic support for pattern matching, but you may use pattern matching even for java classes or classes for which you don't have the source code by using Scala's extractor's.
Keine Kommentare:
Kommentar veröffentlichen