abstracted factory pattern