refactor && add unit test