Adapter
Introduktion
Adapter är ett strukturmönster som låter objekt med inkompatibla gränssnitt samarbeta — som en reseadapter som låter en svensk kontakt fungera i ett amerikanskt eluttag.
Problem
Du bygger en app för börsanalys som laddar ner marknadsdata i XML-format och visar diagram för användaren.
Vid ett tillfälle vill du integrera ett kraftfullt analysbibliotek från tredje part. Men det finns en hake: biblioteket fungerar bara med data i JSON-format.
Du kan inte ändra biblioteket — det är låst kod. Att skriva om din app för att använda JSON istället för XML skulle kräva enorma ändringar. Du behöver en adapter.
Lösning
En Adapter konverterar gränssnittet för ett objekt så att ett annat objekt kan förstå det. Adaptern lindar in Service-objektet och hanterar konverteringen bakom kulisserna.
När ska Adapter användas?
- När du vill använda en befintlig klass men dess gränssnitt inte matchar resten av din kod.
- När du integrerar med tredjepartskod eller äldre system (legacy code) som du inte kan ändra.
- När du vill återanvända befintliga klasser utan att modifiera dem.
Struktur
| Roll | Ansvar |
|---|---|
| Klient | Arbetar med objekt via klientgränssnittet. |
| Klientgränssnitt | Beskriver protokollet som andra klasser måste följa. |
| Service | Den användbara klassen med inkompatibelt gränssnitt. |
| Adapter | Implementerar klientgränssnittet och lindar in Service-objektet. |
Exempel — XML till JSON (PHP)
Scenariot: Din app producerar data i XML. Analysbiblioteket kräver JSON. Adaptern konverterar formatet transparent.
<?php
// ── Klientgränssnitt (din app förstår XML) ────────────────
interface XmlDataSource
{
public function fetchXml(): string;
}
// ── Befintlig klass som producerar XML ────────────────────
class MarketDataService implements XmlDataSource
{
public function fetchXml(): string
{
return '<stock><symbol>AAPL</symbol><price>189.50</price><volume>52000000</volume></stock>';
}
}
// ── Tredjepartsbibliotek som kräver JSON ──────────────────
class AnalyticsLibrary
{
public function analyze(string $json): void
{
echo "Analyserar JSON-data: $json\n";
// Komplex analyslogik som bara förstår JSON...
}
}
// ── Adapter: konverterar XML → JSON ───────────────────────
class XmlToJsonAdapter
{
private AnalyticsLibrary $analytics;
public function __construct(private XmlDataSource $xmlSource)
{
$this->analytics = new AnalyticsLibrary();
}
public function analyzeData(): void
{
$xml = $this->xmlSource->fetchXml();
$json = $this->convertXmlToJson($xml);
$this->analytics->analyze($json);
}
private function convertXmlToJson(string $xml): string
{
$data = simplexml_load_string($xml);
$array = [
'symbol' => (string) $data->symbol,
'price' => (float) $data->price,
'volume' => (int) $data->volume,
];
$json = json_encode($array);
echo "XML in: $xml\n";
echo "JSON ut: $json\n";
return $json;
}
}
// ── Klientkod ─────────────────────────────────────────────
$marketData = new MarketDataService();
$adapter = new XmlToJsonAdapter($marketData);
// Klienten använder adaptern — vet inte om konverteringen
$adapter->analyzeData();
Output:
XML in: <stock><symbol>AAPL</symbol><price>189.50</price><volume>52000000</volume></stock>
JSON ut: {"symbol":"AAPL","price":189.5,"volume":52000000}
Analyserar JSON-data: {"symbol":"AAPL","price":189.5,"volume":52000000}
Fördelar
- Single Responsibility Principle — Konverteringslogiken är isolerad i adaptern.
- Open/Closed Principle — Nya adaptrar kan läggas till utan att ändra klientkoden.
- PHP:s inbyggda
simplexml_load_stringochjson_encodegör konverteringen elegant.
Nackdelar
- Kodkomplexiteten ökar — du lägger till nya klasser.
- Ibland är det enklare att bara skriva om Service-klassen om du har tillgång till den.
Av Victor Hernandez från Bytebase.se