Skip to main content
added 16 characters in body
Source Link
toolic
  • 16.4k
  • 6
  • 29
  • 221

I have written my own basic implementation of the Observer pattern, please. Please code review it as you feel. This is a one file implementation, and any feedback no matter how small is appreciated.

One sticky point is I was unsure on the implementation of RemoveObserverRemoveObserver, so this may not be optimal, could. Could I have used Ranges here to modernise?

#include <iostream>
#include <chrono>
#include <algorithm>
#include <thread>

using std::chrono::high_resolution_clock;
using std::chrono::duration_cast;
using std::chrono::duration;
using std::chrono::milliseconds;

class TimeObserver
{
public:
    virtual void Update(std::chrono::steady_clock::time_point time, std::chrono::steady_clock::time_point startTime) = 0;
};

class Clock : public TimeObserver
{
    virtual void Update(std::chrono::steady_clock::time_point time, std::chrono::steady_clock::time_point startTime)
    {
        duration<double, std::milli> ms_double = time - startTime;
        std::cout << ms_double.count() << "ms\n";
    }
};

class TimeManager
{
public:
    void RegisterObserver(TimeObserver* Observer)
    {
        observerList.push_back(Observer);
    };

    void RemoveObserver(TimeObserver* Observer)
    {
        std::vector<TimeObserver*>::iterator position = std::find(observerList.begin(), observerList.end(), Observer);

        if (position != observerList.end())
            observerList.erase(position);
    };

    void NotifyObservers()
    {
        for (auto& observer : observerList)
        {
            observer->Update(time, startTime);
        }
    }

    void UpdateTime()
    {
        time = high_resolution_clock::now();
        NotifyObservers();
    }

private:
    std::vector<TimeObserver*> observerList;
    std::chrono::steady_clock::time_point time = high_resolution_clock::now();
    std::chrono::steady_clock::time_point startTime = high_resolution_clock::now();
};

int main()
{
    TimeManager timeManager{};
    TimeObserver* clockObserver = new Clock();
    TimeObserver* clockObserver2 = new Clock();

    timeManager.RegisterObserver(clockObserver);

    // Print initial time reading
    timeManager.UpdateTime();

    // sleep for 1s
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));

    // register a second observer
    timeManager.RegisterObserver(clockObserver2);

    // This should print twice as we have 2 observers, should be ~1000ms
    timeManager.UpdateTime();

    // Remove both observers
    timeManager.RemoveObserver(clockObserver);
    timeManager.RemoveObserver(clockObserver2);

    // nothing should print as we have no observers
    timeManager.UpdateTime();
    
    delete clockObserver;
    delete clockObserver2;
}
```

I written my own basic implementation of the Observer pattern, please code review it as you feel. This is a one file implementation, any feedback no matter how small is appreciated.

One sticky point is I was unsure on the implementation of RemoveObserver so this may not be optimal, could I have used Ranges here to modernise?

#include <iostream>
#include <chrono>
#include <algorithm>
#include <thread>

using std::chrono::high_resolution_clock;
using std::chrono::duration_cast;
using std::chrono::duration;
using std::chrono::milliseconds;

class TimeObserver
{
public:
    virtual void Update(std::chrono::steady_clock::time_point time, std::chrono::steady_clock::time_point startTime) = 0;
};

class Clock : public TimeObserver
{
    virtual void Update(std::chrono::steady_clock::time_point time, std::chrono::steady_clock::time_point startTime)
    {
        duration<double, std::milli> ms_double = time - startTime;
        std::cout << ms_double.count() << "ms\n";
    }
};

class TimeManager
{
public:
    void RegisterObserver(TimeObserver* Observer)
    {
        observerList.push_back(Observer);
    };

    void RemoveObserver(TimeObserver* Observer)
    {
        std::vector<TimeObserver*>::iterator position = std::find(observerList.begin(), observerList.end(), Observer);

        if (position != observerList.end())
            observerList.erase(position);
    };

    void NotifyObservers()
    {
        for (auto& observer : observerList)
        {
            observer->Update(time, startTime);
        }
    }

    void UpdateTime()
    {
        time = high_resolution_clock::now();
        NotifyObservers();
    }

private:
    std::vector<TimeObserver*> observerList;
    std::chrono::steady_clock::time_point time = high_resolution_clock::now();
    std::chrono::steady_clock::time_point startTime = high_resolution_clock::now();
};

int main()
{
    TimeManager timeManager{};
    TimeObserver* clockObserver = new Clock();
    TimeObserver* clockObserver2 = new Clock();

    timeManager.RegisterObserver(clockObserver);

    // Print initial time reading
    timeManager.UpdateTime();

    // sleep for 1s
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));

    // register a second observer
    timeManager.RegisterObserver(clockObserver2);

    // This should print twice as we have 2 observers, should be ~1000ms
    timeManager.UpdateTime();

    // Remove both observers
    timeManager.RemoveObserver(clockObserver);
    timeManager.RemoveObserver(clockObserver2);

    // nothing should print as we have no observers
    timeManager.UpdateTime();
    
    delete clockObserver;
    delete clockObserver2;
}
```

I have written my own basic implementation of the Observer pattern. Please code review it as you feel. This is a one file implementation, and any feedback no matter how small is appreciated.

One sticky point is I was unsure on the implementation of RemoveObserver, so this may not be optimal. Could I have used Ranges here to modernise?

#include <iostream>
#include <chrono>
#include <algorithm>
#include <thread>

using std::chrono::high_resolution_clock;
using std::chrono::duration_cast;
using std::chrono::duration;
using std::chrono::milliseconds;

class TimeObserver
{
public:
    virtual void Update(std::chrono::steady_clock::time_point time, std::chrono::steady_clock::time_point startTime) = 0;
};

class Clock : public TimeObserver
{
    virtual void Update(std::chrono::steady_clock::time_point time, std::chrono::steady_clock::time_point startTime)
    {
        duration<double, std::milli> ms_double = time - startTime;
        std::cout << ms_double.count() << "ms\n";
    }
};

class TimeManager
{
public:
    void RegisterObserver(TimeObserver* Observer)
    {
        observerList.push_back(Observer);
    };

    void RemoveObserver(TimeObserver* Observer)
    {
        std::vector<TimeObserver*>::iterator position = std::find(observerList.begin(), observerList.end(), Observer);

        if (position != observerList.end())
            observerList.erase(position);
    };

    void NotifyObservers()
    {
        for (auto& observer : observerList)
        {
            observer->Update(time, startTime);
        }
    }

    void UpdateTime()
    {
        time = high_resolution_clock::now();
        NotifyObservers();
    }

private:
    std::vector<TimeObserver*> observerList;
    std::chrono::steady_clock::time_point time = high_resolution_clock::now();
    std::chrono::steady_clock::time_point startTime = high_resolution_clock::now();
};

int main()
{
    TimeManager timeManager{};
    TimeObserver* clockObserver = new Clock();
    TimeObserver* clockObserver2 = new Clock();

    timeManager.RegisterObserver(clockObserver);

    // Print initial time reading
    timeManager.UpdateTime();

    // sleep for 1s
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));

    // register a second observer
    timeManager.RegisterObserver(clockObserver2);

    // This should print twice as we have 2 observers, should be ~1000ms
    timeManager.UpdateTime();

    // Remove both observers
    timeManager.RemoveObserver(clockObserver);
    timeManager.RemoveObserver(clockObserver2);

    // nothing should print as we have no observers
    timeManager.UpdateTime();
    
    delete clockObserver;
    delete clockObserver2;
}
Source Link

My C++ Implementation of the Observer Pattern

I written my own basic implementation of the Observer pattern, please code review it as you feel. This is a one file implementation, any feedback no matter how small is appreciated.

One sticky point is I was unsure on the implementation of RemoveObserver so this may not be optimal, could I have used Ranges here to modernise?

#include <iostream>
#include <chrono>
#include <algorithm>
#include <thread>

using std::chrono::high_resolution_clock;
using std::chrono::duration_cast;
using std::chrono::duration;
using std::chrono::milliseconds;

class TimeObserver
{
public:
    virtual void Update(std::chrono::steady_clock::time_point time, std::chrono::steady_clock::time_point startTime) = 0;
};

class Clock : public TimeObserver
{
    virtual void Update(std::chrono::steady_clock::time_point time, std::chrono::steady_clock::time_point startTime)
    {
        duration<double, std::milli> ms_double = time - startTime;
        std::cout << ms_double.count() << "ms\n";
    }
};

class TimeManager
{
public:
    void RegisterObserver(TimeObserver* Observer)
    {
        observerList.push_back(Observer);
    };

    void RemoveObserver(TimeObserver* Observer)
    {
        std::vector<TimeObserver*>::iterator position = std::find(observerList.begin(), observerList.end(), Observer);

        if (position != observerList.end())
            observerList.erase(position);
    };

    void NotifyObservers()
    {
        for (auto& observer : observerList)
        {
            observer->Update(time, startTime);
        }
    }

    void UpdateTime()
    {
        time = high_resolution_clock::now();
        NotifyObservers();
    }

private:
    std::vector<TimeObserver*> observerList;
    std::chrono::steady_clock::time_point time = high_resolution_clock::now();
    std::chrono::steady_clock::time_point startTime = high_resolution_clock::now();
};

int main()
{
    TimeManager timeManager{};
    TimeObserver* clockObserver = new Clock();
    TimeObserver* clockObserver2 = new Clock();

    timeManager.RegisterObserver(clockObserver);

    // Print initial time reading
    timeManager.UpdateTime();

    // sleep for 1s
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));

    // register a second observer
    timeManager.RegisterObserver(clockObserver2);

    // This should print twice as we have 2 observers, should be ~1000ms
    timeManager.UpdateTime();

    // Remove both observers
    timeManager.RemoveObserver(clockObserver);
    timeManager.RemoveObserver(clockObserver2);

    // nothing should print as we have no observers
    timeManager.UpdateTime();
    
    delete clockObserver;
    delete clockObserver2;
}
```