eolas/zk/Module_pattern.md

83 lines
2.2 KiB
Markdown
Raw Permalink Normal View History

2022-06-24 21:00:04 +01:00
---
2024-06-16 18:30:03 +01:00
tags:
- OOP
- design-patterns
2022-06-24 21:00:04 +01:00
---
# Module pattern
2022-06-24 21:00:04 +01:00
> Come back and compare this with learning from Node.js
With the module design pattern we create encapsulation: the variables and
functions (as methods) are kept private inside the module and cannot be
overwritten. This design pattern is familiar from Node.js development: every
package you import into your project and download from NPM is a module.
2022-06-24 21:00:04 +01:00
Generally you will create the module as a class, import it and then instantiate
a new instance. However for private development, you could just as well use an
object and duplicate it with `Object.create`.
2022-06-24 21:00:04 +01:00
## Example
Here is an example of a simple module that returns the age of a person.
```js
export default class Age {
constructor(name, birthYear) {
this.name = name;
this.birthYear = birthYear;
}
currentYear() {
return new Date().getFullYear();
}
get age() {
return this.currentYear() - this.birthYear;
}
}
```
```js
const martha = new Age("Martha", 1997);
console.log(martha.age); // 24
2022-06-24 21:00:04 +01:00
```
## Controlling access
In the example above, `aValue` could be edited in instantiations of the class.
Given that modules should not be overwrittable, you could make it a private
property on the class. The benefit of getters and setters is that they dictate
what can be modified and retrieved from the module. So if you use `get` and
`set` you can prevent overwrites.
2022-06-24 21:00:04 +01:00
## Object modules
If you want to use an object instead of a class, you have to take greater care
to ensure that the objects are not overwritable. **Also you cannot use the `#`
modifier to make properties private.**
2022-06-24 21:00:04 +01:00
- Use getters and setters for updating and retrieving values
- Use `Object.seal` to prevent changes to the parent object
- Instead of using getters and setters, for individual properties you can set
`writable` to be `false` for properties that you don't want changed
2022-06-24 21:00:04 +01:00
There are examples of each in the following:
```jsx
export const age = {
name: "",
2022-06-24 21:00:04 +01:00
birthYear: new Number(),
currentYear() {
return new Date().getFullYear();
},
get age() {
return this.currentYear() - this.birthYear;
},
};
Object.seal(age);
Object.defineProperty(age, "aValue", {
2022-06-24 21:00:04 +01:00
value: 6,
writable: false,
});
```