observer cat

Паттерны проектирования — Наблюдатель

Сегодня мы поговорим о паттернах проектирования и в частности о таком паттерне как наблюдатель. Иногда Вы можете встретить термин шаблоны проектирования. Это одно и тоже.

Паттерны проектирования — одни из самых важных инструментов разработчика. Они демонстрируют лучшие решения для задач реальной жизни языком программирования.

Можно писать код и без паттернов и никогда о них не задумываться, но в жизни каждого разработчика наступает момент, когда можно решить задачу «в лоб» без использования лучших практик, или же посмотреть, как эту задачу уже решали до Вас. Именно это и есть шаблоны проектирования. Они и есть лучшие практики задач, которые решались задолго до Вас.

Есть очень много шаблонов проектирования. Учить их все необязательно да и просто затруднительно. Нужно знать, что они есть и при необходимости — воспользоваться ими.

Сегодня я покажу паттерн наблюдатель или Observer, на английском. Это очень популярный и известный шаблон проектирования в программировании.

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

Наблюдатель решает проблему автор/подписчик, когда один автор может иметь одного или много подписчиков.

Наблюдатель — это паттерн поведения. Для справки, согласно общепринятым нормам паттерны разделены на категории:

  • порождающие паттерны;
  • паттерны поведения;
  • структурные паттерны.

Если говорить простым языком — когда один объект изменяет свое состояние, все его подчиненные объекты оповещаются автоматически.

Ниже представлена классическая диаграмма паттерна наблюдатель:

паттерн наблюдатель Идея данного шаблона проста. Один или несколько Наблюдателей (Observer на диаграмме) заинтересован в состоянии Объекта (Subject). Он подписывается на объект. Если в Объекте происходит то, что может быть интересно Наблюдателю — ему отправляется оповещение об изменении. Когда Наблюдателю больше не интересно состояние Объекта — он может отписаться от оповещений.

Эта схема примечательна тем, что для того, чтобы передать данные к наблюдателям Объекту не нужно знать кто они. Это уменьшает связывание кода, что делает разработку более гибкой, а код легко читаемым.

Вы уже пользовались наблюдателем но не догадывались об этом. Если Вы использовали GUI библиотеки такие как Swing, AWT, JavaFX, то наверняка «навешивали» ActionListener на кнопки или поля. Это и есть реализация наблюдателя. Когда кнопка изменяет свое состояние — в приложении срабатывает специальный метод, который подписан на изменение этой кнопки.

Так как тема сайта язык Java я покажу пример наблюдателя на джава. Дело в том, что данный шаблон уже реализован в стандартной библиотеке java и Вам не нужно «изобретать велосипед», чтобы воспользоваться этим паттерном.

Для того, чтобы сделать класс наблюдаемым нужно унаследовать его от класса Observable. Для отправки оповещения подписчикам нужно вызвать метод setChanged(). Я взял достаточно простую предметную область. Допустим у меня есть система, где пользователи заводят блог, а читатели выбирают интересные блоги и подписываются на новые статьи. Очень напоминает WordPress. Разумеется, что все очень упрощенно. Когда в блоге появляется новая статья — подписчики должны получить уведомление. Сейчас неважно как будет отправлено оповещение. Это может быть почта, соц сети, оповещение в браузере. Для нашего примера сделаем просто вывод в консоль.

Код    
  1. import java.util.Observable;
  2.  
  3. public class Blog extends Observable{
  4.    
  5.     private String article;
  6.  
  7.     public String getArticle() {
  8.         return article;
  9.     }
  10.  
  11.     public void setArticle(String article) {
  12.         this.article = article;
  13.         setChanged();
  14.     }
  15.    
  16.    
  17.  
  18. }

 

Код довольно простой и не нуждается в комментариях. Заметьте, что когда вызывается метод setArticle идет вызов метода setChanged() для оповещения подписчиков.

Теперь реализуем подписчика. Для того, дать классу возможность стать подписчиком нужно имплементировать интерфейс Observer. Далее нужно реализовать единственный метод данного интерфейса update. Этот метод будет вызван при оповещении подписчика.

Код    
  1. import java.util.Observable;
  2. import java.util.Observer;
  3.  
  4. public class Subscriber implements Observer {
  5.  
  6.     @Override
  7.     public void update(Observable o, Object arg) {
  8.         // TODO Auto-generated method stub
  9.         System.out.println("New article is been created " + arg);
  10.     }
  11.  
  12. }

 

В методе выше, вместо вывода на консоль в более реальных проектах можно было бы вызвать метод отправки почты или браузерное оповещение.

Теперь посмотрим наш код в действии:

Код    
  1. public class Main {
  2.  
  3.     public static void main(String[] args) {
  4.         Subscriber sub1 = new Subscriber();
  5.         Subscriber sub2 = new Subscriber();
  6.         Blog programmingBlog = new Blog();
  7.         Blog flowerBlog = new Blog();
  8.        
  9.         programmingBlog.addObserver(sub1);
  10.         programmingBlog.addObserver(sub2);
  11.         flowerBlog.addObserver(sub2);
  12.        
  13.         programmingBlog.setArticle("Java tutorial");
  14.         programmingBlog.notifyObservers(programmingBlog.getArticle());
  15.         flowerBlog.setArticle("New Flowers!!!");
  16.         flowerBlog.notifyObservers(flowerBlog.getArticle());
  17.     }
  18. }

В коде выше я моделирую ситуацию из задания. Есть два блога: программирование, цветы. Есть два подписчика. Оба подписываются на программирование и второй еще и на цветы. Когда появляются новые записи в блогах мы оповещаем подписчиков методом notifyObservers. Он может принимать аргументы, а может быть и без аргументов.

Результат работы программы:

New article is been created Java tutorial
New article is been created Java tutorial
New article is been created New Flowers!!!

Все подписчики получили уведомление о новых статьях. Причем Blog ничего не знает о своих подписчиках. Он просто оповещает всех, кто подписался.

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

Добавить комментарий