design pattern - observer, non java.util version