Шаблон проектирования Adapter


На главную
Содержание


E. Gamma, R. Helm, R. Johnson, J. Vlissides определяют назначение шаблона Adapter следующим образом: "Преобразование стандартного интерфейса класса в интерфейс, более подходящий для нужд клиента. Применение шаблона Adapter позволяет организовать совместную работу классов с несовместимыми интерфейсами".

Таким образом, если нас не устраивает интерфейс какого-либо объекта, мы можем создать для него новый интерфейс с помощью шаблона Adapter. При этом мы создаем для исходного класса оболочку, которая обладает нужным интерфейсом.

Поясним принцип применения шаблона на примере. Допустим существует класс TNewClass, определенный следующим образом:
class TNewClass {
//...
public:
bool write();
bool read();
};
Таким образом, интерфейс данного класса содержит функции для считывания и записи неких данных.
Предположим нам необходимо использовать класс TNewClass вместо устаревшего класса TOldClass, который выполнял схожие функции, но имел другой интерфейс (подразумевается, что у нас нет возможности вносить изменения в TNewClass, а создавать его заново требует больших затрат времени в силу его сложности).
Определение класса TOldClass:
class TOldClass {
//...
public:
bool WriteData();
bool ReadData();
};
Если бы мы просто заменили TOldClass на TNewClass, нам пришлось бы изменять весь код, который ранее взаимодействовал с классом TOldClass. Чтобы избежать этого, мы создадим оболочку для класса TNewClass:
class TNewClassWrapper {
TNewClass obj;
public:
bool WriteData() {
return obj.write();
}
bool ReadData() {
return obj.read();
}
};
Теперь мы можем использовать объекты класса TNewClassWrapper вместо объектов класса TOldClass, поскольку они имеют одинаковый интерфейс.

Часто шаблон Adapter используется для обеспечения полиморфного поведения объекта. Допустим наш класс TNewClass необходимо сделать производным от класса TBaseClass. В этом случае мы вынуждены создавать оболочку для TNewClass, чтобы иметь возможность заместить виртуальные функции базового класса.
class TBaseClass {
//...
public:
virtual bool WriteData() = 0;
virtual bool ReadData() = 0;
};
class TDerivedClass : public TBaseClass {
TNewClass obj;
public:
bool WriteData() {
return obj.write();
}
bool ReadData() {
return obj.read();
}
};
Если класс, интерфейс которого необходимо изменить, не обладает всей требуемой функциональностью (например, если в классе TNewClass отсутствует метод write()), то можно реализовать недостающие функции непосредственно в классе-оболочке.

Содержание
На главную


Rambler's Top100
Хостинг от uCoz