factory pattern
factory