Шаблоны проектирования в JavaScript
Шаблоны проектирования помогают сделать код более чистым, понятным и DRY. DRY это аббревиатура означает “don’t repeat yourself” (не повторяйся). В этой статье я описал наиболее популярные шаблоны проектирования в JavaScript.
Фабричный метод/функция (Factory Pattern/Functions)
Фабричная функция это просто функция которая возвращает объект. Этот шаблон удобен тем что не требует дополнительного метода для инициализации объекта как это обычно делается в конструкторе. Шаблон является хорошим примером функционального программирования в JavaScript. Например библиотека jQuery построена на использование фабричных функций.
Одной из главных особенностей этого шаблона определение внутри функции приватных переменных и методов. Для этого достаточно просто исключить их из возвращяемого объекта, но при этом они могут быть доступными через сформированные «замыкания».
function Person(name){ function walk(){ console.log(name+" is walking"); } return{ name : name, talk: function(){ console.log("My name is "+ this.name); } } } var person = Person("Ram"); person.talk(); // output : My name is Ram person.walk(); // TypeError: person.walk is not a function /** walk is private as it is not inside returned function **/
Фабрика с Композицией (Factory with Composition)
Этот шаблон используется для назначения поведений объектам когда нужно избегать нежелательного наследования.
/** Behaviour factories **/ var drinks = function Drinks(type){ var drink_type = type || 'Water'; return { startDrink: function(){ console.log("Start to drink "+ drink_type); } } } var eat = function Eat(type){ var eat_type = type || 'Rice'; return { startEat: function(){ console.log("Start to eat "+ eat_type); } } } /** Object factories **/ var person = function (drink, food) { return Object.assign( {}, drinks(drink), eat(food) ); // Merge our 'behaviour' objects }; var person = person('Wine', 'Noodles'); person.startDrink(); //"Start to drink Wine" person.startEat(); //"Start to eat Noodles"
Шаблон Модуль (Module Pattern)
Шаблон Module — это порождающий шаблон, инкапсулирующий приватную информацию, методы и переменные, используя замыкания. Он позволяет оборачивать публичные и приватные методы в модули, и тем самым избегать их попадание в глобальный контекст, где они могут конфликтовать с интерфейсами других разработчиков.
var Module = (function(num) { // Private data is stored within the closure var privateNum = 1; // Because the function is immediately invoked, // the return value becomes the public API var api = { getPrivateData: function() { return privateNum; }, getDoublePrivateData: function() { return api.getPrivateData() * num; } }; return api; })(2); var num = Module.getPrivateData(); console.log(num); //1 var num = Module.getDoublePrivateData(); console.log(num); // 2 view raw
Прототип (Prototype Pattern)
Шаблон предназначен для создания объекта, который можно использовать в качестве основы для других объектов посредством наследования прототипа. С этим шаблоном легко работать и он очень популярен в JavaScript из-за встроенной поддержки наследования прототипов в JS.
function Welcome(name) { this.name = name; } Welcome.prototype.sayHello = function() { return 'Hello, ' + this.name + '!'; } var welcome = new Welcome('Shyam'); var output = welcome.sayHello(); console.log(output); //"Hello, Shyam!"
Сингельтон (Singleton Pattern)
Шаблон Singleton — ограничивает создание экземпляра класса одним объектом. После создания первого объекта он будет возвращать ссылку на тот же объект всякий раз, когда будет вызывается инициализация нового.
var Singleton = (function() { // instance stores a reference to the Singleton var instance; function createInstance() { // private variables and methods var _privateVariable = 'I am a private variable'; function _privateMethod() { console.log('I am a private method'); } return { // public methods and variables publicMethod: function() { console.log('I am a public method'); }, publicVariable: 'I am a public variable' }; } return { // Get the Singleton instance if it exists // or create one if doesn't getInstance: function() { if (!instance) { instance = createInstance(); } return instance; } }; })(); // there is no existing instance of Singleton, so it will create one var instance1 = Singleton.getInstance(); // there is an instance of Singleton, so it will return the reference to this one var instance2 = Singleton.getInstance(); console.log(instance1 === instance2); // true instance2.publicMethod(); //'I am a public method'
Абстрактная фабрика (Abstract Factory Pattern)
Шаблон абстрактной фабрики — это еще один порождающий шаблон, который можно использовать для определения взаимосвязанных экземпляров или объектов не специфицируя их конкретных классов.
function Car() { this.name = "Car"; this.wheels = 4; } function Tractor() { this.name = "Tractor"; this.wheels = 4; } function Bike() { this.name = "Bike"; this.wheels = 2; } const vehicleFactory = { createVehicle: function(type) { switch (type.toLowerCase()) { case "car": return new Car(); case "tractor": return new Tractor(); case "bike": return new Bike(); default: return null; } } }; var car = vehicleFactory.createVehicle("Car"); console.log(car); // Car { name: "Car", wheels: 4 }
Прикольная статья