lundi 18 janvier 2021

Is there a term or pattern / anti-pattern related to explicitly returning an object within a constructor?

Let's say I've written an Element class that helps me flesh out DOM elements and behavior dynamically and I want to define an instance of Element in its own separate file for code organization purposes.

Let's say the following call would have more properties than I care to have written out in the current file:

new Element({
    // complex object structure
})

So instead I have a use method to pass the necessary data to a wrapper class written elsewhere, like so:

const Publisher = require("../manifest/classes/publisher.js")
const ElementsPanel = require("../manifest/components/elements-panel.js")
let publisher = new Publisher()
module.exports = class {
  constructor(env) {
    this.publisher = publisher
    new ElementsPanel().use({
      traits: {
        publisher,
        env
      },
      actions: {
        select: self => {}
      },
      ready: [
        self => {
          console.log("ready triggered")
        }
      ]
    }).appendTo(document.body)
  }
}

Where ElementsPanel is a class that contains the settings to generate the desired instance of Element. I could use a function, but createElementsPanel() looks a little less object-oriented to me than new ElementsPanel() and I'm trying to follow an object-oriented design approach. Instead of doThings() I want thing = new Thing(), thing.getDone().

Alternatively requiring the instance itself as an export forces either the instance of Element to be created immediately, or a require call to be used further into the code, and I like to keep my require calls at the top. So this is a style choice.

ElementsPanel:

const Element = require("../../element.js")
module.exports = class {
  constructor() {
    return new Element("div", {
      id: "elements-panel",
      classes: ["hidden"],
      actions: {
        update: (self, voxel) => {
          console.log("elements panel updating with spawned voxel:", voxel)
          if (!self.traits.elements[voxel.element]) {
            self.traits.elements[voxel.element] = {
                // ...
            }
          }
        }
      },
      ready: [
        self => {
          let tickCount = 0
          self.traits.elements = {}
          self.traits.publisher.on("spawn", voxel => {
            self.actions.update(voxel)
          })
        }
      ]
    })
  }
}

I like how this looks better than the alternatives I've considered, but it uses a class without that class being stateful, and I believe the rule of thumb is to use classes when your object needs to be stateful. The class instead is used here as a syntax style mechanism.

So I'm asking whether what I'm doing here is associated with a common term, pattern, or anti-pattern so I can change it now if necessary before someone sees my code one day and banishes me to developer h*ll.

Aucun commentaire:

Enregistrer un commentaire