API design has many of the same challenges as PL design. I would say that 'addObserver' is fine, but 'removeObserver' is a buggy API.
Instead, like channels connecting to a remote service, we should be able to '.close()' the observer from the receiver's end, and the remote end should be able to '.check()' whether the observer is closed, and simply drop all the closed connections every time it's about to send an update.
Additionally, sending messages to a closed observer shouldn't be an error, will just drop the message then return.
This API is much more robust in context of concurrent connections and closing of connections.