Юсянь: партнер по контенту CSDN, новый звездный наставник CSDN, полноценный творческий звездный создатель, 51CTO (ведущая знаменитость + эксперт-блогер), энтузиаст открытого исходного кода github (вторичная разработка исходного кода с нуля, серверная архитектура игры https: https:/ /github.com/Пикчен)
Подробное объяснение принципа шаблона наблюдателя:
Шаблон наблюдателя (шаблон наблюдателя) — это шаблон поведенческого проектирования, который определяет отношение зависимости «один-ко-многим», позволяя нескольким объектам-наблюдателям контролировать объект-субъект одновременно, когда субъект происходит объект. При изменении все объекты-наблюдатели уведомляются об обновлении соответствующим образом.
Основная идея паттерна наблюдателя — отделить объект-наблюдатель от объекта-субъекта, чтобы зависимости между ними стали слабыми. Объект-субъект отвечает за управление операциями регистрации, отмены регистрации и уведомления объектов-наблюдателей, а объекты-наблюдатели отвечают за определение логики обновления.
Паттерн Observer обычно включает в себя следующие роли:
- Субъект (Subject): определяет методы регистрации, отмены и уведомления объекта-наблюдателя.
- Конкретный субъект: реализует интерфейс субъекта, поддерживает список объектов-наблюдателей и уведомляет наблюдателей при изменении состояния.
- Observer (Наблюдатель): определяет метод получения уведомлений об обновлениях.
- Конкретный наблюдатель (Concrete Observer): реализует интерфейс наблюдателя и определяет конкретную логику обновления.
Базовая структурная диаграмма:
Ниже представлена классическая структурная диаграмма режима наблюдателя:
+-----------------+ +-----------------+
| Subject | | Observer |
+-----------------+ +-----------------+
| +Attach(observer) | | +Update() |
| +Detach(observer) | +-----------------+
| +Notify() |
+-----------------+
▲
|
|
+-----------------+
| ConcreteSubject |
+-----------------+
| -observers |
| +SetState() |
| +GetState() |
+-----------------+
▲
|
|
+-----------------+
| ConcreteObserver |
+-----------------+
| +Update() |
+-----------------+
На приведенной выше структурной диаграмме Subject
роль субъекта определяет методы регистрации, отмены и уведомления объекта-наблюдателя. Обычно он содержит список объектов-наблюдателей и уведомляет наблюдателей об изменении состояния.
Observer
Роль наблюдателя, определяющая метод получения уведомлений об обновлениях.
ConcreteSubject
является ролью конкретного субъекта, реализует интерфейс субъекта и поддерживает список объектов-наблюдателей. Когда состояние изменяется, оно Update
уведомляет наблюдателя, вызывая метод наблюдателя.
ConcreteObserver
Это роль конкретного наблюдателя, который реализует интерфейс наблюдателя и определяет конкретную логику обновления. Когда он получает уведомление об обновлении темы, он выполняет соответствующее действие.
Пояснение сценариев использования:
Режим наблюдателя подходит для следующих сценариев:
-
Рассмотрите возможность использования шаблона Observer, когда об изменении состояния одного объекта необходимо уведомить несколько других объектов, а операции этих объектов зависят от изменения состояния. Шаблон Observer предоставляет слабосвязанный способ уменьшения зависимостей между объектами-субъектами и объектами-наблюдателями.
-
Когда в системе необходимо установить связь «один ко многим» и объект-субъект может одновременно уведомлять несколько объектов-наблюдателей, можно использовать шаблон наблюдателя. Таким образом можно реализовать динамическую связь между объектами, что делает систему более гибкой и расширяемой.
-
Паттерн Observer можно использовать, когда абстрактная модель имеет два аспекта, один из которых зависит от другого, но оба необходимо изменять независимо. Режим наблюдателя может инкапсулировать изменения в двух аспектах в соответствующих объектах, делая их независимыми друг от друга и улучшая удобство обслуживания и масштабируемость системы.
Пример реализации кода:
Ниже приведен простой пример использования языка Go для реализации шаблона наблюдателя:
package main
import "fmt"
// Subject 主题接口
type Subject interface {
Attach(observer Observer) // 注册观察者
Detach(observer Observer) // 注销观察者
Notify() // 通知观察者
}
// Observer 观察者接口
type Observer interface {
Update() // 更新操作
}
// ConcreteSubject 具体主题
type ConcreteSubject struct {
observers []Observer
state string
}
func (s *ConcreteSubject) Attach(observer Observer) {
s.observers = append(s.observers, observer)
}
func (s *ConcreteSubject) Detach(observer Observer) {
for i, o := range s.observers {
if o == observer {
s.observers = append(s.observers[:i], s.observers[i+1:]...)
break
}
}
}
func (s *ConcreteSubject) Notify() {
for _, observer := range s.observers {
observer.Update()
}
}
func (s *ConcreteSubject) SetState(state string) {
s.state = state
s.Notify()
}
func (s *ConcreteSubject) GetState() string {
return s.state
}
// ConcreteObserver 具体观察者
type ConcreteObserver struct {
name string
}
func (o *ConcreteObserver) Update() {
fmt.Printf("Observer %s received the update.\n", o.name)
}
func main() {
subject := &ConcreteSubject{}
observer1 := &ConcreteObserver{name: "Observer1"}
observer2 := &ConcreteObserver{name: "Observer2"}
subject.Attach(observer1)
subject.Attach(observer2)
subject.SetState("new state")
subject.Detach(observer2)
subject.SetState("another state")
}
В приведенном выше примере мы определили Subject
интерфейс и Observer
интерфейс, представляющие субъекта и наблюдателя соответственно. ConcreteSubject
Структура реализует Subject
интерфейс и отвечает за ведение списка наблюдателей, регистрацию наблюдателей, отмену регистрации наблюдателей и уведомление наблюдателей. ConcreteObserver
Структура реализует Observer
интерфейс и определяет логику операции обновления.
В main
функции мы создаем конкретный объект-субъект subject
и два конкретных объекта-наблюдателя observer1
и observer2
. Вызывая Attach
метод, мы регистрируем объект-наблюдатель с объектом-субъектом. Затем SetState
измените состояние объекта-субъекта, вызвав метод, тем самым запустив операцию уведомления. Когда наблюдатель получит уведомление об обновлении, он выполнит соответствующее действие.
Ссылки на документацию:
Вот несколько ссылок на литературу по шаблону Observer для дальнейшего изучения и использования:
-
Шаблоны проектирования: элементы объектно-ориентированного программного обеспечения многократного использования — классическая книга по шаблонам проектирования Эриха Гаммы, Ричарда Хелма, Ральфа Джонсона и Джона Влиссайдса. Он содержит подробное введение и примеры шаблона Observer.
Ссылка: Amazon.com
-
Шаблоны проектирования Head First. В этой книге Эрика Фримена, Элизабет Робсон, Берта Бейтса и Кэти Сьерра представлены шаблоны проектирования в доступной и занимательной форме. Он содержит подробное объяснение и примеры шаблона наблюдателя.
Ссылка: Amazon.com
Какие продукты в настоящее время используют шаблон наблюдателя:
Шаблон наблюдателя широко используется в механизме событий в Java. Java предоставляет набор механизмов событий и прослушивателей для обработки передачи сообщений и запуска событий между объектами. Некоторые типичные продукты и технологии Java, такие как среда Swing GUI, JavaBeans, служба сообщений Java (JMS) и т. д., используют шаблон наблюдателя.
-
Платформа Swing GUI: Swing — это платформа для создания графических пользовательских интерфейсов на Java, а механизм событий реализован на основе режима наблюдателя. Компоненты в Swing (такие как кнопки, текстовые поля и т. д.) могут использоваться как субъектные объекты, а прослушиватели событий действуют как наблюдатели для получения и обработки уведомлений о событиях компонентов.
-
JavaBeans: JavaBeans — это спецификация технологии Java для создания повторно используемых компонентов. В JavaBeans механизм уведомления об изменении атрибута реализован на основе шаблона наблюдателя. Атрибуты в JavaBeans могут использоваться как субъектные объекты, а прослушиватели изменений атрибутов действуют как наблюдатели для получения и обработки уведомлений об изменениях атрибутов.
-
Служба сообщений Java (JMS): JMS — это спецификация API для распределенного обмена сообщениями на Java. Механизм подписки и публикации сообщений в JMS реализован на основе шаблона наблюдателя. Тема сообщения в JMS может использоваться как объект темы, а подписчик сообщения выступает в качестве наблюдателя за получением и обработкой опубликованных сообщений.
Помимо вышеупомянутых продуктов и технологий, паттерн Observer также широко используется во многих других областях, таких как мониторинг событий в разработке Android, событийно-ориентированное программирование в среде Spring и системы очередей сообщений. Гибкость и расширяемость шаблона Observer делают его одним из наиболее часто используемых шаблонов проектирования при разработке программного обеспечения.