refactor code by state_pattern