refactoring and add cache