factory abstract