Adapter jest strukturalnym wzorcem projektowym, czasem można go spotkać pod nazwą wrapper. Zrozumienie w jaki sposób działa oraz poznanie sytuacji w jakich można go użyć potrafi rozwiązać niejeden problem programistyczny.
Wyobraźmy sobie, że pracujemy w projekcie w którym używamy stworzonego przez nasz zespół loggera.
public class CustomLogger : ILogger { public void Log(string info) { Console.WriteLine(info); } }
public interface ILogger { void Log(string info); }
public class HalaZCzesciami { private ILogger _logger; public HalaZCzesciami(ILogger logger) { _logger = logger; } public Kierownica StworzKierownice() { var kierownica = new Kierownica(); _logger.Log("Stworzono Kierownice"); return kierownica; } ... }
var logger = new CustomLogger(); var hala = new HalaZCzesciami(logger); var kierownica = hala.StworzKierownice();
Logger nie jest specjalnie skomplikowany – wszystko wyświetla na konsoli.
W trakcie trwania projektu przychodzi decyzja, że wszystkie logi maja być zapisywane w pliku, a nie wyświetlane na konsoli. Dodatkowo ma być użyta w celu zapisania logów zewnętrzna biblioteka.
Aby zapisać logi do pliku przy pomocy zewnętrznej biblioteki musimy napisać następujący kawałek kodu:
public Kierownica StworzKierownice() { var kierownica = new Kierownica(); var extLogger = new ExternalLogger(); extLogger.LogInfo("Stworzono Kierownice"); return kierownica; }
Możemy również użyć zaimplementować to też w inny sposób:
public class HalaZCzesciami { private ExternalLogger _logger; public HalaZCzesciami(ExternalLogger logger) { _logger = logger; } public Kierownica StworzKierownice() { var kierownica = new Kierownica(); _logger.LogInfo("Stworzono Kierownice"); return kierownica; } }
Na potrzeby tego przykładu nie jest trudne zamienić te pojedyncze linijki. Jednak w przypadku dużego projektu tego rodzaju zmiana może zając bardzo dużo czasu i z całą pewnością o czymś się zapomoni i będą błędy.
Sposób bezpieczny – Adapter
Problem który próbujemy rozwiązać to dostosować istniejący interfejs do API zewnętrznej biblioteki. Adapter daje nam możliwość zaadaptować nowy interfejs z starym interfejsem. Wzorzec adapter radzi, aby stworzyć klasę, która będzie implementować interfejs naszego starego loggera i wykona operacje na zewnętrznej bibliotece.
public class LoggerAdapter : ILogger { private ExternalLogger _extLogger; public LoggerAdapter() { _extLogger = new ExternalLogger(); } public void Log(string info) { _extLogger.LogInfo(info); } }
var logger = new LoggerAdapter(); var hala = new HalaZCzesciami(logger); var kierownica = hala.StworzKierownice();
Jak adapter wygląda w UMLu?
Przydatne linki – Adapter
Przykład kiedy używać wzorca adapter. Polecam!
Film na yt z tłumaczeniem jak działa adapter.