Шаблон проектирования Adapter используется для преобразования интерфейса класса (Target) в другой интерфейс (Adaptee), ожидаемый клиентами. Адаптер позволяет несовместимым классам работать вместе, что иначе было бы невозможно из-за их несовместимых интерфейсов.
Шаблон адаптера может быть реализован двумя способами: с помощью наследования (классовая версия шаблона адаптера) и с помощью композиции (объектная версия шаблона адаптера).
Мой вопрос касается версии шаблона адаптера класса, которая реализована с использованием наследования.
Вот пример редактора чертежей:
interface Shape
{
Rectangle BoundingBox();
Manipulator CreateManipulator();
}
class TextView
{
public TextView() { }
public Point GetOrigin() { }
public int GetWidth() { }
public int GetHeight() { }
}
interface Shape
{
Rectangle BoundingBox();
Manipulator CreateManipulator();
}
class TextView
{
public TextView() { }
public Point GetOrigin() { }
public int GetWidth() { }
public int GetHeight() { }
}
Мы хотели бы повторно использовать класс TextView для реализации TextShape, но интерфейсы разные, и поэтому объекты TextView и Shape нельзя использовать взаимозаменяемо.
Следует ли изменить класс TextView, чтобы он соответствовал интерфейсу формы? Возможно нет.
TextShape может адаптировать интерфейс TextView к интерфейсу формы одним из двух способов:
- Наследуя интерфейс Shape и реализацию TextView (классовая версия шаблона адаптера)
- Создавая экземпляр TextView внутри объекта TextShape и реализуя интерфейс TextShape с помощью экземпляра TextView (объектная версия шаблона адаптера).
Адаптер класса
interface Shape
{
Rectangle BoundingBox();
Manipulator CreateManipulator();
}
class TextView
{
public TextView() { }
public Point GetOrigin() { }
public int GetWidth() { }
public int GetHeight() { }
}
class TextShape : TextView, Shape
{
public Rectangle BoundingBox()
{
Rectangle rectangle;
int x, y;
Point p = GetOrigin();
x = GetWidth();
y = GetHeight();
//...
return rectangle;
}
#region Shape Members
public Rectangle Shape.BoundingBox()
{
return new TextBoundingBox();
}
public Manipulator Shape.CreateManipulator()
{
return new TextManipulator();
}
#endregion
}
Теперь вопрос :-). Является ли TextShape наследуемым от Shape и особенно от TextView действительным отношением «является»? А если нет, то не нарушает ли это принцип подстановки Лисков?