Is there are good DRY fix for this painful design pattern?

Ben Finney ben+python at benfinney.id.au
Mon Feb 26 17:15:12 EST 2018


Steven D'Aprano <steve+comp.lang.python at pearwood.info> writes:

> I have a class with a large number of parameters (about ten) assigned
> in `__init__`. The class then has a number of methods which accept
> *optional* arguments with the same names as the
> constructor/initialiser parameters. If those arguments are None, the
> defaults are taken from the instance attributes.

The catalogue in Refactoring identifies what you need:

    Introduce Parameter Object

    You have a group of parameters that naturally go together.

    Replace them with an object.

    <URL:https://refactoring.com/catalog/introduceParameterObject.html>

Applying that to your example::

    class Foo:

        def __init__(self, wibble_param, dwarves, wobble_param):
            do_stuff_with(wibble_param)
            self.dwarves = dwarves
            do_other_stuff_with(wobble_param)

        def spam(self, dwarves=None):
            if dwarves is None:
                dwarves = self.dwarves

            # … now do the real spam work …

        def eggs(self, dwarves=None):
            if dwarves is None:
                dwarves = self.dwarves

            # … now do the real eggs work …

> […] to add insult to injury the class is still under active
> development with an unstable API, so every time I change one of the
> parameters, or add a new one, I have to change it in over a dozen
> places.

By encapsulating those parameters that all belong together, you can
change that set of parameters (by changing what ‘dwarves’ gets passed
around) and the function signatures don't change.

-- 
 \        “All opinions are not equal. Some are a very great deal more |
  `\   robust, sophisticated, and well supported in logic and argument |
_o__)                                     than others.” —Douglas Adams |
Ben Finney




More information about the Python-list mailing list