add three factory pattern