观察者模式，使用组合来替代继承