Polish code

Add more abstraction and remove duplicate code.