refactor to observer