Observers are very powerful instrument in Magento. They allow us to bind our functionality to some Magento events. Many of you know about dispatchEvent function. This function calls all observers registered for this event. For example, we have the following code snippet placed in this app/code/core/Mage/Catalog/Model/Resource/Product/Collection.php file.

Mage::dispatchEvent('catalog_product_collection_load_after', array('collection' => $this));

It means, that we can bind any event we want to identifier ‘catalog_product_collection_load_after’ and operate with $this variable (it’s a product collection in our case). But it is important to know what event choose for your functionality. Therefore, Magento runs your observer after collection loading.
Now, we need to bind our observer to ‘catalog_product_collection_load_after’ event. See below how we can do this

<global>
    <!--...-->
    <!--Scope where we declare all events-->
    <events>
        <!--Event identifier-->
        <catalog_product_collection_load_after>
            <!--Scope where we declare all observers for current event-->           
            <observers>
                <!--unique id for our observer-->
                <atwix_product_collection_load_after>
                    <!--observer type-->
                    <type>singleton</type>
                    <!--path to our observer (app/code/local/Atwix/Test/Model/Observer.php)-->
                    <class>atwix_test/observer</class>
                    <!--Method's Name-->
                    <method>collectionLoadAfter</method>
                </atwix_product_collection_load_after>
            </observers>
        </catalog_product_collection_load_after>
    </events>
    <!--...-->
</global>

Notice: You should know one more thing – it is observer type. Observer type is a singleton by default, so if you skip the type node, your observer will be loaded as a singleton. That means, if you have many observers binded to the same action, the data, that was passed to the observers will be changed in the first observer and will be passed to another. When you choose ‘model’ type or ‘object’

<type>model</type>

that means, if data was changed in the first observer, then changed data will be NOT passed into the second. The second observer loads the data again. Also, we have ‘disabled’ type, what tells Magento do not run this observer.

Here is the simple observer. Note, that the next array(‘collection’ => $this) is passed into dispatchEvent function, so we should use the getCollection() function, if array(‘data’ => $this) would be passed – then we would use getData(). See bellow.

class Atwix_Test_Model_Observer
{
    public function collectionLoadAfter($observer)
    {
        $collection = $observer->getCollection();
        //$collection value is the same as $this value that was passed, it's product collection
        //in this function you can change collection value
    }
}

That’s all guys. Please, share your own experience in the comments.