1
\$\begingroup\$

I've decided to implement a simple case of the Observer pattern. I've gone about this considering you can only register 1 single observer in the Observable, instead of allowing multiple ones.

I would really like feedback about what'd be the proper way to return the listener in the run method while still yielding values, if possible i'd like to allow some sort of method chaining

Overall I would like some criticism about this whole design and of course, anything else is on the table will be appreciated.

Code:

import time


class Observer:

    def __init__(self):
        self.lines = []
        self.execution_time = None

    def on_process(self, value):
        line = f"<< processed: {value} >>"
        self.lines.append(line)
        return line

    def on_done(self, value):
        self.execution_time = value


class Observable:

    def __init__(self):
        self.listener = None

    def register_listener(self, listener):
        self.listener = listener
        return self

    def run(self, iterable):
        s = time.time()
        for v in iterable:
            yield self.listener.on_process(v)

        self.listener.on_done(time.time() - s)


if __name__ == '__main__':
    obj = Observable().register_listener(Observer())

    for x in obj.run(range(10)):
        print(x)

    listener = obj.listener
    print("Number of lines:", len(listener.lines))
    print("Execution time:", listener.execution_time)
\$\endgroup\$
2
\$\begingroup\$
  • You haven't implemented the observer pattern as your subject, Observable, doesn't contain a list of observers.

    Whilst this may seem like some small petty point it is the core problem that the pattern hopes to solve.

  • You have failed to make the subject relay to its observers. As you have moved the code, run, that should be in the observer into the subject.

    This makes the observer interface neigh on useless, because if you want to change this functionality then you're screwed.

An example of the observer pattern is in Python's logging library. In this you have events like a logger.info(message). The logger, the subject, goes on to call the underlying handlers, observers, with the event. This causes the handler to handle the event how it's been designed to.

It's common to have a StreamHandler and sometimes a FileHandler. The former that just prints the message, and the latter that writes the message to a file.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ @BPL Yes exactly that. Yes this would be called an iterative review. We have some rules around them, but in short do not edit the above question, post a new question. Also, to be clear, I am in no way obligated to help you. \$\endgroup\$ – Peilonrayz Mar 27 at 22:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.