Шаблон проектирования "Наблюдатель"
29 мая 2020Относится к поведенческим шаблонам.
Имеется объект, ведущий список своих "подчиненных" и автоматически уведомляющий их об изменении своего состояния.
Пример на PHP
В PHP (начиная с 5.1) имеются интерфейсы SplObserver и SplSubject, позволяющие реализовать шаблон "Наблюдатель".
Класс, получающий уведомления:
class UserObserver implements \SplObserver
{
public function update(\SplSubject $subject)
{
}
}
Класс, отправляющий уведомления:
class User implements \SplSubject
{
private string $email;
private array $observers = [];
public function __construct()
{
$this->observers = new \SplObjectStorage();
}
public function attach(\SplObserver $observer)
{
$this->observers->attach($observer);
}
public function detach(\SplObserver $observer)
{
$this->observers->detach($observer);
}
public function changeEmail(string $email)
{
$this->email = $email;
$this->notify();
}
public function notify()
{
foreach ($this->observers as $observer) {
$observer->update($this);
}
}
}
Использование:
$observer = new UserObserver();
$user = new User();
$user->attach($observer);
$user->changeEmail('test@test.com');
Пример на Go
package main
type IUser interface {
Attach(observer IUserObserver)
ChangeEmail(email string)
}
type IUserObserver interface {
Update(user IUser)
}
type User struct {
email string
observers []IUserObserver
}
func (u *User) Attach(observer IUserObserver) {
u.observers = append(u.observers, observer)
}
func (u *User) ChangeEmail(email string) {
u.email = email
u.notify()
}
func (u *User) notify() {
for _, v := range u.observers {
v.Update(u)
}
}
type UserObserver struct {
}
func (o *UserObserver) Update(user IUser) {
// требуемые действия
}
func main() {
observer := UserObserver{}
user := User{}
user.Attach(&observer)
user.ChangeEmail("test@test.com")
}
Источники:
http://designpatternsphp.readthedocs.io/ru/latest/Behavioral/Observer/README.html
https://habrahabr.ru/company/mailru/blog/325492/