Синглтон шаблон | Заводской узор | Шаблон конструктора
Темы
- Синглтон шаблон
- Заводской узор
- Заводской шаблон против шаблона конструктора
Шаблон Singleton (использует Redux или React Context)
- Шаблон проектирования Singleton предоставляет один экземпляр, который может использоваться несколькими компонентами.
- Singleton Pattern можно считать основой глобальных библиотек управления состоянием, таких как Redux или React Context.
- Это шаблон, который ограничивает класс созданием только одного экземпляра.
- К ним можно получить глобальный доступ, и они действуют как единая точка доступа для доступа к глобальному состоянию.
let instance; let globalState = { color: "" }; class StateUtility { constructor() { if (instance) { throw new Error("New instance cannot be created!!"); } instance = this; } getPropertyByName(propertyName) { return globalState[propertyName]; } setPropertyValue(propertyName, propertyValue) { globalState[propertyName] = propertyValue; } } let stateUtilityInstance = Object.freeze(new StateUtility()); export default stateUtilityInstance;
- Мы следим за тем, чтобы не раскрывать файл
globalState
. Мы раскрываем их, используя методы классаStateUtility
. Таким образом, мы защищаем глобальное состояние от прямого изменения. - Наконец, мы создаем экземпляр класса следующим образом:
let stateUtilityInstance = Object.freeze(new StateUtility());
. - Мы использовали
Object.freeze
, чтобы ни один другой класс/компонент/модуль не мог изменить открытыйstateUtilityInstance
.
Заводской шаблон (Заводской шаблон против конструкторов) —
- Фабрика — это объект, класс или функция в парадигме функционального программирования для создания объектов.
- Фабричный методсоздает новые объекты в соответствии с указаниями клиента. Одним из способов создания объектов в JavaScript является вызов функции-конструктора с оператором new.
- Шаблон проектирования Factory используется, когда у нас есть суперкласс с несколькими подклассами, и на основе входных данных нам нужно вернуть один из подклассов. Этот шаблон снимает с себя ответственность за создание экземпляра класса из клиентской программы в класс фабрики.
- Классы делегируют ответственность одному из нескольких вспомогательных подклассов, и вы хотите локализовать знания о том, какой вспомогательный подкласс является делегатом.
- Фабричные методы часто используются в приложениях, которые управляют, поддерживают или манипулируют наборами объектов, которые отличаются друг от друга, но в то же время имеют много общих характеристик (т. е. методов и свойств).
- Фабричный шаблон может использовать внутри конструктор или класс. Но фабричный шаблон предпочтительнее в тех случаях, когда процесс создания объекта зависит от динамических факторов, например, когда мы хотим динамически создавать подклассы.
- Factory предоставляет нам гибкий и многоразовый механизм создания объектов.
// creates factory function function vehicleFactory (manufacturer, plateNO) { return { manufacturer, plateNO, startEngine () { console.log("reving engine") }, drive () { console.log("driving car...") } } } const Vehicle1 = vehicleFactory("Toyota", 12345); console.log(Vehicle1) // prints //{ // manufacturer: 'Toyota', // plateNO: 12345, // startEngine: [Function: startEngine], // drive: [Function: drive] //} const Vehicle2 = vehicleFactory("Ford", 13345); console.log(Vehicle2) // prints // { // manufacturer: 'Ford', // plateNO: 13345, // startEngine: [Function: startEngine], // drive: [Function: drive] // }
Примеры,
- Фабричный шаблон способствует повторному использованию кода за счет повторного использования методов
StartEngine
,driveVehicle
иstopEngine
.
class Car { constructor(options) { this.wheels = options.wheels || 4; this.doors = options.doors || 4; this.color = options.color || "silver"; } } class Truck { constructor(options) { this.wheels = options.wheels || 6; this.doors = options.doors || 2; this.color = options.color || "red"; } } class Factory { create = (options, vehicleType) => { if(!vehicleType) { return "unable to make vehicle. Please specify a vehicle type and tryagain!" } let vehicle; if (vehicleType === "car") { vehicle = new Car(options); } else if (vehicleType === "truck") { vehicle = new Truck(options); } vehicle.vehicleType = vehicleType; vehicle.startEngine = ()=> console.log(`Reving ${vehicleType} engine`); vehicle.driveVehicle = ()=> console.log(`Driving ${vehicleType}...`); vehicle.stopEngine = ()=> console.log(`Stop ${vehicleType} engine`); return vehicle; } }; const vehicleFactory = new Factory(); const car = vehicleFactory.create({ wheels: 4, doors: 2, color: "black", }, "car"); console.log(car) console.log(car.startEngine()) console.log(car.driveVehicle()) // prints: //Car { // wheels: 4, // doors: 4, // color: 'silver', // vehicleType: 'car', // startEngine: [Function], // driveVehicle: [Function], // stopEngine: [Function] //} // Reving car engine // Driving car... const truck = vehicleFactory.create({ wheels: 4, doors: 2, color: "yellow", }, "truck") console.log(truck) console.log(truck.startEngine()) console.log(truck.stopEngine()) // prints //Truck { // wheels: 4, // doors: 2, // color: 'yellow', // vehicleType: 'truck', // startEngine: [Function], // driveVehicle: [Function], // stopEngine: [Function] //} // Reving truck engine // Stop truck engine
- Благодаря шаблону factory наш код также легко поддерживать, поэтому, если бизнес расширяется и завод начинает производить новые виды транспортных средств, мы можем легко изменить нашу реализацию, чтобы справиться с этим, как показано ниже:
class Car { constructor(options) { this.wheels = options.wheels || 4; this.doors = options.doors || 4; this.color = options.color || "silver"; } } class Truck { constructor(options) { this.wheels = options.wheels || 6; this.doors = options.doors || 2; this.color = options.color || "red"; } } class Bus { constructor(options) { this.wheels = options.wheels || 4; this.doors = options.doors || 4; this.color = options.color || "white"; } } class Motorcycle { constructor(options) { this.wheels = options.wheels || 2; this.doors = options.doors || 0; this.color = options.color || "Black"; } } class Factory { create = (options, vehicleType) => { if(!vehicleType) { return "unable to make vehicle. Please specify a vehicle type and tryagain!" } let vehicle; if (vehicleType === "car") { vehicle = new Car(options); } else if (vehicleType === "truck") { vehicle = new Truck(options); } else if (vehicleType === "bus") { vehicle = new Bus(options); } else if (vehicleType === "motorcycle") { vehicle = new Motocycle(options); } vehicle.vehicleType = vehicleType; vehicle.startEngine = ()=> console.log(`Reving ${vehicleType} engine`); vehicle.driveVehicle = ()=> console.log(`Driving ${vehicleType}...`); vehicle.stopEngine = ()=> console.log(`Stop ${vehicleType} engine`); return vehicle; } }; const vehicleFactory = new Factory(); const bus = vehicleFactory.create({ wheels: 4, doors: 4, color: "yellow", }, "bus"); console.log(bus) console.log(bus.startEngine()) console.log(bus.driveVehicle()) // prints: // Bus { // wheels: 4, // doors: 4, // color: 'yellow', // vehicleType: 'bus', // startEngine: [Function], // driveVehicle: [Function], // stopEngine: [Function] //} // Reving bus engine // Driving bus... const bike = vehicleFactory.create({ wheels: 2, doors: 0, color: "red", }, "motorcycle") console.log(bike) console.log(bike.startEngine()) console.log(bike.stopEngine()) // prints // Motorcycle { // wheels: 2, // doors: 0, // color: 'red', // vehicleType: 'bike', // startEngine: [Function], // driveVehicle: [Function], // stopEngine: [Function] //} // Reving motorcycle engine // Stop motorcycle engine
Больше примеров,
var Factory = function () { this.createEmployee = function (type) { var employee; if (type === "fulltime") { employee = new FullTime(); } else if (type === "parttime") { employee = new PartTime(); } else if (type === "temporary") { employee = new Temporary(); } else if (type === "contractor") { employee = new Contractor(); } employee.type = type; employee.say = function () { console.log(this.type + ": rate " + this.hourly + "/hour"); } return employee; } } var FullTime = function () { this.hourly = "$12"; }; var PartTime = function () { this.hourly = "$11"; }; var Temporary = function () { this.hourly = "$10"; }; var Contractor = function () { this.hourly = "$15"; }; function run() { var employees = []; var factory = new Factory(); employees.push(factory.createEmployee("fulltime")); employees.push(factory.createEmployee("parttime")); employees.push(factory.createEmployee("temporary")); employees.push(factory.createEmployee("contractor")); for (var i = 0, len = employees.length; i < len; i++) { employees[i].say(); } }
Заводской шаблон против конструкторов
- Шаблон конструктора и шаблон фабрики похожи, поскольку это шаблоны создания объектов, возвращающие новый объект.
- Метод Factory может возвращать уже созданный объект, в отличие от конструктора, который всегда создает новый экземпляр.
- Фабричные методы продвигают идею кодирования с использованием интерфейса, а затем реализации, что приводит к более гибкому коду, но конструктор привязывает ваш код к конкретной реализации.
- Причины использования конструкторов: мы используем конструкторы для инициализации объекта с состоянием по умолчанию или начальным состоянием. Значения по умолчанию для примитивов могут не соответствовать вашим требованиям. Другая причина использования конструктора заключается в том, что он информирует о зависимостях.
- Причина использования Factory: шаблон метода Factory позволяет подклассам выбирать тип создаваемых объектов. Это способствует слабой связи, устраняя необходимость привязки классов, специфичных для приложения, к коду.
const vehicleOptions = {type: "cars", color: "white", doors: 4, wheels: 4} // factory pattern function Factory(options) { let factory = {}; factory.type = options.type; factory.color = options.color; factory.wheels = options.wheels; factory.doors = options.doors; return factory; } const vehicle = Factory(vehicleOptions); // constructor pattern function ConstructorPattern(options) { this.type = options.type; this.color = options.color this.doors = options.doors; this.wheels = options.wheels; } const vehicle2 = new ConstructorPattern(vehicleOptions); console.log("factory car", vehicle) // prints { type: 'cars', color: 'white', wheels: 4, doors: 4 } console.log("constructor car", vehicle2) // prints { type: 'cars', color: 'white', wheels: 4, doors: 4 }
Когда использовать заводской шаблон
Шаблон Factory может быть особенно полезен при применении в следующих ситуациях:
- Когда настройка нашего объекта или компонента связана с высоким уровнем сложности.
- Когда нам нужно легко генерировать разные экземпляры объектов в зависимости от среды, в которой мы находимся.
- Когда мы работаем со многими небольшими объектами или компонентами, которые имеют одни и те же свойства.
- При составлении объектов с экземплярами других объектов, которым для работы нужно только соответствие контракту API (он же утиный ввод). Это полезно для развязки.
Спасибо за прочтение
- 👏 Пожалуйста, хлопайте в историю и подписывайтесь на меня 👉
- 📰 Посмотреть больше материалов на Интервью по кодированию и проектированию систем
- 🔔 Подпишитесь на меня: LinkedIn!
Я знаю, что всегда есть что улучшить. Пожалуйста, поделитесь своими мыслями
🚀👉 Присоединяйтесь к коллективу талантов Level Up и найдите потрясающую работу