1

Suppose I'd like to implement the templating pattern, but the only real differences between the subclasses are their choices of some invariant dependencies.

Is there a drawback to preferring this style:

public abstract class AbstractClass {
    private final DependencyA dependencyA;
    private final DependencyB dependencyB;

    public AbstractClass(final DependencyA dependencyA, final DependencyB dependencyB) {
        this.dependencyA = dependencyA;
        this.dependencyB = dependencyB;
    }

    public void doStuffWithDeps() {
        //Business logic using the dependency fields
    }
}

To this style?

public abstract class AbstractClass {
    protected abstract DependencyA getDependencyA();
    protected abstract DependencyB getDependencyB();

    public void doStuffWithDeps() {
        //Business logic using the dependency getters
    }
}

I don't have much experience using the first of the two, but I'd argue that in cases where the dependencies don't change over time, the first is preferred as there is no reason to keep asking for the dependencies for each call to the doStuffWithDeps() method. However, whenever I've seen this kind of problem it has always been solved with the second implementation, which makes me wonder if I've missed something.

I realise inheritance is not really a good solution to these kinds of problems in the first place, but suppose these are my two options, which one should I prefer and why?

4
  • Did you mean protected final DependencyA dependencyA; Jan 20, 2018 at 16:01
  • @MarkBenningfield no. Could you elaborate on what makes you say that?
    – kinbiko
    Jan 20, 2018 at 16:24
  • If derived classes are meant to override doStuffWithDeps(), they cannot access the private dependency fields. Jan 20, 2018 at 16:54
  • @MarkBenningfield the doStuffWithDeps() isn't meant to be overridden. The methods that would be overridden exist in the second example only. In the first they are replaced with constructor params instead, with the additional assumption that they don't change over time. This question asks about the advantages and disadvantages of the two ways of doing this. Hope that helps clearing things up.
    – kinbiko
    Jan 20, 2018 at 17:16

3 Answers 3

1

If subclasses of your abstract class will use field injection, it's much easier for them if you use second style.

With first style they have to in constructor give you something even though they don't have their dependency yet. So they give you proxy. That proxy will change behavior from not yeat injected to injected when injection phase completes.

So what you thought gave you immutability gave you nothing more than the second approach.

0

The key question here is do you want instances of your AbstractClass to be immutable or not. In other words do you want a object, once it's instanced not be able to change its dependencies. If so, go with the first method, otherwise the second.

If it is all the same for your situation, make it immutable. Immutable objects make reading code much more easier and don't allow you to make accidental changes to the object somewhere later in the code via its reference. Another point for immutable is that that way the objects are strictly defined by their dependencies and you know what to expect from then in all situations.

0

Well, whether it's a drawback or an advantage depends on your intent. The first example is a standard construction for dependency injection.

If the dependencies need to be able to change over the lifetime of a given instance, then use the second example. Again, whether it's an advantage or a drawback depends on what it is that you need to do.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.