0

Let's say I need write a Wrapper for a 3rd party class which I'm not able to change.

The interface of the class looks like this

class Rewriter {
    public List<Mapping> getMappings();
}

The wrapper looks like this

class RewriterSpec {
    private final Rewriter rewriter;

    public RewriterSpec(Rewriter rewriter) {
        this.rewriter = rewriter;
    }

    public addMapping(Mapping m) {
        rewriter.getMappings().add(m);
    }
}

So from my understanding the RewriterSpec violates the Law of Demeter because it requires structural knowledge about the Rewriter.

Now, the question is, would it be better from a design / testing point of view to just pass in the list of mappings?

class Rewriter {
    public List<Mapping> getMappings();
}

The wrapper looks like this

class RewriterSpec {
    private final Rewriter rewriter;

    public RewriterSpec(List<Mapping> mappings) {
        this.mappings = mappings;
    }

    public addMapping(Mapping m) {
        mappings.add(m);
    }
}

Is it okay to just pass the List by reference?

helpermethod
  • 59,493
  • 71
  • 188
  • 276

1 Answers1

0

Wikipedia states the following:

https://en.wikipedia.org/wiki/Law_of_Demeter

More formally, the Law of Demeter for functions requires that a method m of an object O may only invoke the methods of the following kinds of objects:[2]

  • O itself
  • m's parameters
  • Any objects created/instantiated within m
  • O's direct component objects
  • A global variable, accessible by O, in the scope of m

By following these principals, you could define a method in the Rewriter interface to directly add Mapping objects to its list to satisfy the principle (A global variable, accessible by O, in the scope of m).

class RewriterSpec {
    private final Rewriter rewriter;

    public RewriterSpec(Rewriter rewriter) {
        this.rewriter = rewriter;
    }

    public addMapping(Mapping m) {
        rewriter.addMapping(m);
    }
}

Considering Rewriter can't be modified, you can opt for the following:

class RewriterSpec {
    private final Rewriter rewriter;
    private final List<Mapping> mappings;

    public RewriterSpec(Rewriter rewriter) {
        this.rewriter = rewriter;
        this.mappings = rewriter.getMappings();
    }

    public addMapping(Mapping m) {
        mappings.addMapping(m);
    }
}
Luciano van der Veekens
  • 6,307
  • 4
  • 26
  • 30