Home > Software design >  how to not repeat the same constructor in this class?
how to not repeat the same constructor in this class?

Time:08-12

I have a program that has a lot of similar classes.

the problem is that G0, G1, G2, and G3 classes, have the same constructor() structure (but this some little differences)

// this code is repeated on every child
this.x = _xyzObj.x ?? GcodeAPI.previusX ?? 0;
this.y = _xyzObj.y ?? GcodeAPI.previusY ?? 0;
this.z = _xyzObj.z ?? GcodeAPI.previusZ ?? 0;

but where is the problem?

normally for calling the class I use something like this

new G1({x:1, y:2, z: 10}).getCode();

As you see in the example,
the G1 class takes as parameters an object of data.

as this happens the same for the other child classes like
G0, G1, G2, G3, and so on...


I am interested to see if there is a way to
put the repetitive constructor() code inside the parent class (Gcommands)

✅ like I did for the methods (getCode();)

... and yes, I tried, but...
since the object of data came from the child class,
the parent class can't access the child variables
(like we did with super(); for getting the parent var from a child... but we can't do the opposite)

class GcodeAPI {
}

class Gcommands extends GcodeAPI {
  constructor() {
    super();
    this.lineOfCode = "⚠️ No line of code - please use getLine() method first";
  }

  getCode() {
    this.setLastPosition();
    this.lineOfCode = `${this.prefix} X${this.x} Y${this.y} Z${this.z}`;
    return this.lineOfCode;
  }

  setLastPosition() {
    GcodeAPI.previusX = this.x;
    GcodeAPI.previusY = this.y;
    GcodeAPI.previusZ = this.z;
  }
}

class G0 extends Gcommands {
  constructor(_xyzObj) {
    super();
    // these line are repetitive
    this.x = _xyzObj.x ?? GcodeAPI.previusX ?? 0;
    this.y = _xyzObj.y ?? GcodeAPI.previusY ?? 0;
    this.z = _xyzObj.z ?? GcodeAPI.previusZ ?? 0;

    this.prefix = `G0`;
  }
}

class G1 extends Gcommands {
  constructor(_xyzObj) {
    super();
    // these line are repetitive
    this.x = _xyzObj.x ?? GcodeAPI.previusX ?? 0;
    this.y = _xyzObj.y ?? GcodeAPI.previusY ?? 0;
    this.z = _xyzObj.z ?? GcodeAPI.previusZ ?? 0;

    this.prefix = `G1`;
  }
}

class G2 extends Gcommands { 
  constructor(_xyzObj) {
    super();
    // these line are repetitive
    this.x = _xyzObj.x ?? GcodeAPI.previusX ?? 0;
    this.y = _xyzObj.y ?? GcodeAPI.previusY ?? 0;
    this.z = _xyzObj.z ?? GcodeAPI.previusZ ?? 0;

    this.prefix = `G2`;
  }
}

class G3 extends Gcommands {
  constructor(_xyzObj) {
    super();
    // these line are repetitive
    this.x = _xyzObj.x ?? GcodeAPI.previusX ?? 0;
    this.y = _xyzObj.y ?? GcodeAPI.previusY ?? 0;
    this.z = _xyzObj.z ?? GcodeAPI.previusZ ?? 0;

    this.prefix = `G3`;
  }
}

console.log(new G3({ x: 1, y: 2, z: 3 }).getLine());


basically, I want a code similar to this,
but I don't know what is the syntax for making
the object parameter be in child class
but the variable in the parent class.

class GcodeAPI {}

class Gcommands extends GcodeAPI {
  constructor() {
    super();
    this.lineOfCode = "⚠️ No line of code - please use getLine() method first";

    // here are the repetitive classes
    this.x = _xyzObj.x ?? GcodeAPI.previusX ?? 0;
    this.y = _xyzObj.y ?? GcodeAPI.previusY ?? 0;
    this.z = _xyzObj.z ?? GcodeAPI.previusZ ?? 0;
  }

  getCode() {
    this.setLastPosition();
    this.lineOfCode = `${this.prefix} X${this.x} Y${this.y} Z${this.z}`;
    return this.lineOfCode;
  }

  setLastPosition() {
    GcodeAPI.previusX = this.x;
    GcodeAPI.previusY = this.y;
    GcodeAPI.previusZ = this.z;
  }
}

class G0 extends Gcommands {
  constructor(_xyzObj) {
    super();
    this.prefix = `G0`;
  }
}

class G1 extends Gcommands {
  constructor(_xyzObj) {
    super();

    this.prefix = `G1`;
  }
}

class G2 extends Gcommands {
  constructor(_xyzObj) {
    super();

    this.prefix = `G2`;
  }
}

class G3 extends Gcommands {
  constructor(_xyzObj) {
    super();

    this.prefix = `G3`;
  }
}


if you need some testing examples:

console.log(
  new G0({
    x: 1,
    y: 2,
  }).getCode(),
);

console.log(
  new G1({
    x: 3,
    y: 4,
  }).getCode(),
);

console.log(
  new G2({
    x: 5,
  }).getCode(),
);

console.log(
  new G3({
    z: 6,
  }).getCode(),
);

console.log(
  new G1({
    x: 7,
    y: 8,
    z: 9,
  }).getCode(),
);

CodePudding user response:

You can pass _xyzObj to super so that it is accessible.

class GcodeAPI {
  constructor(_xyzObj) {
    this.lineOfCode = "⚠️ No line of code - please use getLine() method first";
    this.x = _xyzObj.x ?? this.previusX ?? 0;
    this.y = _xyzObj.y ?? this.previusY ?? 0;
    this.z = _xyzObj.z ?? this.previusZ ?? 0;
  }
}

class Gcommands extends GcodeAPI {
  getCode() {
    this.setLastPosition();
    this.lineOfCode = `${this.prefix} X${this.x} Y${this.y} Z${this.z}`;
    return this.lineOfCode;
  }

  setLastPosition() {
    GcodeAPI.previusX = this.x;
    GcodeAPI.previusY = this.y;
    GcodeAPI.previusZ = this.z;
  }
}

class G0 extends Gcommands {
  constructor(_xyzObj) {
    super(_xyzObj);
    this.prefix = "G0";
  }
}

class G1 extends Gcommands {
  constructor(_xyzObj) {
    super(_xyzObj);
    this.prefix = "G1";
  }
}

class G2 extends Gcommands {
  constructor(_xyzObj) {
    super(_xyzObj);
    this.prefix = "G2";
  }
}

class G3 extends Gcommands {
  constructor(_xyzObj) {
    super(_xyzObj);
    this.prefix = "G3";
  }
}

console.log(
  new G0({
    x: 1,
    y: 2,
  }).getCode(),
);

console.log(
  new G1({
    x: 3,
    y: 4,
  }).getCode(),
);

console.log(
  new G2({
    x: 5,
  }).getCode(),
);

console.log(
  new G3({
    z: 6,
  }).getCode(),
);

console.log(
  new G1({
    x: 7,
    y: 8,
    z: 9,
  }).getCode(),
);

  • Related