Object-oriented – Is “Introduce Parameter Object” actually a good pattern

design-patternsobject-orientedrefactoring

I have a situation where I want to call a function which requires a number of parameters. This function is not called directly, it is called indirectly and the parameters are delegated several times. Some extra parameters may be added in between the different layers, but those aren't included in the example for the sake of simplicity.

In pseudo code, A indirectly calls the functionality that occurs in C.abc.

class A {
    private B b;

    public int abc() {
        return b.abc(value1, value2, value3);
    }
}

class B {
    private C c;

    public int abc(int x, int y, int z) {
        return c.abc(x, y, z);
    }
}

class C {
    private int w = 100;

    public int abc(int x, int y, int z) {
        // Do something with parameters x, y, z, e.g.:
        return w + x + y + z;
    }
}

The number of parameters could be different than three of course: it could be smaller or larger as long as the parameters are going to be used together. The Introduce Parameter Object is sometimes advised in such a situation (here and here).

It would be applied as follows:

class XYZParameterObject {

    private int x, y, z;

    public constructor(int x, int y, int z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    public int abc(int w) {
        return w + x + y + z;
    }
}

class A {
    private B b;

    public int abc() {
        return b.abc(new XYZParameterObject(value1, value2, value3));
    }
}

class B {
    private C c;

    public int abc(XYZParameterObject xyz) {
        return c.abc(xyz);
    }
}

class C {
    private int w = 10;

    public int abc(XYZParameterObject xyz) {
        // Do something with parameters x, y, z, e.g.:
        return xyz.abc(this.w);
    }
}

To me this seems like a class is designed around just one method, while it does not have any behavior. It would actually be the same as passing a closure instead of creating a XYZParameterObject instance. In both situations the x, y, z parameters are reduced to simply one parameter. Both looks like abusing a class just for the sake of not having to pass the same arguments over and over. On the other hand, that would be somewhat convenient of course!

So what is an advisable practice in such a situation?

Best Answer

A parameter object is just a way of collecting a set of parameters into a unit. But in your example you are doing something more - your are adding business logic (the addition) into the parameter object itself (which in turn means the C class becomes is superfluous). But then it is not just a parameter object anymore.

A parameter object is not a class built around a single method, it is a data transfer object, which means it does not have methods at all (or at at least only methods for accessing data). But it could be the starting point for a real class with business methods.

Whether a parameter object is a good idea in the first place depends on your code. Your example is too abstract to tell. But if x, y and z say represented coordinates for a point in 3D it would probably be useful to group them in a parameter object, but probably also useful furthermore to add some business logic for calculations on points, e.g scaling, adding etc.