Типы сооружений для обработки осадков: Септиками называются сооружения, в которых одновременно происходят осветление сточной жидкости...
Папиллярные узоры пальцев рук - маркер спортивных способностей: дерматоглифические признаки формируются на 3-5 месяце беременности, не изменяются в течение жизни...
Топ:
Процедура выполнения команд. Рабочий цикл процессора: Функционирование процессора в основном состоит из повторяющихся рабочих циклов, каждый из которых соответствует...
Интересное:
Влияние предпринимательской среды на эффективное функционирование предприятия: Предпринимательская среда – это совокупность внешних и внутренних факторов, оказывающих влияние на функционирование фирмы...
Лечение прогрессирующих форм рака: Одним из наиболее важных достижений экспериментальной химиотерапии опухолей, начатой в 60-х и реализованной в 70-х годах, является...
Уполаживание и террасирование склонов: Если глубина оврага более 5 м необходимо устройство берм. Варианты использования оврагов для градостроительных целей...
Дисциплины:
2019-08-07 | 142 |
5.00
из
|
Заказать работу |
|
|
Адаптер, Adapter — структурный шаблон проектирования, предназначенный для организации использования функций объекта, недоступного для модификации, через специально созданный интерфейс.
Основные характеристики
Задача
Система поддерживает требуемые данные и поведение, но имеет неподходящий интерфейс. Чаще всего шаблон Адаптер применяется если необходимо создать класс, производный от вновь определяемого или уже существующего абстрактного класса.
Способ решения
Адаптер предусматривает создание класса-оболочки[1] с требуемым интерфейсом.
Участники
Класс Adapter приводит интерфейс класса Adaptee в соответствие с интерфейсом класса Target (наследником которого является Adapter). Это позволяет объекту Client использовать объект Adaptee так, словно он является экземпляром класса Target.
Следствия
Шаблон Адаптер позволяет включать уже существующие объекты в новые объектные структуры, независимо от различий в их интерфейсах.
Реализация
Включение уже существующего класса в другой класс. Интерфейс включающего класса приводится в соответствие с новыми требованиями, а вызовы его методов преобразуются в вызовы методов включённого класса.
Замечания и комментарии
Шаблон Адаптер позволяет в процессе проектирования не принимать во внимание возможные различия в интерфейсах уже существующих классов. Если есть класс, обладающий требуемыми методами и свойствами (по крайней мере, концептуально), то при необходимости всегда можно воспользоваться шаблоном Адаптер для приведения его интерфейса к нужному виду.
Близким Адаптеру является шаблон Фасад, не всегда можно отличить один от другого[2].
|
Применение шаблона
Типичным примером использования шаблона Адаптер можно назвать создание классов, приводящих к единому интерфейсу функции языка PHP обеспечивающие доступ к различным СУБД[3].
Вариант решения данной проблемы с использованием шаблона Адаптер показан на рисунке.
Пример использования шаблона Адаптер
Примеры реализации [показать]
Пример реализации шаблона на C#
using System;
namespace Adapter
{
class MainApp
{
static void Main()
{
// Create adapter and place a request
Target target = new Adapter();
target.Request();
// Wait for user
Console.Read();
}
}
// "Target"
class Target
{
public virtual void Request()
{
Console.WriteLine("Called Target Request()");
}
}
// "Adapter"
class Adapter: Target
{
private Adaptee adaptee = new Adaptee();
public override void Request()
{
// Possibly do some other work
// and then call SpecificRequest
adaptee.SpecificRequest();
}
}
// "Adaptee"
class Adaptee
{
public void SpecificRequest()
{
Console.WriteLine("Called SpecificRequest()");
}
}
}
Примечания
Мост (шаблон проектирования)
Bridge, Мост — шаблон проектирования, используемый в проектировании программного обеспечения чтобы «разделять абстракцию и реализацию так, чтобы они могли изменяться независимо». Шаблон bridge (от англ. — мост) использует инкапсуляцию, агрегирование и может использовать наследование для того, чтобы разделить ответственность между классами.
|
Цель
При частом изменении класса, преимущества объектно-ориентированного подхода становятся очень полезными, позволяя делать изменения в программе, обладая минимальными сведениями о реализации программы. Шаблон bridge является полезным там, где не только сам класс часто меняется, но и то, что класс делает.
Описание
Когда абстракция и реализация разделены, они могут изменяться независимо. Рассмотрим такую абстракцию как фигура. Существует множество типов фигур, каждая со своими свойствами и методами. Однако есть что-то, что объединяет все фигуры. Например, каждая фигура должна уметь рисовать себя, масштабироваться и т. п. В то же время рисование графики может отличаться в зависимости от типа ОС, или графической библиотеки. Фигуры должны иметь возможность рисовать себя в различных графических средах, но реализовывать в каждой фигуре все способы рисования или модифицировать фигуру каждый раз при изменении способа рисования непрактично. В этом случае помогает шаблон bridge, позволяя создавать новые классы, которые будут реализовывать рисование в различных графических средах. При использовании такого подхода очень легко можно добавлять как новые фигуры, так и способы их рисования.
Примеры
Пример на C#
using System;
namespace Bridge
{
// MainApp test application
class MainApp
{
static void Main()
{
Abstraction ab = new RefinedAbstraction();
// Set implementation and call
ab.Implementor = new ConcreteImplementorA();
ab.Operation();
// Change implemention and call
ab.Implementor = new ConcreteImplementorB();
ab.Operation();
// Wait for user
Console.Read();
}
}
/// <summary>
/// Abstraction - абстракция
/// </summary>
/// <remarks>
/// <li>
/// <lu>определяем интерфейс абстракции;</lu>
/// <lu>хранит ссылку на объект <see cref="Implementor"/></lu>
/// </li>
/// </remarks>
class Abstraction
{
protected Implementor implementor;
// Property
public Implementor Implementor
{
set{ implementor = value; }
}
public virtual void Operation()
{
implementor.Operation();
}
}
/// <summary>
/// Implementor - реализатор
/// </summary>
/// <remarks>
/// <li>
/// <lu>определяет интерфейс для классов реализации. Он не обязан точно
/// соотведствовать интерфейсу класса <see cref="Abstraction"/>. На самом деле оба
/// интерфейса могут быть совершенно различны. Обычно интерфейс класса
/// <see cref="Implementor"/> представляет только примитивные операции, а класс
|
/// <see cref="Abstraction"/> определяет операции более высокого уровня,
/// базирующиеся на этих примитивах;</lu>
/// </li>
/// </remarks>
abstract class Implementor
{
public abstract void Operation();
}
/// <summary>
/// RefinedAbstraction - уточненная абстракция
/// </summary>
/// <remarks>
/// <li>
/// <lu>расширяет интерфейс, определенный абстракцией <see cref="Abstraction"/></lu>
/// </li>
/// </remarks>
class RefinedAbstraction: Abstraction
{
public override void Operation()
{
implementor.Operation();
}
}
/// <summary>
/// ConcreteImplementor - конкретный реализатор
/// </summary>
/// <remarks>
/// <li>
/// <lu>содержит конкретную реализацию интерфейса <see cref="Implementor"/></lu>
/// </li>
/// </remarks>
class ConcreteImplementorA: Implementor
{
public override void Operation()
{
Console.WriteLine("ConcreteImplementorA Operation");
}
}
// "ConcreteImplementorB"
class ConcreteImplementorB: Implementor
{
public override void Operation()
{
Console.WriteLine("ConcreteImplementorB Operation");
}
}
}
Пример JavaScript
// Implementor ("интерфейс")
function Implementor() {
this.operation = function() {};
}
// ConcreteImplementor (реализация Implementor)
function ConcreteImplementorA() {
this.operation = function() {
alert("ConcreteImplementorA.operation");
};
}
ConcreteImplementorA.prototype = new Implementor();
ConcreteImplementorA.prototype.constructor = ConcreteImplementorA;
function ConcreteImplementorB() {
this.operation = function() {
alert("ConcreteImplementorB.operation");
};
}
ConcreteImplementorB.prototype = new Implementor();
ConcreteImplementorB.prototype.constructor = ConcreteImplementorB;
// Abstraction
function Abstraction() {
var implementor;
this.getImplementor = function() {
// доступ к implementor'у из RefinedAbstraction
return implementor;
};
this.setImplementor = function(val) {
implementor = val;
};
this.operation = function() {
implementor.operation();
};
}
// RefinedAbstraction
function RefinedAbstraction() {
var abstr = new Abstraction();
this.setImplementor = function(val) {
abstr.setImplementor(val);
};
this.operation = function() {
abstr.operation();
};
}
// использование:
var refAbstr = new RefinedAbstraction();
refAbstr.setImplementor(new ConcreteImplementorA());
refAbstr.operation(); // "ConcreteImplementorA.operation"
refAbstr.setImplementor(new ConcreteImplementorB());
refAbstr.operation(); // "ConcreteImplementorB.operation"
Без необходимости перегрузки методов Abstraction, можно значительно упростить RefinedAbstraction:
function RefinedAbstraction() {
Abstraction.call(this);
}
Так же можно сохранить ссылки на перегружаемые методы сразу после инстанцирования Abstraction:
|
function RefinedAbstraction() {
Abstraction.call(this);
var abstr_setImplementor = this.setImplementor;
this.setImplementor = function(val) {
abstr_setImplementor(val);
};
}
|
|
История создания датчика движения: Первый прибор для обнаружения движения был изобретен немецким физиком Генрихом Герцем...
Семя – орган полового размножения и расселения растений: наружи у семян имеется плотный покров – кожура...
Автоматическое растормаживание колес: Тормозные устройства колес предназначены для уменьшения длины пробега и улучшения маневрирования ВС при...
История развития пистолетов-пулеметов: Предпосылкой для возникновения пистолетов-пулеметов послужила давняя тенденция тяготения винтовок...
© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!