add factory pattern