The solution to the design problem you proposed appears to severely limit flexibility and would therefore require overriding classes. It is far better to offer more flexibility even if it is potentially hazardous than to require users override classes which IMO is far more hazardous.

Here is the design problem: there is one event dispatched but two potentially very different use-cases for this event. Those are: 1) modify the query before it executes (e.g. addFieldToFilter()) and 2) modify the loaded items (e.g. appendReviewSummary()). The big problem is the ordering of these cannot be easily controlled. For example, Mage_Review causes the collection to be loaded so no other observer can modify the query.

An alternate solution would be to dispatch two events back-to-back instead of one, like:

    Mage::dispatchEvent('catalog_block_product_collection_load_before', array('collection' => $collection));
    Mage::dispatchEvent('catalog_block_product_collection_load_after', array('collection' => $collection));

I'd be fine with this solution as well but as it stands currently, adding a simple filter to the product collection (or any other query change) requires a core class override.