refactor to template pattern