abstracting and templatizing classes