Чтение онлайн

на главную - закладки

Жанры

JavaScript. Подробное руководство, 6-е издание
Шрифт:

proto.constructor = constructor; proto.add = function {

// Примерить фильтр ко всем аргументам перед добавлением

for(var і = 0; і < arguments.length; i++) {

var v = arguments[i];

if (!filter(v)) throw("значение + v + отвергнуто фильтром");

}

// Вызвать реализацию метода add из базового класса

superclass.prototype.add.apply(this, arguments);

};

return constructor;

}

В примере 9.14 есть один интересный момент, который хотелось бы отметить. Он заключается в том, что, обертывая операцию создания подкласса функцией, мы получаем возможность использовать аргумент

superclass
в вызовах конструктора и метода базового класса и избежать указания фактического имени суперкласса. Это означает, что в случае изменения имени суперкласса достаточно будет изменить имя в одном месте, а не отыскивать все его упоминания в программном коде. Такого способа стоит придерживаться даже в случаях, не связанных с определением фабричных функций. Например, с помощью функции-обертки можно было бы переписать определение класса
NonNullSet
и метода
Function.prototype.extend
(пример 9.11), как показано ниже:

var NonNullSet = (function { // Определить и вызвать функцию

var superclass = Set; // Имя суперкласса указывается в одном месте,

return superclass.extend(

function { superclass.apply(this, arguments); }, // конструктор

{ // методы

add: function {

// Проверить аргументы на равенство null или undefined

for(var і = 0; і < arguments.length; i++)

if (arguments[i] == null)

throw new Еrror("Нельзя добавить null или undefined");

// Вызвать метод базового класса, чтобы выполнить добавление

return superclass.prototype.add.apply(this, arguments);

}

});

});

В заключение хотелось бы подчеркнуть, что возможность создания подобных фабрик классов обусловлена динамической природой языка JavaScript. Фабрики классов представляют собой мощный и гибкий инструмент, не имеющий аналогов в языках, подобных Java и C++.

9.7.3. Композиция в сравнении с наследованием

В предыдущем разделе мы решили определить класс множеств, накладывающий ограничения на свои элементы в соответствии с некоторыми критериями, а для достижения поставленной цели использовали механизм наследования, определив функцию создания специализированного подкласса указанной реализации множества, использующего указанную функцию-фильтр для ограничения круга допустимых элементов множества. При таком подходе для каждой комбинации суперкласса и функции-фильтра необходимо создавать новый класс.

Однако существует более простой путь решения этой задачи. В объектно-ориентированном программировании существует известный принцип «предпочтения композиции перед наследованием». [18]

В данном случае применение приема композиции могло бы выглядеть как реализация нового множества, «обертывающего» другой объект множества и делегирующего ему все обращения после фильтрации нежелательных элементов. Пример 9.15 демонстрирует, как это реализовать.

Пример 9.15. Композиция множеств вместо наследования

18

См. Э. Гамма и др. «Приемы объектно-ориентированного проектирования. Паттерны проектирования» или Дж. Блох «Java. Эффективное программирование».

/*

* Объект FilteredSet обертывает указанный объект множества и применяет

* указанный фильтр в своем методе add. Обращения ко всем остальным базовым

* методам просто передаются обернутому экземпляру множества.

*/

var FilteredSet = Set.extend(

function FilteredSet(set, filter) { // Конструктор

this.set = set; this.filter = filter;

},

{ // Методы экземпляров

add: function {

// Если фильтр был указан, применить его

if (this.filter) {

for(var і = 0; і < arguments.length; i++) {

var v = arguments[i];

if (!this.filter(v))

throw new Error("FilteredSet: значение " + v + " отвергнуто фильтром");

}

}

// Затем вызвать метод add объекта

this.set.add this.set.add.apply(this.set, arguments);

Поделиться:
Популярные книги

Том 3. Рассказы 1896-1899

Горький Максим
3. Собрание сочинений в тридцати томах
Проза:
русская классическая проза
5.00
рейтинг книги
Том 3. Рассказы 1896-1899

Хозяин Теней 5

Петров Максим Николаевич
5. Безбожник
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Хозяин Теней 5

Глава рода

Шелег Дмитрий Витальевич
5. Живой лёд
Фантастика:
боевая фантастика
6.55
рейтинг книги
Глава рода

Наследие Маозари 8

Панежин Евгений
8. Наследие Маозари
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
постапокалипсис
рпг
фэнтези
эпическая фантастика
5.00
рейтинг книги
Наследие Маозари 8

Император Пограничья 1

Астахов Евгений Евгеньевич
1. Император Пограничья
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Император Пограничья 1

Играть... в тебя

Зайцева Мария
3. Звериные повадки Симоновых
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Играть... в тебя

Камень. Книга шестая

Минин Станислав
6. Камень
Фантастика:
боевая фантастика
7.64
рейтинг книги
Камень. Книга шестая

Романов. Том 1 и Том 2

Кощеев Владимир
1. Романов
Фантастика:
фэнтези
попаданцы
альтернативная история
5.25
рейтинг книги
Романов. Том 1 и Том 2

Двойник Короля 7

Скабер Артемий
7. Двойник Короля
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Двойник Короля 7

Бандит 2

Щепетнов Евгений Владимирович
2. Петр Синельников
Фантастика:
боевая фантастика
5.73
рейтинг книги
Бандит 2

Группа крови на рукаве

Вязовский Алексей
1. ГК
Фантастика:
боевая фантастика
попаданцы
альтернативная история
6.40
рейтинг книги
Группа крови на рукаве

Эволюционер из трущоб. Том 9

Панарин Антон
9. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Эволюционер из трущоб. Том 9

Иной. Том 1. Школа на краю пустыни

Amazerak
1. Иной в голове
Фантастика:
боевая фантастика
рпг
аниме
5.75
рейтинг книги
Иной. Том 1. Школа на краю пустыни

Локки 6. Потомок бога

Решетов Евгений Валерьевич
6. Локки
Фантастика:
аниме
фэнтези
5.00
рейтинг книги
Локки 6. Потомок бога