Композитные шаблоны проектирования
Введение
Композитный шаблон дизайна представляет собой структурный шаблон, который использует для использования композиции при реализации интерфейса, а не с использованием множественного наследования.Он объединяет объекты в древовидные структуры и позволяет клиентам индивидуально обрабатывать отдельные объекты и композиции.
Бывают ситуации, когда клиенты игнорируют разницу между композициями объектов и отдельными объектами.Если обращение с несколькими объектами так же, как дескриптор каждого из них, идентичен, шаблон Composite Design является хорошим выбором для уменьшения сложности и обработки их как однородных.
Цель
- Целью этого шаблона является создание объектов в древовидных структурах для представления иерархии целого целого.
- Composite позволяет клиентам обрабатывать отдельные объекты и композиции объектов равномерно.
Схема проектирования
Композитный шаблон предоставляет следующие единицы: Компонент, Лист и Композит.
Component
является интерфейсом для всех компонентов, включая составные. Он объявляет интерфейс для объектов в композицииLeaf
представляет собой листовые объекты в композиции, реализует всеComponent
методыComposite
представляет собой композицию, вComponent
которой есть дети. Обычно реализует все методы и методы Componenet для управления детьми.
Реализация
Компонентный шаблон проектирования - очень распространенный подход для реализации иерархии объектной модели документа.Такой пример - графические редакторы, которые формируют разные формы и слои в иерархии.
Позволяет реализовать базовую архитектуру такого редактора.Позволяет использовать следующий интерфейс:
// VisualElement that is drawn on the screen
type VisualElement
interface {
// Draw draws the visual element
Draw(drawer *Drawer) error
}
Редактор поддерживает две формы (круг и квадрат).Каждая из структур, представляющих соответствующую форму, подчиняетсяVisualElement
интерфейсу, реализуяDraw
функцию, которая имеет точно такую же опознаваемость, которая отображается в интерфейсе.Следующий фрагмент кода иллюстрирует реализацию компонентов:
// Square represents a square
type Square
struct
{
// Location of the square
Location Point
// Side size
Side float64
}
// Draw draws a square
func (square *Square) Draw(drawer *Drawer) error {
return drawer.DrawRect(Rect{
Location: square.Location,
Size: Size{
Height: square.Side,
Width: square.Side,
},
})
}
// Circle represents a circle shape
type Circle
struct
{
// Center of the circle
Center Point
// Radius of the circle
Radius float64
}
// Draw draws a circle
func (circle *Circle) Draw(drawer *Drawer) 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 drawer.DrawEllipseInRect(rect)
}
Чтобы создать композицию и нарисовать несколько фигур на экране,Layer
создайте объект.Он содержит массивVisualElement
.Он несет ответственность за взаимодействие над элементами и привлечение каждого из них.Поскольку вы можете видеть, что фактическая структура используетVisualElement
интерфейс в качестве контракта для поддержки разных форм независимо от их типа.
// Layer contains composition of visual elements
type Layer
struct {
// Elements of visual elements
Elements []VisualElement
}
// Draw draws a layer
func (layer *Layer) Draw(drawer *Drawer) error {
for
_, element := range layer.Elements
{
if
err := element.Draw(drawer); err != nil
{ return err}
fmt.Println()
}
return nil
}
Объект может быть составлен, как показано в следующем фрагменте кода:
circle := &photoshop.Circle{
Center: photoshop.Point{X: 100, Y: 100},
Radius: 50,
}
square := &photoshop.Square{
Location: photoshop.Point{X: 50, Y: 50},
Side: 20,
}
layer := &photoshop.Layer{
Elements: []photoshop.VisualElement{
circle,
square,
},
}
layer.Draw(&photoshop.Drawer{})
Выводы
Работа с Tree-структурированными данными делает код более сложным и, следовательно, подвержен ошибкам.Композитные шаблоны проектирования обеспечивают решение, позволяющее равномерно обрабатывать сложные и примитивные объекты.Операции, которые вы можете выполнять на всех составных объектах, часто имеют наименее распространенные отношения, которые позволяют обрабатывать набор объектов как единое целое.