refactor into abstract and implementation classes