Problem
Imagine you're developing a fitness tracking application that gathers workout data from various fitness devices in XML format and generates detailed performance summaries for users.As you strive to enhance the app's capabilities, you contemplate integrating a sophisticated machine learning algorithm for personalised workout recommendations.
However, there's a snag: the algorithm exclusively processes data in JSON format. Adapting the algorithm to accommodate XML data might disrupt existing code that relies on its current functionality. Additionally, accessing and modifying the algorithm's source code might not be feasible, rendering this solution impractical.
Solution
To bridge the gap between the CSV data format used by fitness devices and the JSON format required by the advanced machine learning algorithm, you can implement an adapter. This adapter serves as a mediator, facilitating communication between the two objects with different interfaces.
The adapter encapsulates the conversion process, shielding the underlying complexity from both the fitness tracking application and the machine learning algorithm. For instance, you can design an adapter that transforms workout data from CSV format to JSON format seamlessly.
Adapters not only facilitate data conversion but also enable collaboration between objects with disparate interfaces. Here's how it operates within our scenario:
The adapter defines an interface that aligns with the requirements of either the fitness tracking application or the machine learning algorithm.
Utilising this interface, the fitness tracking application or the algorithm can interact with the adapter's methods securely.
Upon receiving a request, the adapter translates the data from CSV to JSON format (or vice versa) and forwards it to the respective recipient, ensuring compatibility.
In some cases, you can implement a two-way adapter capable of facilitating bidirectional data conversion, enabling seamless communication between the fitness tracking application and the machine learning algorithm.
Real Life Example :
When embarking on your first trip from the US to Europe, you might encounter an unexpected challenge when attempting to charge your laptop. The varying power plug and socket standards across countries can catch you off guard. This discrepancy means that your US plug won't fit into a German socket, for example. Thankfully, this issue can be resolved by employing a power plug adapter equipped with both an American-style socket and a European-style plug.
Object adapter
This implementation uses the object composition principle: the adapter implements the interface of one object and wraps the other one. It can be implemented in all popular programming languages.
// Target interface
interface EuropeanSocket {
fun plugIn(type: String)
}
// Adaptee (adapting the US socket)
class AmericanSocket {
fun plugIn(type: String) {
println("Plugged into American socket: $type")
}
}
// Adapter
class SocketAdapter(private val americanSocket: AmericanSocket) : EuropeanSocket {
override fun plugIn(type: String) {
println("Using adapter to plug into European socket")
americanSocket.plugIn(type)
}
}
// Client
class Laptop {
fun charge(europeanSocket: EuropeanSocket, type: String) {
europeanSocket.plugIn(type)
}
}
fun main() {
val americanSocket = AmericanSocket()
val socketAdapter = SocketAdapter(americanSocket)
val laptop = Laptop()
laptop.charge(socketAdapter, "Type C")
}
EuropeanSocket
is the target interface that defines the methodplugIn(type: String)
.AmericanSocket
is the adaptee, representing the existing American socket implementation.SocketAdapter
is the adapter class that implements theEuropeanSocket
interface. It contains a reference to theAmericanSocket
and delegates theplugIn
call to it.Laptop
is the client class that consumes theEuropeanSocket
interface. It has a methodcharge
which accepts an object that implementsEuropeanSocket
.In the
main
function, an instance ofAmericanSocket
is created, then an instance ofSocketAdapter
is created, passing theAmericanSocket
instance to it. Finally, theLaptop
charges using theSocketAdapter
, which internally uses theAmericanSocket
to plug into the European socket.