Question

Given a base class with around 25 or so subclasses, I have found that adding an argument to the base constructor is painful.

protected AbstractController(Service1 s1, Service2 s2, Service3 s3){ ... }
public Concrete1Controller(Service1 s1, Service2 s2, Service3 s3) : base(s1, s2, s3)
public Concrete2Controller(Service1 s1, Service2 s2, Service3 s3) : base(s1, s2, s3)

Now that I need yet another object passed to my base controller, I am debating introducing a wrapper class and refactoring so that only a single parameter is required in the constructors of (most) concrete instances.

public class ServiceLayer
{
    public Service1 S1 {get; private set; }
    public Service2 S2 {get; private set; }
    public Service3 S3 {get; private set; }

    public ScheduledReportServices(Service1 s1, Service2 s2, Service3 s3)
    {
        S1 = s1;
        S2 = s2;
        S3 = s3;
    }
}

Which will allow me to clean up quite a bit.

protected AbstractController(ServiceLayer sl){ ... }
public Concrete1Controller(ServiceLayer sl) : base(sl)
public Concrete2Controller(ServiceLayer sl) : base(sl)

Given the amount that this reduces clutter, I'm either a dope for not doing this to begin with or there's a valid argument against this kind of approach.

I'd be interested in a) knowing what this "pattern" is called and b) if I'm going to regret it and if so, why?

Was it helpful?

Solution

a) You are performing an 'Introduce/Extract Parameter Object' refactoring.

b) I cannot say if you will regret this or not. If every single instance of this requires services s1-s3 without exception, then this looks like a good refactoring.

This can open the gate to undesired dependencies if you are not careful with your parameter object. Try to avoid combining unrelated references going forward to prevent this from becoming a big dependency-ball.

OTHER TIPS

There's nothing inherently wrong with this. In the past, I've had several cases where it has been more logical to add a SomeClassCreateInfo class in to the picture, rather than passing parameters.

So when to do it?

This is an inherently more difficult question to answer, and it becomes largely situational. Usually it becomes obvious when a Parameter-Wrapper/CreateInfo class is needed. But also, sometimes, it might be a sign that things are wrong with the design. In your case, the abstract controller needs access to a bunch of services. Is there any other way to provide this information?

Licensed under: CC-BY-SA with attribution
scroll top