Question

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?

Was it helpful?

Solution

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.

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