Шаблоны проектирования в JavaScript

Spread the love

Шаблоны проектирования помогают сделать код более чистым, понятным и 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 }
Была ли вам полезна эта статья?
[11 / 2.1]

Spread the love
Подписаться
Уведомление о
guest
1 Комментарий
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Анонимно
Анонимно
1 год назад

Прикольная статья

Last edited 1 год назад by Анонимно