C : Шаблон наблюдателя

#c #design-patterns #observers

Вопрос:

Насколько эффективно я могу написать setScore (), не добавляя его на IObserver ? Есть ли что-то лучшее, чтобы добавить такой метод ? или какая-нибудь лучшая реализация, чем эта ? ПОЖАЛУЙСТА, ПОМОГИТЕ.

ObserverPattern.cpp:88:7: ошибка: «класс IObservable» не имеет члена с именем » setScore’

 //interface
class IObserver
{
public:
    virtual void update(int) = 0;   
};

//interface
class IObservable
{
public:
    virtual void subscribe(IObserver *) = 0;
    virtual void unsubscribe(IObserver *) = 0;
    virtual void notifyAll() = 0;   
};


class CricketMatchScore : public IObservable
{
    
public:

    CricketMatchScore()
    :   mScore (0)
    {

    }

    void subscribe(IObserver * obj)
    {
        mObservers.push_back(obj);
    }   

    virtual void unsubscribe(IObserver * obj)
    {
        auto iter = std::find(mObservers.begin(), mObservers.end(), obj);
        if (iter != mObservers.end())
        {
            mObservers.erase(iter);
        }
    }

    void notifyAll()
    {
        for (auto amp; item : mObservers)
        {
            item->update(mScore);
        }
    }

    void virtual setScore(int score)
    {
        if (mScore != score)
        {
            mScore = score;
            notifyAll();
        }
    }

private:
    std::vector<IObserver*> mObservers;
    int mScore;

};


class CricInfo : public IObserver
{
public:
    void update(int score)
    {
        std::cout<<score<<std::endl;
    }
};

int main()
{
    IObserver * ob1 = new CricInfo;
    IObserver * ob2 = new CricInfo;

    IObservable * obl = new CricketMatchScore;

    obl->subscribe(ob1);
    obl->subscribe(ob2);

    obl->setScore(20);

    return 0;

}
 

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

1. Зачем использовать IObservable* в качестве типа для obl , когда вы могли бы использовать CricketMatchScore* (или на самом деле CricketMatchScore , поскольку здесь нет причин использовать динамическое распределение)?

2. Спасибо тебе за ответ, Фред. Я как раз проходил через внедрение @ medium.com/@gayashanbc/… , так должны ли мы создавать интерфейсы в этом случае ? Будут ли они по-прежнему иметь смысл, если мы не будем использовать динамический полиморфизм и не будем пытаться сделать вещи универсальными ? Простите, если мои вопросы глупы. Спасибо.

3. Для того чтобы интерфейс работал с максимальной универсальностью, он должен был бы иметь виртуальные функции для всех функций, которые могут понадобиться его клиенту. Если клиентам нужно setScore , IObservable нужно setScore . Альтернативой является уродство, когда клиент dynamic_cast переходит к типу с setScore функцией, и как только клиенту нужно это сделать, попрощайтесь с претензиями на универсальность.

4. Среди этих двух реализаций, что лучше и почему ????? thispointer.com/… Против medium.com/@gayashanbc/…

Ответ №1:

Полиморфизм/Переопределение функций работает только тогда, когда вы переопределяете функцию(виртуальную), написанную в базовом классе, чтобы вести себя по-другому в производном классе, но здесь setScore она не объявлена в вашем базовом классе. Итак, полиморфизм здесь не сработает. Это ваш лучший выбор

  CricketMatchScore* ob3 = new CricketMatchScore(); //you already used ob1 above, it's a conflicting declaration in your code
 

Проверьте эту реализацию шаблона наблюдателя

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

1. Лучшим вариантом было бы CricketMatchScore ob3; . Нет необходимости new и в дополнительном багаже, который он вообще приносит.

2. Ладно, понял. Спасибо.