Reputation: 6396
I have a class that has internal state and public getters:
function Section() {
let ls = ['a','b','c','d','e','f'];
let i = 0;
this.map = () => ls[i];
this.changeI = () => i=(i+1)%ls.length;
}
I have a user of this class:
function Ground() {
let section = new Section();
let mover = new Mover(this);
let map;
this.map = () => map;
this.init = () => {
map = section.map();
};
this.draw = () => {
console.log(map);
}
}
and user of that class:
function Mover(ground) {
let map = ground.map;
this.dojob = () => {
let usemap = map()
return usemap + 'X';
}
}
Now when I call changeI
, the return of the map
function changes so I need to update the variable I use to draw the map in Ground function.
I can make it a getter function instead of a variable as Mover class uses, but I think there is something wrong with this approach, I mean is there a better way to do this, or can I get rid of this internal state or the nested dependencies?
I need an answer as simple as few abstractions as possible.
Upvotes: 1
Views: 48
Reputation: 42228
Each of these classes has an internal instance of Section
or an internal instance of another class which accesses Section
. So you can call .map()
and always get the updated value from the Section
map, regardless of i
;
Note that Ground
creates its own new Section()
rather than taking an existing Section
instance as an argument, so the only way to call changeI
on this Section
instance is through ground.section.changeI()
.
Is there a reason that you aren't using ES6 class syntax? I rewrote these as classes with a typescript annotations (but you can remove those) and some other changes which I think make it much more readable.
class Section {
private ls = ['a', 'b', 'c', 'd', 'e', 'f'];
private i = 0;
public map = (): string => {
return this.ls[this.i];
}
public changeI = (): void => {
this.i = (this.i + 1) % this.ls.length;
}
}
class Ground {
public readonly section = new Section();
public map = (): string => {
return this.section.map();
}
public draw = (): void => {
console.log(this.map());
}
public createMover = (): Mover => {
return new Mover(this);
}
}
class Mover {
private readonly ground: Ground;
constructor(ground: Ground) {
this.ground = ground;
}
public dojob = (): string => {
return this.ground.map() + 'X';
}
}
You can test it out and see that we are properly incrementing in all places.
const ground = new Ground();
const mover = new Mover(ground);
ground.draw(); // "a"
ground.section.changeI();
ground.draw(); // "b"
console.log( mover.dojob() ); // "bX"
ground.section.changeI();
console.log( mover.dojob() ); // "cX"
Upvotes: 1