Реализация шаблона наблюдателя

#c #observer-pattern

#c #наблюдатель-шаблон

Вопрос:

Мне было трудно точно понять, что такое шаблон наблюдателя, но я создал следующий код для своего проекта. Он использует SDL. Я использую библиотеку boost для реализации сигналов и, следовательно, реализую свой шаблон наблюдателя. Правильно ли это выглядит?

 /* This is setting up our signal for sending observations */
boost::signals2::signal<void (char, int, int)> sig;

/* Subjects the Observer will connect with */
sig.connect(amp;setChest);
sig.connect(amp;setNonTraverse);
sig.connect(amp;setEntry);
sig.connect(amp;setExit);

std::cout << "Waiting for user-interaction. Press on the 'X' to quit" << std::endl;

while ( !quit ) {               
    status = SDL_WaitEvent(amp;event);   //wait for an event to occur
    switch (event.type) {           //check the event type
        case SDL_KEYDOWN:           //Check if a key was pressed.     
        key = SDL_GetKeyName(event.key.keysym.sym);
        break;
        case SDL_MOUSEBUTTONUP:
        sig(key[0],event.button.x/32,event.button.y/32);
        break;
        case SDL_QUIT:          // Click on the 'X' to close the window.
        exit ( 1 );
        break;
    }
  } //while
  return true;
}
  

Комментарии:

1. В описании из Википедии говорится: «Шаблон наблюдателя (подмножество шаблона публикации / подписки) — это шаблон проектирования программного обеспечения, в котором объект, называемый субъектом, поддерживает список своих иждивенцев, называемых наблюдателями, и автоматически уведомляет их о любых изменениях состояния, обычно путем вызова одного из их методов.» Разве это не то, что я делаю? Тем не менее, спасибо за ваш вклад!

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

Ответ №1:

Ваш опубликованный код является кодом Наблюдателя.

В шаблоне наблюдателя наблюдатель не реагирует непосредственно на изменения состояния объектов. Вместо этого субъект информирует наблюдателя о любых изменениях, вызывая обратный вызов наблюдателя. Вот почему наблюдатель должен зарегистрироваться у субъекта, а не просто опрашивать (проверять состояние в цикле while) субъекта.

Я не слишком знаком с C , но вот некоторый Java-подобный псевдокод, в котором изложена основная идея:

 class Observer{
    public Observer(Subject subject){
        subject.register(this);
    }
    public void updateFromSubject(Subject subject){
        //respond to change
    }
}

class Subject{
    List<Observer> observers;
    public void register(Observer observer){
        observers.add(observer);
    }
    private void notifyObservers(){
        for(Observer obs : observers){
            obs.updateFromSubject(this);
        }
    }
    public void changeStateToNewState(Object o){
        .... //business logic
        notifyObservers();
}
  

Обратите внимание на отсутствие while цикла, что означает, что наблюдатель просто не выполняет никакой работы, пока не произойдет фактическое событие, вместо того, чтобы проверять флаг миллион раз в секунду, просто чтобы увидеть, изменился ли он.

Комментарии:

1. Хм, вы можете указать мне правильное направление? Как мне изменить свой текущий код? Разве функции субъектов не зависят от того, что наблюдается?

2. нет, наблюдатели — это классы, которые зарегистрированы для субъекта. наблюдатели для субъектов то же, что подписчики для газеты. таким образом, в основном, когда что-то важное меняется в предмете, наблюдатели узнают об этом.