Using subtype polymorphism doesn't remove conditional constructs completely (except in some cases of dispatching, such as by key or filename). More often, the conditional construct is left alone, only at the level of selecting a suitable implementation, but then that implementation is used within the polymorphic function in a direct way without conditions. In the last lesson, we looked at an example function that selects the desired way of implementing the strategy based on the user's age and returns it.
const chooseCostInsuranceStrategy = (user) => {
if (user.getAge() < 18) {
return new LessThan18();
} else if (/* ... */) {
// some code
}
}
A function that selects the desired class, creates the object, and returns it is called a factory (more precisely, a factory method). A big name for a very simple thing. A factory can be implemented in any way, including all the methods we've looked at this course.
In general, a factory is anything that creates an object or collections of objects. Not necessarily different classes, there could even be only one class, but the creation process involves some preliminary calculations. In real projects, factories can be quite large.
Factories are often implemented as classes with a single static method, called, naturally, factory
. Factories themselves don't make objects (although sometimes they do), because it's not an abstraction of data, and it makes no sense to substitute them. Otherwise, you'll get substitutes for substitutes.
export default class {
static factory(/* parameters */) {
// factory code
}
}
JavaScript allows you to create objects using a reference to a class
const className = Application;
const app = new className();
This syntax gives you great scope for dispatching. For example, in some situations it'll be possible to get away from the conditional structures completely:
import ManagerPolicy from './policies/ManagerPolicy.js';
import WorkerPolicy from './policies/WorkerPolicy.js';
// Policy - this name is usually used for authorization, i.e., by the system for checking access rights
const mapping = {
manager: ManagerPolicy,
worker: WorkerPolicy,
};
const getUserPolicy = (user) => {
const className = mapping[user.getType()];
return new className();
};
The Hexlet support team or other students will answer you.
A professional subscription will give you full access to all Hexlet courses, projects and lifetime access to the theory of lessons learned. You can cancel your subscription at any time.
Programming courses for beginners and experienced developers. Start training for free
Our graduates work in companies:
From a novice to a developer. Get a job or your money back!
Sign up or sign in
Ask questions if you want to discuss a theory or an exercise. Hexlet Support Team and experienced community members can help find answers and solve a problem.