
//Adaptee
class StringList {
constructor() {
this.rows = [];
}
//SpecificRequest()
getString() {
return this.rows.join("\n");
}
add(value) {
this.rows.push(value);
}
}
//Adapter
class TextAdapter extends StringList {
constructor() {
super();
}
//Request()
getText() {
return this.getString();
}
}
function getTextAdapter() {
let adapter = new TextAdapter();
adapter.add("line 1");
adapter.add("line 2");
return adapter;
}
//Client
let adapter = getTextAdapter();
let text = adapter.getText();
//text: line 1
// line 2
console.log(text);
Преобразует интерфейс класса в другой интерфейс, ожидаемый клиентами. Обеспечивает совместную работу классов, которая была бы невозможна без данного паттерна из-за несовместимости интерфейсов.Read moreЗадача. Программа читает текст из любого источника через один метод. Готовый библиотечный класс хранит строки текста и умеет их склеивать, но метод у него называется иначе. Библиотеку изменить нельзя. Переписывать весь код, который вызывает ожидаемый метод, тоже не хочется. Идея. Адаптер подгоняет существующий класс под интерфейс, которого ждёт клиент. Такой класс называют адаптируемым, а нужный клиенту интерфейс - целевым. В этом варианте адаптер наследует адаптируемый класс и вдобавок реализует целевой интерфейс. Его целевой метод просто вызывает унаследованный, иногда с небольшим преобразованием. Поэтому адаптер сам по себе - адаптируемый класс со всеми его методами. Для сравнения: адаптер через композицию хранит адаптируемый объект, а не наследует его класс. Как читать пример. Адаптируемый класс уже делает нужную работу, но метод у него называется иначе. Целевой интерфейс объявляет метод, которого ждёт клиент. Адаптер наследует адаптируемый класс и добавляет целевой метод, который вызывает унаследованный. Объект здесь один: адаптер и есть адаптируемый объект. В большинстве языков клиент наполняет его собственными методами адаптируемого класса, а результат читает через целевой метод. Языки без наследования классов его имитируют: встраивают адаптируемый объект или добавляют целевой метод прямо в тип адаптируемого. Когда применять. Адаптер класса нужен, когда подгоняется один известный класс и заодно нужны его остальные методы. Он не годится, если подгоняемый объект уже существует или может оказаться подклассом адаптируемого. Адаптер класса - это всегда новый объект одного жёстко заданного класса, поэтому такие объекты он подогнать не может. Частая ошибка. Забыть, что адаптер открывает наружу все методы адаптируемого класса. Клиенты начинают вызывать их напрямую, и целевой интерфейс больше не скрывает адаптируемый. |