how to perfectly implement observer design pattern in java