Я работаю над примером шаблона проектирования для шаблона Observer в книге Адди Османи «Шаблоны проектирования JavaScript». Мой вопрос: почему важно, чтобы в его реализации шаблона было столько уровней абстракции?JavaScript: Почему так много абстракции/взаимодействия в шаблоне наблюдателей Адди?
Например, в его примере, просто добавить наблюдатель («толчок» наблюдатель на массив), это включает в себя:
- с использованием нативного
push()
метода. - создание
ObjectList.add()
метод. - Наследование/расширение объекта
ObjectList
с объектомSubject
. - , создающий метод
Subject.addObserver()
, который будет использоваться в качестве интерфейса, но который использует метод под капотом. - расширение метода
Subject.addObserver()
для новых объектов. - Реализация его путем вызова метода
addObserver()
на недавно расширенном объекте.
Вот пример кода для шаблона дизайна во всей своей полноте:
function ObserverList(){
this.observerList = [];
}
ObserverList.prototype.add = function(obj){
return this.observerList.push(obj);
};
ObserverList.prototype.count = function(){
return this.observerList.length;
};
ObserverList.prototype.get = function(index){
if(index > -1 && index < this.observerList.length){
return this.observerList[ index ];
}
};
ObserverList.prototype.indexOf = function(obj, startIndex){
var i = startIndex;
while(i < this.observerList.length){
if(this.observerList[i] === obj){
return i;
}
i++;
}
return -1;
};
ObserverList.prototype.removeAt = function(index){
this.observerList.splice(index, 1);
};
function Subject(){
this.observers = new ObserverList();
}
Subject.prototype.addObserver = function(observer){
this.observers.add(observer);
};
Subject.prototype.removeObserver = function(observer){
this.observers.removeAt(this.observers.indexOf(observer, 0));
};
Subject.prototype.notify = function(context){
var observerCount = this.observers.count();
for(var i=0; i < observerCount; i++){
this.observers.get(i).update(context);
}
};
// The Observer
function Observer(){
this.update = function(){
// ...
};
}
А вот реализация/использование:
HTML
<button id="addNewObserver">Add New Observer checkbox</button>
<input id="mainCheckbox" type="checkbox"/>
<div id="observersContainer"></div>
Script
// Extend an object with an extension
function extend(extension, obj){
for (var key in extension){
obj[key] = extension[key];
}
}
// References to our DOM elements
var controlCheckbox = document.getElementById("mainCheckbox"),
addBtn = document.getElementById("addNewObserver"),
container = document.getElementById("observersContainer");
// Concrete Subject
// Extend the controlling checkbox with the Subject class
extend(new Subject(), controlCheckbox);
// Clicking the checkbox will trigger notifications to its observers
controlCheckbox.onclick = function(){
controlCheckbox.notify(controlCheckbox.checked);
};
addBtn.onclick = addNewObserver;
// Concrete Observer
function addNewObserver(){
// Create a new checkbox to be added
var check = document.createElement("input");
check.type = "checkbox";
// Extend the checkbox with the Observer class
extend(new Observer(), check);
// Override with custom update behaviour
check.update = function(value){
this.checked = value;
};
// Add the new observer to our list of observers
// for our main subject
controlCheckbox.addObserver(check);
// Append the item to the container
container.appendChild(check);
}
Теперь я сравнил его реализацию с другими реализациями одного и того же шаблона (книги и блоги). И кажется, что Адди добавляет тонну больше абстракции, чем другие разработчики шаблона наблюдателя. Вопрос в том, почему? Не удалось ли это реализовать проще, наследуя от объекта ObserverList
? Достигает ли это большей степени развязки, делая это так, как делает Адди? Если да, то как это? Не создает ли шаблон дизайна развязку? Кажется, что объект Subject
приносит много ненужного кода.
Объект 'Subject' здесь - это еще один код, который вам нужен. Мне кажется, что он может либо наследоваться от «ObserverList», либо может содержать общедоступный «ObserverList», а затем в таких случаях ему не нужно было бы определять совершенно новый интерфейс наблюдателя и переопределять целую кучу уже существующих методов в объекте 'ObserverList'. – jfriend00
Этот вопрос кажется дискуссионным вопросом + Первичный вопрос для меня. –
@ jfriend00: Я думаю, что этот вопрос лучше всего подходит для SO, поскольку он относится к пониманию существенной «теории» того, как этот шаблон дизайна реализован в JS в том, что считается фундаментальной/авторитетной книгой по этому вопросу. Это не просто произвольный блок кода, требующий оптимизации. – shmuli