JavaScript is a multi-paradigm programming language, so it provides us with a lot of different ways to deal with the same problem.
👉 What problem does factory pattern solve?
Factory pattern is used as a substitute for using classes.
For example, we want to create a couple of software developers who prefer different programming languages.
We can implement this behavior using class.
class SoftwareDeveloper {
constructor(language) {
this.language = language || 'C';
}
writeMessageInChat() {
console.log(`My favorite programming language is ${this.language}!`);
}
}
const Brendan = new SoftwareDeveloper('JavaScript');
const Guido = new SoftwareDeveloper('Python');
const Dennis = new SoftwareDeveloper();
Brendan.writeMessageInChat(); // My favorite programming language is JavaScript!
Guido.writeMessageInChat(); // My favorite programming language is Python!
Dennis.writeMessageInChat(); // My favorite programming language is C!
👉 What is a factory pattern?
Factory pattern uses factory functions to create objects instead of a class.
Simply put, a factory is just a function, that returns an object.
So, let's re-implement the exact same behavior using a factory function.
const SoftwareDeveloper = (language) => {
const lang = language || 'C';
return ({
writeMessageInChat: () => {
console.log(`My favorite programming language is ${lang}!`);
}
})
}
const Brendan = SoftwareDeveloper('JavaScript');
const Guido = SoftwareDeveloper('Python');
const Dennis = SoftwareDeveloper();
Brendan.writeMessageInChat(); // My favorite programming language is JavaScript!
Guido.writeMessageInChat(); // My favorite programming language is Python!
Dennis.writeMessageInChat(); // My favorite programming language is C!
👉 How to use it like a top-performer?
The factory pattern is very useful when you need to create a lot of objects, where some of the properties are the same.
That's exactly what React developers do in the createFactory
function.
/**
* Return a function that produces ReactElements of a given type.
* See https://reactjs.org/docs/react-api.html#createfactory
*/
export function createFactory(type) {
const factory = createElement.bind(null, type);
factory.type = type;
return factory;
}
// Example
import React from 'react';
const div = React.createFactory('div');
div(null, 'First div');
div(null, 'Second div');
div(null, 'Third div');
👉 Why is it legacy?
React v0.11 created a factory internally to deal with encapsulated components.
But this model was eventually considered conceptually wrong.
So the createFactory
function was introduced in React v0.12 to fix this issue.
// You write this
var Item = React.createClass(...)
// React v0.11 does this internally
class ItemClass {
}
function ItemFactory(...args) {
return React.createElement(ItemClass, ...args);
}
module.exports = ItemFactory;
// And you use it straight away
var Item = require('Item');
class App {
render() {
return Item({ text: 'Hello world!'});
}
}
// Or with JSX
var Item = require('Item');
class App {
render() {
return <Item text="Hello world!" />;
}
}
👉 React v0.12
The createFactory
function was a way to create components without creating an extra factory internally.
Simply put, React devs move the createFactory
from inside React.createClass
to the consuming module.
// You write this
var Item = React.createClass(...)
// React v0.12 do this internally
class Item {
}
module.exports = Item;
// But you need to call createFactory yourself
var Button = React.createFactory(require('Item'));
class App {
render() {
return Item({ text: 'Hello world!'});
}
}
// Or just let JSX do its job
var Item = require('Item');
class App {
render() {
return <Item text="Hello world!" />;
}
}
In the current state, React doesn't need the createFactory
function, because it deals with components without an extra factory.
P.S. Follow me on Twitter for more content like this!
Top comments (1)
You can find more info on this here.