Наблюдатель (шаблон проектирования)

Материал из Seo Wiki - Поисковая Оптимизация и Программирование
Перейти к навигацииПерейти к поиску

Наблюдатель, Observer — поведенческий шаблон проектирования. Также известен как «подчинённые» (Dependents), «издатель-подписчик» (Publisher-Subscriber).

Назначение

Определяет зависимость типа «один ко многим» между объектами таким образом, что при изменении состояния одного объекта все зависящие от него оповещаются об этом событии.

Реализация

Файл:Observer.png

При реализации шаблона «наблюдатель» обычно используются следующие классы.

  • Observable — интерфейс, определяющий методы для добавления, удаления и оповещения наблюдателей.
  • Observer — интерфейс, с помощью которого наблюдаемый объект оповещает наблюдателей.
  • ConcreteObservable — конкретный класс, который реализует интерфейс Observable.
  • ConcreteObserver — конкретный класс, который реализует интерфейс Observer.

Область применения

Шаблон «наблюдатель» применяется в тех случаях, когда система обладает следующими свойствами:

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

Данный шаблон часто применяют в ситуациях, в которых отправителя сообщений не интересует, что делают с предоставленной им информацией получатели.

Примеры

PHP5

<source lang="php"> interface Observer{ function notify($obj); }

class ExchangeRate{ static private $instance = NULL; private $observers = array(); private $exchange_rate;

private function ExchangeRate(){ }

static public function getInstance(){ if(self::$instance == NULL){ self::$instance = new ExchangeRate(); } return self::$instance; }

public function getExchangeRate(){ return $this->exchange_rate; }

public function setExchangeRate($new_rate){ $this->exchange_rate = $new_rate; $this->notifyObservers(); }

public function registerObserver($obj){ $this->observers[] = $obj; }

function notifyObservers(){ foreach($this->observers as $obj){ $obj->notify($this); } } }

class ProductItem implements Observer{

public function __construct(){ ExchangeRate::getInstance()->registerObserver($this); }

public function notify($obj){ if($obj instanceof ExchangeRate) { // Update exchange rate data print "Received update!\n"; } } }

$product1 = new ProductItem(); $product2 = new ProductItem();

ExchangeRate::getInstance()->setExchangeRate(4.5); </source>

Пример на C#

<source lang="csharp"> using System; using System.Collections; using System.Threading;

namespace Observer {

   /// <summary>
   /// Observer Pattern Judith Bishop Jan 2007
   /// 
   /// The Subject runs in a thread and changes its state
   /// independently. At each change, it notifies its Observers.
   /// </summary>
   class Program
   {
       static void Main(string[] args)
       {
           Subject subject = new Subject();
           Observer Observer = new Observer(subject,"Center","\t\t");
           Observer observer2 = new Observer(subject,"Right","\t\t\t\t");
           subject.Go();
           // Wait for user
           Console.Read();
       }
   }
   class Simulator : IEnumerable {
       string [] moves = {"5","3","1","6","7"};
       public IEnumerator GetEnumerator() 
       {
           foreach( string element in moves )
               yield return element;
       }
   }
   class Subject {
       
       public delegate void Callback (string s);
       
       public event Callback Notify;
       
       Simulator simulator = new Simulator( );
       
       const int speed = 200;
       public string SubjectState { get; set; }
       public void Go() 
       {
           new Thread(new ThreadStart(Run)).Start( );
       }
       void Run () 
       {
           foreach (string s in simulator) 
           {
               Console.WriteLine("Subject: " + s);
               SubjectState = s;
               Notify(s);
               Thread.Sleep(speed); // milliseconds
           }
       }
   }
   interface IObserver 
   {
       void Update(string state);
   }
   class Observer : IObserver
   {
       string name;
       Subject subject;
       string state;
       string gap;
       public Observer(Subject subject, string name, string gap)
       {
           this.subject = subject;
           this.name = name;
           this.gap = gap;
           subject.Notify += Update;
       }
       public void Update(string subjectState)
       {
           state = subjectState;
           Console.WriteLine(gap + name + ": " + state);
       }
   }

} </source>

C++

<source lang=cpp>

  1. include <iostream>
  2. include <string>
  3. include <map>
  4. include <boost/foreach.hpp>

class SupervisedString; class IObserver{ public: virtual void handleEvent(const SupervisedString&) = 0; };


class SupervisedString{ // Observable class std::string _str; std::map<IObserver* const, IObserver* const> _observers;

typedef std::map<IObserver* const, IObserver* const>::value_type item;

void _Notify(){ BOOST_FOREACH(item iter, _observers){ iter.second->handleEvent(*this); } }

public: void add(IObserver& ref){ _observers.insert(item(&ref, &ref)); }

void remove(IObserver& ref){ _observers.erase(&ref); }

const std::string& get() const{ return _str; }

void reset(std::string str){ _str = str; _Notify(); } };


class Reflector: public IObserver{ // Prints the observed string into std::cout public: virtual void handleEvent(const SupervisedString& ref){ std::cout<<ref.get()<<std::endl; } };

class Counter: public IObserver{ // Prints the length of observed string into std::cout virtual void handleEvent(const SupervisedString& ref){ std::cout<<"length = "<<ref.get().length()<<std::endl; } };

int main(){

SupervisedString str; Reflector refl; Counter cnt;

str.add(refl); str.reset("Hello, World!"); std::cout<<std::endl;

str.remove(refl); str.add (cnt); str.reset("World, Hello!"); std::cout<<std::endl;

return 0; } </source>

Примечания

См. также

Ссылки

реализация паттерна observer(наблюдатель) на javascript


Поведенческие шаблоны проектирования

Interpreter/Интерпретатор | Template Method/Шаблонный метод | Command/Команда | Chain of Responsibility/Цепочка обязанностей | Iterator/Итератор, Cursor | Mediator/Посредник | Memento/Хранитель, Token | Observer/Наблюдатель, Listener | State/Состояние | Strategy/Стратегия | Visitor/Посетитель | Event listener | Single-serving visitor | Hierarchical visitor |

bg:Наблюдател (шаблон) ca:Patró observador cs:Observer de:Observer (Entwurfsmuster) en:Observer pattern es:Observer (patrón de diseño) fr:Observateur (patron de conception) it:Observer pattern ja:Observer パターン ko:옵저버 패턴 nl:Observer pl:Obserwator (wzorzec projektowy) pt:Observer th:อ็อบเซิร์ฟเวอร์แพตเทิร์น zh:观察者模式

Если вам нравится SbUP.com Сайт, вы можете поддержать его - BTC: bc1qppjcl3c2cyjazy6lepmrv3fh6ke9mxs7zpfky0 , TRC20 и ещё....