мост

Введение

Шаблон моста представляет собой шаблон создания, используемый для отрыва абстракции от его реализации.Мост использует инкапсуляцию, агрегацию и может использовать наследование для разделения обязанностей на разные классы.

Цель

  • Отделите абстракцию от ее реализации, которая позволяет независимо варьироваться.
  • Публиковать интерфейс в иерархии наследования и сверять реализацию в своей собственной иерархии наследования.

Схема проектирования

Объекты, участвующие в этом шаблоне, представлены на следующей диаграмме:

  • Abstractionопределяет интерфейс абстракции и поддерживает ссылку на объект типаImplementor
  • RefinedAbstractionрасширяет интерфейс, определяемый
  • Abstraction Implementorопределяет интерфейс для объектов реализации
  • ConcreteImplementorреализуетImplementorинтерфейс и определяет его конкретную реализацию

Реализация

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

Для этого мы должны отделитьCircleструктуру от ее реализации:

// Circle represents a circle shape
type Circle struct {
    // DrawingContext for this circle
    DrawingContext Drawer
    // Center of the circle
    Center Point
    // Radius of the circle
    Radius float64
}

// Draw draws a circle
func (circle *Circle) Draw() error {
    rect := Rect{
        Location: Point{
            X: circle.Center.X - circle.Radius,
            Y: circle.Center.Y - circle.Radius,
        },
        Size: Size{
            Width:  2 * circle.Radius,
            Height: 2 * circle.Radius,
        },
    }

    return circle.DrawingContext.DrawEllipseInRect(rect)
}

DrawerОпределяет контракт междуCircleабстракцией и ее реализацией:

// Drawer draws on the underlying graphics device
type Drawer interface {
    // DrawEllipseInRect draws an ellipse in rectanlge
    DrawEllipseInRect(Rect) error
}

Для каждой поддерживаемой технологии рендеринга мы должны реализовать структуру, которая подчиняетсяDrawerинтерфейсу:

Это пример реализацииOpenGLящика:

// OpenGL drawer
type OpenGL struct{}

// DrawEllipseInRect draws an ellipse in rectangle
func (gl *OpenGL) DrawEllipseInRect(r Rect) error {
    fmt.Printf("OpenGL is drawing ellipse in rect %v", r)
    return nil
}

Это пример реализацииDirect2Dящика:

// Direct2D drawer
type Direct2D struct{}

// DrawEllipseInRect draws an ellipse in rectangle
func (d2d *Direct2D) DrawEllipseInRect(r Rect) error {
    fmt.Printf("Direct2D is drawing ellipse in rect %v", r)
    return nil
}

Затем мы можем легко отобразить круг, используя желаемую систему рисования.Мы должны просто изменить реализацию, установивDrawingContextполе:

openGL := &uikit.OpenGL{}
direct2D := &uikit.Direct2D{}

circle := &uikit.Circle{
    Center: uikit.Point{X: 100, Y: 100},
    Radius: 50,
}

circle.DrawingContext = openGL
circle.Draw()

circle.DrawingContext = direct2D
circle.Draw()

Выводы

Шаблон моста разработан заранее, чтобы абстракция и реализация менялись независимо.Это позволяет нам самостоятельно изменять реализацию из ее абстракции.

results matching ""

    No results matching ""