In designing an API that provides an event listening interface, it seems there are two conflicting ways of treating calls to add/remove listeners:
Multiple calls to addListener will only add a single listener (like adding it to a set); can be removed with a single call to removeListener.
Multiple calls to addListener will add a listener each time (like adding it to a list); must be balanced by multiple calls to removeListener.
I've found an example of each: (1) - The DOM addEventListener call in browsers only adds listeners once, silently ignoring requests to add the same listener a second time and (2) - jQuery
.on behaviour adds listeners multiple times.
Most other listener APIs seem to use (2), such as SWT and Swing event listeners. If (1) is chosen, there's also the question of whether it should fail silently or with an error when there is a request to add the same listener twice.
In my implementations, I tend to stick with (2) since it provides a cleaner setup/teardown type interface and reveals bugs where 'setup' is unintentionally being done twice, and is consistent with most implementations I've seen.
This leads me to my question - Is there a particular architecture or other underlying design that lends itself better to the other implementation? (ie: why does the other pattern exist?)