1

We've built a class that allows you to easily draw stuff on a <canvas> element.

That class is called Canvas. I've encapsulated the <canvas> element and the class itself in a WebComponent, called <paper-canvas>.

<paper-canvas>
  <canvas id="#canvas"></canvas>
<paper-canvas>

<script>
  class PaperCanvas {
    constructor() {
      this.canvas = new Canvas('#canvas')
    }
  }
</script>

The Canvas class has a lot of methods such as:

  • importPNG()
  • drawSquare()

etc..

So right now when we want to say importPNG() we do something like this:

document.querySelector('paper-canvas').canvas.importPNG()

but I get a feeling that this is breaking encapsulation since I'm accessing internal properties of <paper-canvas>.

An alternative would be to do something like this:

<paper-canvas>
  <canvas id="#canvas"></canvas>
<paper-canvas>

<script>
  class PaperCanvas {
    constructor() {
      this.canvas = new Canvas('#canvas')
    }

    importPNG() {
      return this.canvas.importPNG()
    }
  }
</script>

and then for using it:

document.querySelector('paper-canvas').importPNG()

but this means that every time I add a new method on Canvas that should be publicly accessible to other members, I would also need to add it to my PaperCanvas class.

What's the recommended way of dealing with such cases?

Doc Brown
  • 199,015
  • 33
  • 367
  • 565
nicholaswmin
  • 1,869
  • 2
  • 18
  • 36
  • Possible duplicate of [Law of Demeter and its applicability](https://softwareengineering.stackexchange.com/questions/316678/law-of-demeter-and-its-applicability) – gnat Apr 19 '18 at 09:53
  • This is why inheritance of classes includes automatic delegation. – Frank Hileman Apr 20 '18 at 01:40

1 Answers1

1

It seems what you really want is to inherit PaperCanvas from Canvas. ECMAScript6 (which is, I guess, the language you are using here) supports this, you may implement it like

class PaperCanvas extends Canvas {
    constructor() {
        super('#canvas');
    }
}

Now a call like

 document.querySelector('paper-canvas').importPNG()

should work, with no need to implement delegation calls for every inherited method.

Doc Brown
  • 199,015
  • 33
  • 367
  • 565