The Adapter Design Pattern in Scala using implicits

Comparing to the standard implementations of Adapter Pattern by GoF — Scala have a better, shorter, and fancier way to implement it. In this post I’m going to explain and guide how to implement and use the Adapter design pattern in Scala (using implicits).

Let’s start with a short reminder — the adapter pattern is a pattern to convert the interface of a class into another interface clients expect. Many people saying that design patterns are missing features of the language — so we’ll see how Scala making it easier for us.

Scala Code Samples — Adapter Design Pattern

gist of Scala and Java code samples presented here — link to gist

General sample (Adaptor/Adaptee)

Assume we have some existing code -

And we want to use the Client with the newly written non compatible “Adaptee” class

What we need to do is to write the “adapter”. In scala, all needed is to have the implicit conversion in the scope -

Now, we’re ready to go. Just use the Client directly with the adaptee and the Scala compiler will automatically call the adapter method (adaptee2Adaptor) to do the correct conversion.

An important note — the underline at the “adaptee” is IntelliJ’s way to show us that an implicit conversion took place here. This is very important when reading Scala code.

A concrete sample (AirConditioner)

Now, let’s do the same with a real world example. We have an AirConditioner class which have setTemperature method that gets Celsius as the parameter, we’ll create an adapter for Fahrenheit.

Advantages/Disadvantages

+ Easier (&shorter) usage — reduce boilerplate code and noise + Independance of client/adaptee/adapter. The only connection is that the implicit method should be in scope. + Scala compiler will automatically decide which Adapter should be used. If more than one in scope a compilation error will occur and the developer will have to do the conversion explicitly.

+ Extensibility — We can use the client with different adoptees (set AirConditioner temperature using different temperature measuring methods)

- auto complete cluttering with all possible conversions (or confusion if same method name exists in different conversions)
- Adds an implicit level of indirection which adds to the complexity, therefore might be harder to understand (Modern IDE(i.e. IntelliJ) will help to minimize it with underlining these conversions. To see the conversion [Mac: control + Q])

Explicit implicit

The danger zone — Implicit conversion is a very powerful tool which should be used with care. Especially dangerous when using on common types like Int, List, Tupel, Option etc … So another way to have easy conversion without the danger zone is using explicit implicit, using Scala feature called implicit class. Again, the implicit class must be in scope and in addition we need to call the toCelsius method.

An example from Scala library

Scala provides both ways to convert from Java collections to Scala collections and vice versa. The developer can choose which way he prefers by choosing which namespace to import ( JavaConversions -A collection of implicit conversions supporting interoperability between Scala and Java collections. & JavaConverters — A collection of decorators that allow converting between Scala and Java collections using asScala and asJava methods.). More about the differances from stackoverflow.com - http://stackoverflow.com/questions/8301947/what-is-the-difference-between-javaconverters-and-javaconversions-in-scala

The silver bullet — Type-class pattern

This pattern is a bit more complex but it gives you all the benefits of implicit conversions without the danger and ugly parts of using implicit conversion.

val asCelsius = converter.convert(degrees)

airConditioner.setTemperature(new Fahrenheit(75))

airConditioner.setTemperature(new Celsius(23))

We’re using our Celsius AirConditioner and we only need implicit definition of converter in scope.

* Note:
def setTemperature[T: ToCelsius](degrees: T): Unit unfolds to -> def setTemperature[T](degrees: T)(implicit ev: ToCelsius[T]): Unit

Additional readings

Wikipedia — Adapter pattern — https://en.wikipedia.org/wiki/Adapter_pattern
Scala documentation — Implicits — http://docs.scala-lang.org/tutorials/FAQ/finding-implicits.html
Programming in Scala, First Edition — Implicit conversions — http://www.artima.com/pins1ed/implicit-conversions-and-parameters.html

Originally published at https://maxondev.com on December 20, 2014.

Full of enthusiasm for technology - Software developer - Traveling/snowboarding/hiking/running

Full of enthusiasm for technology - Software developer - Traveling/snowboarding/hiking/running