Is passing too many arguments to the constructor considered an anti-pattern?

前端 未结 5 891
独厮守ぢ
独厮守ぢ 2021-01-01 20:31

I am considering using the factory_boy library for API testing. An example from the documentation is:

class UserFactory(factory.Factory):
    class Meta:
            


        
5条回答
  •  暗喜
    暗喜 (楼主)
    2021-01-01 20:41

    The biggest risk would be if you had a large number of positional arguments and then ended up not knowing which is which.. Keyword arguments definitely make this better.

    As suggested by others, the builder pattern also works quite nicely. If you have a very large number of fields, you can also do something more generic, like so:

    class Builder(object):
    
        def __init__(self, cls):
            self.attrs = {}
            self.cls = cls
    
        def __getattr__(self, name):
            if name[0:3] == 'set':
                def setter(x):
                    field_name = name[3].lower() + name[4:]
                    self.attrs[field_name] = x
                    return self
                return setter
            else:
                return super(UserBuilder, self).__getattribute__(name)
    
        def build(self):
            return self.cls(**self.attrs)
    
    class User(object):
    
        def __str__(self):
            return "%s %s" % (self.firstName, self.lastName)
    
        def __init__(self, **kwargs):
            # TODO: validate fields
            for key in kwargs:
                setattr(self, key, kwargs[key])
    
        @classmethod
        def builder(cls):
            return Builder(cls)
    
    print (User.builder()
      .setFirstName('John')
      .setLastName('Doe')
      .build()) # prints John Doe
    

提交回复
热议问题