Приклади практичних об'єктно-орієнтованих шаблонів дизайну JavaScript


81

Які об’єктно-орієнтовані шаблони дизайну ви використовуєте в javascript вашої програми та чому?

Не соромтеся надсилати поштовий індекс, навіть якщо до нього не додається офіційний шаблон дизайну.

Я написав багато javascript, але я не застосовував багато об'єктно-орієнтованих шаблонів до того, що я роблю, і я впевнений, що мені багато чого не вистачає.


Ви, мабуть, не бачили класичного ООП у тому сенсі, що можете подумати. Однак ви, напевно, використовували функції прототипу ООП і просто ніколи цього не усвідомлювали.
dave

Я насправді (іноді) усвідомлюю, коли використовую ООП - я хочу почати використовувати ООП набагато свідоміше, саме тому, що хочу бути набагато обдуманішим щодо цього
ming yeow

Я голосую за те, щоб закрити це питання як нетематичне, оскільки воно просто вимагає переліку речей, які інші люди роблять у своєму коді.
Альмо,

Відповіді:


54

Далі подано три популярні шаблони JavaScript. Ці випадки легко реалізуються через закриття :

Ви також можете перевірити:

Далі йде виступ Google I / O за 2008 рік, представлений Діасом, де він обговорює деякі теми зі своєї книги:


приємно! каррі виглядає набагато розумнішим способом узагальнення, яке я намагався зробити. вже використовую прості форми модулів та мемоїзування - але потрібно вивчити ці приклади, щоб продемонструвати, як я зараз це роблю. Які з них ви використовуєте найбільше?
ming yeow

@ming: Можливо, це шаблон модуля. Дуже легко впровадити та зрозуміти, і він має деякі цікаві функції, включаючи простору імен та приватні змінні / методи.
Даніель Вассалло,

26

Спадщина

Я використовую позначення для успадкування, яке базується на ExtJS 3 , який, на мою думку, працює досить близько до емуляції класичного успадкування в Java. В основному це працює наступним чином:

// Create an 'Animal' class by extending
// the 'Object' class with our magic method
var Animal = Object.extend(Object, {
    move : function() {alert('moving...');}
});

// Create a 'Dog' class that extends 'Animal'
var Dog = Object.extend(Animal, {
    bark : function() {alert('woof');}
});

// Instantiate Lassie
var lassie = new Dog();

// She can move and bark!
lassie.move();
lassie.bark();

Простори імен

Я також погоджуюсь з Еріком Міраглією щодо дотримання просторів імен, тому наведений вище код слід запускати у власному контексті поза об'єктом вікна, це критично важливо, якщо ви плануєте запустити свій код як одну з багатьох одночасних фреймворків / бібліотек, що виконуються у вікні браузера.

Це означає, що єдиний шлях до об’єкта вікна - через власний простір імен / об’єкт модуля:

// Create a namespace / module for your project
window.MyModule = {};

// Commence scope to prevent littering 
// the window object with unwanted variables
(function() {

    var Animal = window.MyModule.Animal = Object.extend(Object, {
         move: function() {alert('moving...');}
    });

    // .. more code

})();

Інтерфейси

Ви також можете використовувати більше досягнень конструкцій ООП, таких як інтерфейси, щоб покращити дизайн вашого додатка. Мій підхід до них полягає в тому, щоб покращити Function.prototype, щоб отримати позначення в таких напрямках:

var Dog = Object.extend(Animal, {
     bark: function() {
         alert('woof');
     }
     // more methods ..
}).implement(Mammal, Carnivore);

ОО Шаблони

Що стосується "Шаблонів" у розумінні Java, я знайшов застосування лише для шаблону Singleton (чудово підходить для кешування) та шаблону Observer для керованих подіями функціональних можливостей, таких як призначення деяких дій, коли користувач натискає кнопку.

Прикладом використання шаблону спостерігача може бути:

// Instantiate object
var lassie = new Animal('Lassie');

// Register listener
lassie.on('eat', function(food) {
   this.food += food;
});

// Feed lassie by triggering listener
$('#feeding-button').click(function() {
    var food = prompt('How many food units should we give lassie?');
    lassie.trigger('eat', [food]);
    alert('Lassie has already eaten ' + lassie.food + ' units');
});

І це лише декілька хитрощів у моїй торбинці OO JS, сподіваюся, вони стануть вам у нагоді.

Якщо ви збираєтеся піти цією дорогою, я рекомендую вам прочитати Javascript Дугласа Крокфордса : Гарні частини . Це чудова книга для цього.


20

Я є шанувальником модульної схеми . Це спосіб реалізації розширюваних, незалежних (більшу частину часу) рамок.

Приклад:

Фреймворк Q,, визначається так:

var Q = {};

Щоб додати функцію:

Q.test = function(){};

Ці два рядки коду використовуються разом для формування модулів . Ідея, що стоїть за модулями, полягає в тому, що всі вони розширюють деяку базову структуру, в даному випадку Q, але не залежать один від одного (якщо правильно розроблені) і можуть бути включені в будь-якому порядку.

У модулі ви спочатку створюєте фреймворковий об'єкт, якщо він не існує (що є прикладом шаблону Singleton ):

if (!Q)
    var Q = {};

Q.myFunction = function(){};

Таким чином, ви можете мати кілька модулів (наприклад, наведений вище) в окремих файлах та включати їх у будь-якому порядку. Будь-який із них створить об’єкт фреймворку, а потім розширить його. Жодне керівництво не повинно перевіряти, чи існує система. Потім, щоб перевірити, чи існує модуль / функція у власному коді:

if (Q.myFunction)
    Q.myFunction();
else
    // Use a different approach/method

1
Це виглядає надзвичайно корисно. як ти використовуєш це у своєму коді? Дякую, що поділились!
ming yeow

Я використав його в недавньому проекті, який я робив, де мав окремі файли JavaScript для загальних функцій, інтерфейсу користувача та двох інших спеціалізованих механізмів. Усі файли додали функції до одного і того ж фреймворку (визначеного за допомогою методу, який я показав вище), і вони викликали функції, як це було зроблено вище.
Chris Laplante,

Одним з основних напрямків використання цього типу техніки є уникнення забруднення глобального простору імен. Що забруднює більше? Єдина Qзмінна фреймворка, або десятки і десятки функцій та змінних?
Chris Laplante,

6

Шаблон синглтона часто дуже корисний для "інкапсуляції" та організації. Ви навіть можете змінити доступність.

var myInstance = {
  method1: function () {
    // ...
  },
  method2: function () {
    // ...
  }
};

найчистіший спосіб реалізації синглтона в javascript


чудово - це той, яким я користуюсь постійно! Але це приблизно обсяг мого javascript OO. ;)
ming yeow

4

Мені дуже подобається шаблон ланцюжка методів jquery , що дозволяє викликати кілька методів для одного об'єкта. Це робить дуже простим виконання декількох операцій в одному рядку коду.

Приклад:

$('#nav').click(function() {
   $(this).css('color','#f00').fadeOut();
});

правильно - погодився! ви розробляли власні власні методи, які працюють таким чином раніше?
ming yeow

3

Мені дуже подобається шаблон "Декоратор" із плагінами jQuery. Замість того, щоб модифікувати плагіни відповідно до ваших потреб, напишіть власний плагін, який просто пересилає запити та додає додаткові параметри та функціональність.

Наприклад, якщо вам потрібно постійно передавати набір аргументів за замовчуванням, і вам потрібна дещо інша поведінка, яка пов’язана з бізнес-логікою, напишіть плагін, який робить все, що потрібно, preі postпрацює, що відповідає вашим потребам, і передає ваші аргументи за замовчуванням. якщо ці конкретні аргументи не вказані.

Основна перевага цього полягає в тому, що ви можете оновлювати свої бібліотеки і не турбуватися про перенесення змін бібліотеки. Ваш код може зламатися, але є принаймні шанс, що він цього не зробить.


Це звучить як чудова ідея. Чи є у вас фактичний приклад коду для фактичного розширення? Навіть простий приклад дуже допоможе кожному.
ming yeow

3

Одним з корисних шаблонів у світі javascript є ланцюговий шаблон, який спочатку популярний у LINQ, а також використовується в jQuery.

цей шаблон дозволяє нам називати різні методи класу ланцюговим способом.

головною структурою цього шаблону буде така

var Calaculator = function (init) {
    var result = 0;
    this.add = function (x) { result += (init + x); return this; };
    this.sub = function (x) { result += (init - x); return this; };
    this.mul = function (x) { result += (init * x); return this; };
    this.div = function (x) { result += (init / x); return this; };

    this.equals = function (callback) {
        callback(result);
    }

    return this;
};


new Calaculator(0)
    .add(10)
    .mul(2)
    .sub(5)
    .div(3)
    .equals(function (result) {
        console.log(result);
    });

ключовою ідеєю цього шаблону є thisключове слово, що робить можливим доступ до іншого публічного члена функції Калькулятора.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.