Паттерн Revealing Constructor (открытый конструктор) — это подход, когда конструктор класса принимает функцию, которой раскрываются приватные методы/данные, позволяя инициализировать объект с контролируемым доступом к его внутренностям.
Характеристики:
const promise = new Promise((resolve, reject) => {
// Здесь доступны только resolve/reject
setTimeout(() => resolve('Done'), 100);
});
// Снаружи нет доступа к resolve/reject
Некоторые реализации позволяют создавать эмиттеры с контролируемыми правами:
const { EventEmitter } = require('events');
class ControlledEmitter {
constructor(executor) {
const emitter = new EventEmitter();
executor({
emit: emitter.emit.bind(emitter),
addListener: emitter.on.bind(emitter)
});
this.emitter = emitter;
}
}
const ce = new ControlledEmitter(({ emit }) => {
emit('data', 'secret'); // Доступно только при создании
});
При создании кастомных стримов:
const { Writable } = require('stream');
const ws = new Writable({
write(chunk, encoding, callback) {
// Этот метод доступен только внутри конструктора
console.log(chunk.toString());
callback();
}
});
При создании воркера:
const { Worker } = require('worker_threads');
const worker = new Worker(`
const { parentPort } = require('worker_threads');
parentPort.on('message', (msg) => {
// Обработчик доступен только при создании
});
`, { eval: true });
В кластерном API:
const cluster = require('cluster');
if (cluster.isMaster) {
const worker = cluster.fork();
// worker.exposedMethod доступен только в этом контексте
}
Рассмотрим упрощенную реализацию:
class SecureContainer {
#secret = 42; // Приватное поле
constructor(executor) {
const controller = {
getSecret: () => this.#secret,
setSecret: (val) => { this.#secret = val; }
};
executor(controller); // Открываем API только на этапе построения
}
get publicValue() {
return this.#secret / 2;
}
}
const instance = new SecureContainer(({ setSecret }) => {
setSecret(100); // Можно установить только при создании
});
console.log(instance.publicValue); // 50
console.log(instance.#secret); // SyntaxError: Private field must be declared in an enclosing class
Контролируемая инициализация:
Безопасность:
Гибкость:
Revealing Constructor широко используется в Node.js для:
Promise
)EventEmitter
)stream.Writable
)Ключевые особенности:
Где искать:
Promise
, Worker
)Паттерн особенно полезен в API, где важно ограничить доступ к критически важным методам после инициализации объекта.