#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. нет, наблюдатели — это классы, которые зарегистрированы для субъекта. наблюдатели для субъектов то же, что подписчики для газеты. таким образом, в основном, когда что-то важное меняется в предмете, наблюдатели узнают об этом.