Adapter pattern is used to combine two pieces of functionality that don't work together right out of the box,
like trying to use data out of an old/new service that comes in an unusual format. Alternatively, an adapter
pattern can be used to create one way to interact with 2+ resources.
In this example, class JSONProcessor only uses data in JSON format. There is a requirement to
utilize data out of a service that returns data in CSV format (CSVProvider below). In order to
use data from CSVProvider in JSONProcessor, an adapter is required.
The following class, CSVProvider returns some data in CSV format.
class CSVProvider {
public getColumnHeaders(): string {
return "FirstName,LastName,Age";
}
public getData(): string {
const line1 = "John,Smith,25";
const line2 = "Mary,Smith,25";
const line3 = "Jacob,Smith,3";
const CRLF = "\n";
const interimResult = [line1, line2, line3];
const res = interimResult.join(CRLF);
return res;
}
}
The following class, JSONProcessor, needs to work with data that is provided by the CSVProvider,
but JSONProcessor can only work with JSON data. The formats are not quite compatible.
class JSONProcessor {
public doSomethingWithJSON(json: string): void {
console.log(JSON.stringify(json, null, 2));
}
public showJSON(json: string): void {
console.table(json);
}
}
"Adapter" is the middleware that takes CSV from CSVProvider, converts it to JSON and feeds it
to an instance of the JSONProcessor class. No need to alter neither CSVProvider nor JSONProcessor, Adapter
acts as a shim that makes the two data sources work.
class Adapter {
private csvProvider: CSVProvider;
constructor() {
this.csvProvider = new CSVProvider();
}
public ConvertCsvToJson(): string {
const incoming = this.csvProvider.getData().split("\n");
const columnHeaders = this.csvProvider.getColumnHeaders().split(",");
let arr = [] as any;
for (let i = 0; i < incoming.length; i++) {
let vals = incoming[i].split(",");
const person = new Object();
for (let j = 0; j < columnHeaders.length; j++) {
person[columnHeaders[j]] = vals[j];
}
arr.push(person);
}
return arr;
}
}
And this is one of the ways that it could be used:
const adapter1 = new Adapter();
const jp = new JSONProcessor();
jp.doSomethingWithJSON(adapter1.ConvertCsvToJson());
jp.showJSON(adapter1.ConvertCsvToJson());
//result
[
{
"FirstName": "John",
"LastName": "Smith",
"Age": "25"
},
{
"FirstName": "Mary",
"LastName": "Smith",
"Age": "25"
},
{
"FirstName": "Jacob",
"LastName": "Smith",
"Age": "3"
}
]
┌─────────┬───────────┬──────────┬──────┐
│ (index) │ FirstName │ LastName │ Age │
├─────────┼───────────┼──────────┼──────┤
│ 0 │ 'John' │ 'Smith' │ '25' │
│ 1 │ 'Mary' │ 'Smith' │ '25' │
│ 2 │ 'Jacob' │ 'Smith' │ '3' │
└─────────┴───────────┴──────────┴──────┘