Доверие
Доверие — уважение причины, по которой вас решили обмануть.
UPD После этого «поста» понял, что пора начинать писать в твиттер.
Доверие — уважение причины, по которой вас решили обмануть.
UPD После этого «поста» понял, что пора начинать писать в твиттер.
Вся красота и гибкость джаваскрипта раскрывается как раз на подобных задачах: реализация функционала, который не заложен в языковые конструкции, но широко применяется в других языках программирования.
Синглтон по определению — объект, который может присутствовать в системе только в единственном числе.
Самое простое, что можно сделать — создать объект, и назвать его условно синглтоном. То есть непрограммными средствами решаем задачу.
window.singletone = {
// singletone body
};
Такой подход порождает больше вопросов и проблем, чем решает: нет никакой инкапсуляции данных, ссылку на объект необходимо явно прокидывать во все области видимости, где подразумевается его использование. Да и сама форма записи, в случае большого количества методов, сложна для чтения.
Вопрос с инкапусяцией можно решить с помощью замыкания:
var singletone = (function() {
var private;
function private_method () {}
return {
public : function () {
return private_method(private);
}
}
}());
Уже немного лучше. Данные инкапсулированы, но строить хоть какую систему наследования с подобным подходом сложно. Для упрощения процесса наследования, будем работать с функцией – конструктором. Эта функция должна возвращать ссылку на один и тот же объект. Самое простое, что можно сделать во вновь сложившейся ситуации, это сконструировать объект и всегда возвращать ссылку на него
var Singletone;
Singletone = (function () {
var instance;
instance = {};
return function () {
return instance;
}
}());
Этот код больше похож на правду: во-первых мы инкапсулировали данные, во-вторых программно ограничили количество инстансов синглтона до одного. Возможность использования конструктора как с new так и без. Код вполне рабочий, и подходящий для использования в продакшене. Но в нем еще достаточно минусов: объект конструируется в любом случае, даже если конструктор не был ни разу вызван, невозможность использования цепочки прототипов, некорректный конструктор объекта, возвращаемого Singletone.
var singletone,
another_singletone;
singletone = new Singletone();
another_singletone = Singletone();
console.log(singletone === another_singletone); // true
console.log(another_singletone.constructor === Singletone); // false
console.log(another_singletone.__proto__ === Singletone.prototype); // false
Конечно мы можем вручную установить свойство constructor, __proto__. Правда такой код потеряет в кроссбраузерности и изящности (все равно продолжит работать, что намного важнее красоты). Я же в своих изысканиях ищу максимально изящный вариант.
Судя по предъявляемым требованиям, конструктор синглтона должен создавать и запоминать объект при первом вызове, и возвращать этот объект при последующих. Вспомним, что объект функции это объект, и будем хранить в нем инстанс сконструированного объекта.
function Singletone () {
if (Singletone.instance) {
return Singletone.instance
}
Singletone.instance = this;
}
Вот она, красота, javascript. Если конструктор явно не возвращает объект, то возвращается конструируемый объект. При первом вызове new Singletone в свойство Singletone.instance запишется конструируемый объект, а при последующих будет возвращаться ссылка на него.
Этот код хорош по нескольким причинам: объект не создается, если он не был сконструирован (в отличии от предыдущих вариантов), объект можно расширять с помощью Singletone.prototype, так-же проверять instanceOf Singletone. С другой стороны, эту функцию необходимо всегда вызывать с ключевым словом new. Не то, чтобы я был противником использования new или сокрытия этого механизма от программиста, использующего мой синглтон, но создание возможности вызова конструктора как с new, так и без, позволит избежать ряда вопросов про использование синглтона. Так же в этом варианте функция выступает в качестве хранилища инстанса объекта. Такой подход имеет право на жизнь, но он слишком прямолинеен и показывает детали реализации наружу, делая код чуть уязвимее.
Возможно я бы не придирался так к коду (кстати, в вики пример реализации синглтона именно в виде, представленном выше), если не бы не знал лучшей реализации.
Мы же пойдем дальше, и создадим реализацию, которая:
var Singletone = (function () {
var instance;
return function Construct_singletone () {
if (instance) {
return instance;
}
if (this && this.constructor === Construct_singletone) {
instance = this;
} else {
return new Construct_singletone();
}
}
}());
Разберем что происходит в возвращаемой функции.
Если есть instance, то возвращаем его. Если функция используется с new или без, все равно мы вернем ссылку на объект, сконструированный этой функцией.
Если функция вызвана с new, то this ссылается на объект, конструируемый этой функцией. This так же может быть определен, если функция вызвана в нестрогом режиме (this === window), или если функция вызвана как метод объекта (this === этот_объект). Второй случай аннигилируется проверкой конструктора у this.
Если this не определен (вызов в строгом), или конструктор у this не текущая функция, возвращаем результат текущей функции с new.
Имеем на выходе пуленепробиваемый конструктор синглтона, который можно где угодно хранить и как угодно вызывать. Такую красоту нельзя не прихватить в тулбокс.
Как говорят “правильно сформулированный вопрос — половина ответа”. Но для того, чтобы этот вопрос сформулировать, надо еще постараться.
Задайте вопрос
Не заставляйте собеседника додумывать за вас. Не бойтесь признаться в своем незнании. (наблюдения показывает, что отсутствие вопросительного слова при наличии описания проблемы, является признаком человека, не желающего признать свое незнание. Правда выглядит по-детски?).
Заменить местоимения на сущности
Замечаю за собой, что мыслю частично словами, частично образами. Для образов в языке нет подходящих описаний, поэтому на скорую руку заменяю их на “это”, “то”, “оно”. А надо побольше, побольше конкретики. Когда вопрос читают или слушают, каждое слово обрабатывается согласно его смыслу. Местоимения и производные матов — такие слова, которые могут иметь множество значений в зависимости от контекста. Для их обработки прийдется отмотать весь вопрос назад, чтобы понять про что идет речь.
Замена матом существительных, прилагательных, и любых других частей речи часто встречается в народном фольклоре:
- Нахуя дохуя нахуярили! Расхуяривай нахуй!
- Нахуя расхуяривать? Нахуярили д хуя и хуй с ним.
- Нихуя, не дохуя, похуярили.
Без замены местоимений вопросы зачастую выглядят так:
У меня тут на на компе есть папка, в ней скрытые файлы, в которых смешные картинки. Как мне попасть туда?
У меня есть пункт меню, когда я навожу курсор на выпадающий список, он не работает.
Куда попасть, кто он не работает и что значит не работает: не кликает курсор, не выпадает меню, не открывается пункт меню?
Описывайте задачу, а не частность
Возможны альтернативные варианты решения задачи, и будет не приятно, если ответ на частную ситуацию не приблизит вас к решению задачи. Приведу аналогию.
Я задался целью повесить картину на стену. Прочел в интернете, что картины вешают на гвоздь. Прочел, что гвоздь надо вбить, чтобы он держался. Забивать гвозди я не умею, и иду к мастеру по ремонтам. Я спрашиваю совета как забить гвоздь. Он показывает, дает молоток, и я радостно, но безрезультатно пытаюсь забить гвоздь в бетонную стену. Снова иду к мастеру, говорю, что гвоздь не забивается: стена твердая. Он дает мне перфоратор, показывает как с ним обращаться, я сверлю стену, вбиваю гвоздь, вешаю на него картину и зову мастера, чтобы поделиться с ним своим успехом. Он приходит, и видит, что картина маленькая, и вполе могла бы быть повешена на невидимку, вдетую в обои.
В данном случае надо было описать ситуацию: хочу повесить картину, услышал, что их вешают на гвозди, попробовал забить гвоздь — не получилось. Как мне повесить картину?
Понимайте что будете делать с ответом
Этот пункт перекликается с предыдущим. Вопросы класса «А что будет, если слон подерется с китом» хороши только для коротания вечера в компании друзей, но никак для получения знаний, выяснения закономерностей.
Примените Метод утенка
Этот метод описан в книге «Программист прагматик». Сформулируйте вопрос так, будто объясняете ситуацию утенку, который вообще ничерта ни в теме. Таким образом вы будете использовать совсем другие категории для формулировки вопроса, вспомните детали, которые опускали, когда искали ответ, и с большей вероятностью самостоятельно прийдете к ответу.
Что бы вы посоветовали тем, кто задает вам вопросы?
Осьминоги и каракатицы (моллюски) пришли в своей эволюции к тому-же, решению, что и хордовые (кошечки-собачки и мы с вами): они отрастили глаза. При том не просто глаза, в виде светочуствительных скоплений клеток, а полноценные: с хрусталиком и роговицей. Принципы фокусировки немногим отличаются, но сходных данных достаточно для того, чтобы подавать в суд по вопросам эволюционных авторских прав (если бы такой был, конечно).
После такого перестанешь удивляться, что хорошие дизайнеры приходят к похожим решениям, паттерны программирования переизобретаются.
Описать в виде программы историю, или процесс из жизни. Главное — сделать максимально понятным что имелось в виду.
Например:
function in_the_morning () {
var now,
breakfast;
now = me.look_at_watch();
if (now > TOO_LATE || now < TOO_EARLY) {
try {
me.continue_sleeping();
} catch (err) {
me.do_stuff();
now = me.look_at_watch();
if (now < TOO_EARLY) {
in_the_morning();
} else {
return false;
}
}
} else {
me.take_shower({
soap : SOAP,
shampoo : SHAMPOO || SOAP
});
breakfast = me.prepare_breakfast('eggs', 'bacon');
now = me.look_at_watch();
if (breakfast && now < TOO_LATE) {
me.eat(breakfast);
}
return true;
}
}
Когда видишь такой стиль написания в продакшене, программерское сердце поет, мозг отдыхает, а задачи решаются с пол-пинка.
UPD
Маленький городок среди гор-лесов. Скучный, опрятный, с древней историей. В таком месте хорошо провести старость в последний путь.
Тут борятся за экологичность: ветряки в горах, уличные фонари и автоматы платной стоянки на солнечных батареях. Иногда над таким автоматом ростет дерево, сводя на нет всю рентабельность затеи.
Струящийся фонтан.
Типичная улица.
Каждый дом уникален и по-особому красив.
Многоэтажные застройки присутствуют, но не часты. Как в Гамбурге, так и в Кайзере на звонках пишется фамилия владельца квартиры, а не бездушный номер.
Подъезд индивидуалистов и одного нонконформиста: ни одной похожей подписи.
Внезапно, но каждым субботним утром под окнами на площади собираются палатошники. Продают в основном фрукты-овощи, рыбу. Реже – мед, печенье, горшочные цветы.
Рядом с местом проживания, есть две старые звонящие церкви. Особенно удобно, когда вечером заблудился, достаточно идти на колокольный звон, а там разберешься. Утром начинают звонить рано, часов в шесть. Разные мелодии каждые пятнадцать минут. Сподручно знать время, не открывая глаз.
Пластик и стекло пристроились у древних камней.
Витражи затянуты сеткой. Подозреваю, что против вандалов.
Не первый раз встречаю, как привлекают внимание просто выставляя его с ценниками на улицу. Подошел, выбрал, оплатил в магазине. Удобно.
Витрина аптеки. Аптечные весы с набором гирь и чемодан разных минералов-корешочков.
Парк. Хотя тут 10 минут на автобусе, и ты в лесу.
Как же здорово выглядит трава, прорастающая между плитками. Я прямо тащусь
Указатель свободных мест и направлений ближайших парковок. На фоне – здание банка.
В кафешке-представительстве итальянской кухни (жаль не корейской) меня облаяла собака. Хозяин успокаивает питомца.
Ручка-рыба с человеческими чертами на рыбьем лице.
Солнечные часы с инструкцией. Но даже она не помогла узнать приблизительное время.
Красивейшая стена с табличками. Надписи на нерусском и цифры 1587. Фотка левой поближе. Кто-то переведет?
На переднем плане – центр города и в нем раскопки древних кирпичей. На заднем – главная автобусная станция, которой, по сути, являются две полосы с односторонним движением, где автобусы стоят дольше обычного.
Неведомая фигня без явных опознавательных знаков. Подпертая и огороженая (может вы знаете что это может быть).