30.11.2013, 23:30
|
Аспирант
|
|
Регистрация: 30.11.2013
Сообщений: 42
|
|
Организация кода в публичной библиотеке
Здравствуйте.
В процессе обучения пишу скрипт (главная задача — именно учебная), который хоть и вряд-ли буду публиковать, но хотел бы, чтобы он был потенциально готов к публикации и распространению.
Схема использования — создается объект с данными, модифицируется с помощью собственных методов, затем считывается итоговое значение. Ничего уникального. Но в связи с особенностями задачи — применяться может очень интенсивно, от десятков тысяч до миллионов вызовов.
Возникла дилема — как организовать код, и с моей неопытностью я не могу принять взвешенное решение самостоятельно.
Вариант первый — классическое прототипное наследование в чистом виде. Создаю конструктор, присваиваю прототипу объект с методами. Либо каждый метод в отдельности — Constructor.prototype.method = function() { ... }, чтобы не затереть уже имеющиеся поля, вроде conctructor. «Приватные» методы обозначаются символом в имени, по сути оставаясь публичными.
Вариант второй. Функция, скрывающая приватные методы в замыкании, и возвращающая объект только с публичными методами.
Попытался составить тесткейс для сравнения производительности этих подходов, сделал два тестовых «класса» с абсолютно одинаковой функциональностю, реализованные по-разному.
По результатам моих измерений прототипное наслделование дает прирост в производительности, в зависимости от браузера, либо незначительный (4—5%), либо ощутимый (10—20% и больше).
К недостаткам прототипного наследования могу отнести видимость приватных методов извне («захламление») и необходимость использовать new с конструктором (или определить функцию-обертку для этого).
При создании замыканий получаем в некоторых условиях более медленный код, однако более «чистый» объект на выходе, без видимых приватных методов, и более простой в использовании (не требуется new или обертка).
Прошу помощи в выборе. Также смущает то, что сам не встречал публичных библиотек или фреймворков, использующих чистое прототипное наследование.
Спасибо.
|
|
01.12.2013, 12:41
|
Профессор
|
|
Регистрация: 18.11.2013
Сообщений: 275
|
|
Сообщение от Antonius
|
К недостаткам прототипного наследования могу отнести видимость приватных методов извне
|
В чем недостаток? Рсскажи подробнее? Что мешает создать для них неймспейс префикс или постфикс например "_" ?
|
|
01.12.2013, 13:03
|
|
Быдлокодер;)
|
|
Регистрация: 19.11.2010
Сообщений: 4,338
|
|
Частая ошибка новичков изучающих ООП: модификаторы видимости private и protected созданы ИСКЛЮЧИТЕЛЬНО для увеличения уровня абстракции и банальной удобности, а не для "сокрытия от злых хакеров".
Я использую классическое соглашение:
_ private
__ protected
и всем советую
|
|
01.12.2013, 14:01
|
|
Профессор
|
|
Регистрация: 11.09.2010
Сообщений: 8,804
|
|
Помоему такого рода "приватные методы" (ввиде локальных функций) не оставляют возможности наследоваться от класса и перекрывать методы.
Более того, такой способ работает только для функций (ибо функции расшарены для всех экземпляров), а как же быть с приватными свойствами?
Кстати, никто не встречал использование вместо знака «_» знак «$» для приватных свойств/методов?
__________________
В личку только с интересными предложениями
|
|
01.12.2013, 14:06
|
|
Быдлокодер;)
|
|
Регистрация: 19.11.2010
Сообщений: 4,338
|
|
Сообщение от danik.js
|
Помоему такого рода "приватные методы" (ввиде локальных функций) не оставляют возможности наследоваться от класса и перекрывать методы.
|
Ну приватные метода и не должны наследоваться, для этого есть протектед, хотя это конечно всё условности Прост по аналогии с Action Script 3 или C# и т.д.: модификатор "приватности" означает видимость в пределах класса, а модификатор "протектед" означает видимость также для его потомков.
Сообщение от danik.js
|
Кстати, никто не встречал использование вместо знака «_» знак «$» для приватных свойств/методов?
|
В ангуляре вроде так.
Последний раз редактировалось kobezzza, 01.12.2013 в 14:14.
|
|
01.12.2013, 14:55
|
Профессор
|
|
Регистрация: 18.11.2013
Сообщений: 275
|
|
Сообщение от danik.js
|
Помоему такого рода "приватные методы" (ввиде локальных функций) не оставляют возможности наследоваться от класса и перекрывать методы.
|
function Animal() {
}
Animal.prototype.say = function() {
alert('i Animal')
};
Cat.prototype = Object.create(Animal.prototype); //наследуем
function Cat() {
}
Cat.prototype.say = function() {
this.constructor.prototype.say.call(this); //перекрытый метод
alert('i Cat')
};
new Cat().say();
можно еще для простоты сделать так
Cat.prototype = Object.create(Animal.prototype); //наследуем
Cat.prototype.parent = Cat.prototype;
function Cat() {
}
Cat.prototype.say = function() {
this.parent.say.call(this); //перекрытый метод
alert('i Cat')
};
Сообщение от kobezzza
|
В ангуляре вроде так.
|
кстати раз уж я пытаюсь копировать их апи и названия методов, я на всякий скопировал и эту традицию, теперь бесит =)
Последний раз редактировалось Maxmaxmaximus3, 01.12.2013 в 14:58.
|
|
02.12.2013, 01:51
|
Аспирант
|
|
Регистрация: 30.11.2013
Сообщений: 42
|
|
Сообщение от Maxmaxmaximus3
|
В чем недостаток? Рсскажи подробнее? Что мешает создать для них неймспейс префикс или постфикс например "_" ?
|
Разумеется, если остановлюсь на этом варианте, то так и будет сделано.
Сообщение от kobezzza
|
Частая ошибка новичков изучающих ООП: модификаторы видимости private и protected созданы ИСКЛЮЧИТЕЛЬНО для увеличения уровня абстракции и банальной удобности, а не для "сокрытия от злых хакеров".
Я использую классическое соглашение:
_ private
__ protected
и всем советую
|
Это очевидно же. Дело в другом. Если есть причины сделать метод приватным, то это же не просто так. Например, у него может в будущем поменяться набор или формат параметров или тип/формат возвращаемого значения, он может быть переименован или удален. Да и просто он может выполнять сугубо служебные функции, и «не надо хотеть» использовать его извне. Публично доступен стабильный (хочется надеяться) API,
Но для выбора в моем случае это всего лишь один из «недостатков». Также смущает необходимость использования new. В подобного рода скриптах, рассчитанных на массовое использование, мне подобное требование не встречалась (неопытность? такие библиотеки, скрипты существуют?)
Сообщение от danik.js
|
Помоему такого рода "приватные методы" (ввиде локальных функций) не оставляют возможности наследоваться от класса и перекрывать методы.
Более того, такой способ работает только для функций (ибо функции расшарены для всех экземпляров), а как же быть с приватными свойствами?
Кстати, никто не встречал использование вместо знака «_» знак «$» для приватных свойств/методов?
|
Наследоваться и перекрывать методы (публичные, разумеется), можно при использовании «паразитного», «фабричного» наследования, разве нет? А менять служебные приватные методы как минимум опасно — на их основе работает остальной код, для чего может потребоваться их изменение (а не доопределение новых)? Ко всем данным (приватным свойствам), которые имеют смысл за пределами объекта, должен быть обеспечен доступ средствами открытого API, не так ли? Что заодно позволит выполнять валидацию и коррекцию ошибочных данных (если это возможно) при доступе к ним. В моем случае геттеры-сеттеры я применять не планирую — поддержка у них для этой задачи неудовлетворительная пока что.
Да, и еще вопрос вдогонку. Те, кто использует классическое прототипное наследование, в каком формате вы присваиваете значение прототипу? Constructor.prototype = { … } или Constructor.prototype.field = …?
|
|
02.12.2013, 02:10
|
Профессор
|
|
Регистрация: 18.11.2013
Сообщений: 275
|
|
Сообщение от Antonius
|
Это очевидно же. Дело в другом. Если есть причины сделать метод приватным, то это же не просто так. Например, у него может в будущем поменяться набор или формат параметров или тип/формат возвращаемого значения, он может быть переименован или удален. Да и просто он может выполнять сугубо служебные функции, и «не надо хотеть» использовать его извне.
|
ииииииииииии????
Сообщение от Antonius
|
Но для выбора в моем случае это всего лишь один из «недостатков».
|
В чем недостаток то?
Сообщение от Antonius
|
для чего может потребоваться их изменение
|
Очевидно что когда говорится не поддерживается переопределение имеется ввиду нет удобного доступа к оригиналу из перекрытого. а зачем нужен доступ к оригиналу? потому что когда метод перекрывается, старый функционал сохраняется а новый нарасчивается. это к слову
Сообщение от Antonius
|
Constructor.prototype.field
|
Потому что лучше сжимается мигификаторами =) при такой записи они могут вообще заинлайнить код функции то есть если его мало, то взять и подставить его в те места где метод вызывается.
Последний раз редактировалось Maxmaxmaximus3, 02.12.2013 в 02:13.
|
|
02.12.2013, 02:21
|
|
junior
|
|
Регистрация: 29.11.2011
Сообщений: 3,924
|
|
Прототипы + соглашения + обертка для new. С другой стороны смотря для кого пишешь - можно и не оборачивать new. Тот, кто используют приватные методы извне - сам дурак
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук
|
|
02.12.2013, 02:30
|
Аспирант
|
|
Регистрация: 30.11.2013
Сообщений: 42
|
|
Сообщение от Maxmaxmaximus3
|
ииииииииииии????
|
И если не надо хотеть его использовать извне — не надо давать возможность его использовать извне. Но дальше я уже понял, какие детали упускаю из виду.
Сообщение от Maxmaxmaximus3
|
В чем недостаток то?
|
Потому и в кавычках. Не недостаток, просто некрасиво что-ли...
Сообщение от Maxmaxmaximus3
|
Очевидно что когда говорится не поддерживается переопределение имеется ввиду нет удобного доступа к оригиналу из перекрытого. а зачем нужен доступ к оригиналу? потому что когда метод перекрывается, старый функционал сохраняется а новый нарасчивается. это к слову
|
Да, согласен.
Сообщение от Maxmaxmaximus3
|
Потому что лучше сжимается мигификаторами =) при такой записи они могут вообще заинлайнить код функции то есть если его мало, то взять и подставить его в те места где метод вызывается.
|
Убедительно. И существующее не трогаем, и при минификации выигрываем. Спасибо.
|
|
|
|