Hi I have the following class:
const MyClass = function MyClass() {
this.state = null;
}
MyClass.prototype.set = function(key, value) {
this[key] = value;
}
And the following enum in an other module:
const enumeration = {
ACTIVE: 'active',
PENDING: 'pending',
DONE: 'done'
}
I would like to know what are the best practices / conventions to handle setter for enumerations properties (state here)
I could do something like this:
let myClass = new MyClass();
myClass.set('state', enumeration.PENDING);
but its a bit verbose, and I need to know about the myClass module and the enum module.
An other idea is to do that:
const MyClass function MyClass() {
this.state = null;
}
MyClass.prototype.setPending = function() {
this.state = enumeration.PENDING;
}
and allow to call myClass.setPending()
But I don't know about the right naming of this kind of setters.
First I would argue that this question is not opinion-, but needs-based. If you say that it is preference-based, that means you simply have not encountered the issues which best practices are established to avoid. With that in mind, the first best practice is to keep it as simple as possible. How your API evolves depends on your application's specific needs and your ability to spot which ones are most appropriate.
Below is an example "evolution of code" of an upload object for a web FTP client. Note that there are a lot of different possible paths. This example's only aim is to demonstrate that best practices are not just a matter of preference.
You start off with this:
Then you realize you need a progressbar view to update when the state is set, so you make a specialized setter:
However later on you decide that you need to display a notification, but only when the state is set to 'done'. Or perhaps you find yourself in need of a shorthand method because you have to type
upload.setState('done')
a lot and find typingupload.setStateDone()
easier (cf. jQuery's$.get
vs$.ajax
).Note that you can prefer consistent API over convenience (e.g. I do prefer
$.get
over$.ajax
because there is significant overhead in using the latter, but I prefer to use jQuery's$(elem).on('click',..
over$.click
because all it does is prefill the 'click' string).There's still a problem with the setter: if you set an invalid state, e.g. 'whatever', it will attach the class 'state-whatever', so you update
setState
:Problem is, your states are hard-coded in a method and you would like to re-use them in other components, so you define a states map and adjust
setState
. In order to avoid a hard dependency, you use dependency injection instead of referencing the globalstates
map inside the constructor:On a sidenote, a setter in its most basic form is just a function that sets a property to a value on an object. How specific you make it, depends on how many parameters you hardcode into the setter.