What the article states is that multiple sections of the program create messages on a queue, all parts look at the queue and may do something if the messages are addressed to them.
In event-driven programming it is enough to create an event, an event handler, and then pass the event to the handler. Hence, you can define everyhing related to the handling of the events in a single object (event handler).
Although you may also achieve this via implementing a message queue, and multiple event handlers built-in to multiple sections of your code, it is not necessary.
The article seems to be describing a particular style of event-driven architecture, used to organize code within a single process.
> MOP is a flavour of object-oriented programming (OOP) with the core idea that your objects shouldn’t directly call each other, but communicate by passing messages via a message bus.
Sounds pretty much like a textbook definition of event-drive programming given by someone oblivious to event driven programming.
Event-driven programming has Event handlers (not objects) that pick up specific events. Events aren't messages to a specific Object.
The benefit is easier multithreading, drawback is memory use (incl. GC churn and bandwidth) and/or complexities of copy on write in multithreaded environment. The style is also not amenable to passing big amounts of data around directly. (That is often worked around via explicit memory sharing or a database - and passing handles instead of data.)
Another name for a different flavour of this is reactive programming.
So, there might be a message queue for each object - This seems to be the way that ROS (the robot operating system) is architected when you have nodes that process messages. Still it becomes difficult to disentagle a datum that needs to be accessed and modified by different queues - and avoiding race conditions, etc. But the solution could use message passing itself. If a queue modified a shared datum, it could message all the other queues using that datum and they could then update themselves. Conceivably, each queue could have its own core and so making parallel processing effortless. You would never need to worry about messing up shared data since the data would look after itself. But the 'problem' is that you have traded time and complexity for storage space - each datum now has a 'train' of addresses it has to visit and it has to carry those addresses with itself.
https://en.wikipedia.org/wiki/Event-driven_architecture