modify the code structure and add unittest