diff options
Diffstat (limited to 'doc/development/fe_guide/design_patterns.md')
-rw-r--r-- | doc/development/fe_guide/design_patterns.md | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/doc/development/fe_guide/design_patterns.md b/doc/development/fe_guide/design_patterns.md new file mode 100644 index 00000000000..e05887a19af --- /dev/null +++ b/doc/development/fe_guide/design_patterns.md @@ -0,0 +1,78 @@ +# Design Patterns + +## Singletons + +When exactly one object is needed for a given task, prefer to define it as a +`class` rather than as an object literal. Prefer also to explicitly restrict +instantiation, unless flexibility is important (e.g. for testing). + +```javascript +// bad + +const MyThing = { + prop1: 'hello', + method1: () => {} +}; + +export default MyThing; + +// good + +class MyThing { + constructor() { + this.prop1 = 'hello'; + } + method1() {} +} + +export default new MyThing(); + +// best + +export default class MyThing { + constructor() { + if (!this.prototype.singleton) { + this.init(); + this.prototype.singleton = this; + } + return this.prototype.singleton; + } + + init() { + this.prop1 = 'hello'; + } + + method1() {} +} + +``` + +## Manipulating the DOM in a JS Class + +When writing a class that needs to manipulate the DOM guarantee a container option is provided. +This is useful when we need that class to be instantiated more than once in the same page. + +Bad: +```javascript +class Foo { + constructor() { + document.querySelector('.bar'); + } +} +new Foo(); +``` + +Good: +```javascript +class Foo { + constructor(opts) { + document.querySelector(`${opts.container} .bar`); + } +} + +new Foo({ container: '.my-element' }); +``` +You can find an example of the above in this [class][container-class-example]; + + +[container-class-example]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/app/assets/javascripts/mini_pipeline_graph_dropdown.js |