habradigest web * дизайн * разработка

Page 1

habradigest web * дизайн * разработка

}

Клиентская оптимизация → Клиентская оптимизация и этапы разработки

}

Информационная безопасность → RSA, SHA и AES: кто есть кто и почему

}

Блог им. developer → Фреймворк или свои велосипеды?

}

MooTools → Классы в MooTools

}

Типографика → Десять смертных грехов веб‐типографики

}

.NET → Использование провайдеров компиляции в asp.net

}

Web‐разработка → Ajax‐машина Верстка для мобильных устройств Алгоритмы организации тэгов

} Разработка → Архитектура приложений – горячие точки

1

сентябрь 2008


XaocCPS Слово редактора → Первый выпуск

Добрый день, читатель! Как заведено у программистов нумерация habradigest также начинается с нуля. Таким образом, перед вами первый номер журнала. За прошедший период на Хабра‐ хабре было опубликовано много чего интересного. Я постарался отобрать самое инте‐ ресное и представить это вам в виде очередного выпуска. Первый номер журнала значительно расширился по сравнению с пилотным вы‐ пуском. В новом выпуске, кроме темы веб‐разработки, представлены статьи по опти‐ мизации, типографике, алгоритмам шифрования, .Net, библиотеке MooTools. В проект все еще требуются специалисты по дизайну, php и любые другие спе‐ циалисты, которые хотели бы помочь в поиске, оценке и фильтрации статей на Хабра‐ хабре для habradigest. Если вам интересен проект, и вы хотите предложить те или иные статьи для публикации – добро пожаловать! Ваша помощь будет востребован‐ ной.

2


Covex

Клиентская оптимизация → Клиентская оптимизация и этапы разработки http://habrahabr.ru/blogs/client_side_optimization/38299/

Обычно пользователю нет дела до того, какие подходы мы применяем при разработке, как настроен сервер, какие клиентские и сер‐ верные фреймвёрки мы используем. Его мо‐ жет волновать на сколько сайт полезный, удобный и быстрый. Наша же задача заключа‐ ется в том, чтобы не доставлять пользователю неудобства, радовать его, и тем самым застав‐ лять его покупать наш мега‐продукт или смот‐ реть на наши замечательные баннеры. Эта статья о том, как создавать быстрые сайты.

Как оценить производительность сайта? Я пользовался только двумя сервисами для получения хоть какой‐то формализован‐ ной и достоверной оценки: это плагин для FireBug «YSlow» и сайт webo.in (уверен, что подобных сервисов гораздо больше). Оценка качества доставки контента с сер‐ вера клиенту, которую выдаёт YSlow — это сводный показатель, простой и понятный: «Performance Grade A» — всё хорошо, «Performance Grade F» — всё плохо. Эта оцен‐ ка формируется из 13 других субпараметров, ещё более простых, описанных на английском на сайте developer.yahoo.com. Результат работы сервиса webo.in — это две оценки, основанные на анализе следова‐ ния разработчиками советам владельца сер‐ виса и объёма представленной на сайте ин‐ формации и список рекомендаций для даль‐ нейшей оптимизации. Плюс к тому на сайте есть большое количество статей по данной тематике. Для получения полной картины, я бы по‐ советовал использовать оба способа оценки. Но нужно учитывать, что ощущения пользова‐ теля и автоматически сформированная оценка могут сильно отличаться.

Как же пользователь понимает какой сайт работает быстрее, а какой медленнее? Мы посещаем сайты ради информации и чем быстрее мы её получим в читаемом виде, тем выше будет наше мнение о сайте. Таким образом, одна из первоочередных задач раз‐

работчика — это минимизация времени полу‐ чения оформленной информации и исключе‐ ние всего, что может отложить этот момент. Фактически, я уже описал цель первого этапа разработки (серверная часть входит в этот первый этап =) Но до его подробного описания я бы хотел остановится на одном важном, по моему мнению, моменте. Методология На пути к оптимальному результату есть некоторое количество проблем, в основном — организационных, а техническая же сторона вопроса всегда легко формализуема, а значит — решаема. Давайте выделим из всего технологиче‐ ского процесса «от креатива и ТЗ до начала эксплуатации», собственно, сам процесс раз‐ работки «от базы данных до полной загрузки страницы». Для серверных разработок разра‐ ботан не один подход, метод или паттерн: возьмём, к примеру, MVC. Клиентская разра‐ ботка это: HTML — структура (Structure), CSS — внешний вид (Presentation), JavaScript — пове‐ дение (Behavior). Итого получилось 6 частей: Model, View, Controller, Structure, Presentation, Behavior, из которых две — совпадают: сер‐ верное View — это клиентское Structure. M => C => [V == S] => P => B Я считаю, что необходимо рассматривать все 5 частей техпроцесса, как единое целое. В этом процессе все части проектируются для остальных, последующих за ними; а ошибки их проектирования и реализации приведут к временным потерям на следующих частях и к медленной или неправильной работе конеч‐ ного результата. Для минимизации вероятности ошибок, необходимо, чтобы каждая из частей техпро‐ цесса выполняла только свои задачи. Напри‐ мер, в структуре документа не должно содер‐ жатся аттрибутов, выполняющих функции оформления или поведения: style, onclick, onmouseover; весь CSS и JavaScript должны быть вынесены во внешние файлы. Разделение труда Для внедрения такой схемы можно выде‐ лить следующие специализации: — M => C — проектировщик БД, разработчик модулей системы — C => [V == S] — разработка CMS, автомати‐

зация работы с шаблонами — [V == S] => P — вёрстка и оформление — [V == S] => B => P — JavaScript (тут я не знаю как назвать специализацию) Это примерно 3 человека (админов, дизайне‐ ров, менеджеров и директоров я не считаю =) Итак,

Этап 1: Доставка информации и оформ‐ ления На этом этапе разработчики должны сде‐ лать всё возможное, чтобы не замедлить ско‐ рость загрузки страницы. Способы ускорения получения информа‐ ции Уменьшение количества HTTP‐запросов, Сжатие HTML и CSS, Размещение статичных компонент страницы на нескольких доменах, Уменьшение количества DOM‐элементов, Размещение CSS в HEAD страницы, Настройка HTTP‐заголовков (Expires, ETag, Set‐Cookie), Уменьшение количества DNS запросов Как можно испортить первое впечатле‐ ние от сайта Загрузка и/или использование JavaScript в процессе загрузки информации, Использование iframe‐ов на странице Я расположил пункты в порядке убывания важности. Все пункты предельно понятны. Я хочу остановится только на одном моменте (про сжатие и кэширование я напишу ниже) Размещение CSS в HEAD странице: на странице должен быть только один внешний CSS‐файл Невыполнение этого требования приведёт к задержке отображения страницы, т.к. CSS‐ файлы загружаются последовательно + на каждый HTTP‐запрос уходит дополнительное время. Важность данного требования измеря‐ ется временем отклика сервера и скоростью доступа в интернет у клиента. Требование, фактически, сводится к объе‐ динению всех CSS‐файлов в один. Есть два варианта реализации: ручной и автоматиче‐ ский. Ручной способ выполним только в про‐

3


стых проектах, либо в проектах с однотипными страницами. Во всех остальных случаях сыгра‐ ет роль человеческий фактор и люди просто не будут заниматься этой ерундой каждый раз после любого изменения. Результатом без‐ думного объединения вообще всех файлов могут стать десятки килобайт CSS‐правил, из которых на каждой отдельно взятой странице использоваться будет лишь малая часть. Идею (но не реализацию !!!) для автома‐ тического варианта решения можно подчерп‐ нуть здесь. Суть идеи в синтаксе запроса: для двух файлов /styles/a.css и /styles/b.css может быть сформирован один запрос вида /styles/a.css; b.css. Если такой файл уже есть на сервере, его можно отдать nginx‐ом, иначе запрос должен быть проброшен дальше в backend, чтобы создать этот файл для следую‐ щих обращений к нему. С таким подходом можно физически раз‐ делить CSS‐правила на общие (требуемые на всех страницах) и частные (требуемые только на «нестандартных» страницах), и, при необ‐ ходимости, соединять их. Итог первого этапа — это доставленный и оформленный HTML. Нет никакого JavaScript (на этапе доставки основного контента он только мешает). Время от начала до заверше‐ ния загрузки такой страницы при включенном и выключенном JS фактически будет одинако‐ вым. Это и будет выигрышем в скорости за‐ грузки! Если выполнить требование «Уменьшение количества DOM‐элементов» более‐менее близко к идеальному, то побочным эффектом может стать возможность реализации мо‐ бильной версии сайта и версии для печати тем же самым HTML‐кодом. Останется «всего лишь» реализовать наборы CSS правил для media=«handheld» и media=«print».

Этап 2: Кэширование файлов оформления, сжатие HTML, CSS и JS На данном этапе разработчики должны обеспечить быструю загрузку других страниц сайта (если посетитель решит туда перейти). Этот этап должен проходить параллельно с первым. Для решения задач кэширования и сжатия я рекомендую использовать только nginx, а Апачу останется только генерация динамиче‐ ских страниц и сборка CSS и JS файлов. Приве‐ ду конфигурацию nginx, которую я подготовил «по мотивам» нашей уже работающей систе‐ мы: Основной домен проекта (www.site.org) server {

listen 80; server_name www.site.org site.org; gzip on; gzip_min_length 1000; gzip_proxied expired no‐cache no‐store pri‐ vate auth; gzip_types text/plain application/xml; location / { proxy_pass http://backend; proxy_set_header Host $host; proxy_set_header X‐Real‐IP $remote_addr; proxy_set_header X‐Forwarded‐For $proxy_add_x_forwarded_for; } location /favicon.ico { expires max; root /home/project/img/; } location /s.gif { expires max; root /home/project/img/; } } Здесь все запросы к www.site.com пробра‐ сываются дальше в Apache (http://backend определяется директивой upstream. Исключе‐ ния составляют только favicon.ico и прозрач‐ ный s.gif: они лежат в одном каталоге со всеми остальными интерфейсными картинками, а для броузера доступны как www.site.com/favicon.ico и www.site.com/s.gif. Такое исключение для s.gif сделано только для того, чтобы сократить размер html‐кода. Ответы апача с Content‐Type «text/html», «text/plain», «application/xml» сжимаются налету. Сжатие стоит отключить в случае, когда для проекта выделено небольшое количество ресурсов. Все HTML‐страницы считаются динамиче‐ скими, поэтому они не кэшируются. Домен для интерфейсных картинок (img.site.net) server { listen 80; server_name img.site.net; expires max; add_header Cache‐Control public; location / { root /home/project/img/; } location ~ ^/\d+\.\d+\/.* { root /home/project/img/; rewrite (\d+\.\d+)/(.*) /$2 break; } } Все интерфейсные картинки кэшируются навсегда. Пример: img.nnow.ru/interface/is.png Для того, чтобы сбросить кэш броузеров, введено такое правило: если HTTP‐запрос начинается со «слэш число точка число слэш», то картинки следует брать из корня. Пример: img.nnow.ru/2.0/interface/is.png

Это очень полезно, когда внутрь картинки‐ CSS‐спрайта нам потребуется добавить ещё одну иконку. Домен для CSS‐ и JS‐файлов (static.site.net) server { listen 80; server_name static.site.net; expires max; gzip_static on; location / { return 404; } location /jas/ { # javascript‐and‐stylesheets proxy_set_header Host $host; if (!‐f $request_filename) { break; proxy_pass http://backend; } root /home/project/static/; } } Принцип работы серверных механизмов по сборке CSS и JS был описан выше. Единст‐ венное, про что стоит отметить — это директи‐ ва gzip_static. Эта директива поставляется с модулем ngx_http_gzip_static_module. Модуль позволяет отдавать вместо обычного файла предварительно сжатый файл с таким же име‐ нем и с суффиксом «.gz». По умолчанию мо‐ дуль не собирается, нужно разрешить его сборку при конфигурировании параметром ‐‐ with‐http_gzip_static_module. Сборщик файлов дополнительно должен уметь записывать файлы вида /jas/a.css; b.css.gz. CSS и JS файлы кэшируются навсегда. Сброс кэша может быть реализован добавле‐ нием «версии файла» в название файла: /jas/ver2.0.css; a.css; b.css NB! Мы реализовали сборщик таким обра‐ зом, что файлы a.css и b.css в момент сборки включаются в конечный результат PHP‐ функцией include, т.е. фактически являются исполнимыми PHP‐файлами. Это даёт воз‐ можность избавится от хаков CSS или от анали‐ за User‐Agent броузера в JS: При обращении к /jas/ver2.0.css; Firefox3.css; a.css; b.css Firefox3.css, запоминает в переменную PHP название и версию броузе‐ ра, а последующие части составного файла‐ результата могут прочитать эту переменную и выдавать разное содержимое для разных браузеров. Например: «s.img.nnow.ru/jas/ver,1.0.js; Firefox3.js; habr, index.js» и «s.img.nnow.ru/jas/ver,1.1.js; IE6.js; habr, index.js» Таким же образом меняется и «версия ин‐ терфейсной картинки» для img.nnow.ru/3.0/interface/logo_ni.gif (соответ‐

4


ствующая переменная устанавливается в фай‐ ле‐версии CSS).

ключены перед закрытием тэга body. Жизнь начинается после загрузки HTML‐кода:

Этап 3: Жизнь после загрузки страницы

Задача сводится к выполнению следующих действий:

Цель данного этапа это — навешивание мышиных событий на различные DOM‐ элементы и реализация прочих Web‐два‐ нольных прибамбасов, т.е. оживление страни‐ цы. Говорят, что иногда «грамм видимости важнее килограмма сути» — это как раз про JS. Ведь именно на JavaScript можно реализовать механизмы, упрощающие действия пользова‐ теля; можно сделать много различных визу‐ альных эффектов, подчеркивающих оформле‐ ние, удобство и полезность сайта (а фактиче‐ ски всю работу, которую проделали разработ‐ чики на предыдущих этапах). К этому моменту мы должны иметь оформленную HTML‐страницу, на которой все ссылки и формы обязаны работать без JavaScript‐а. Должны быть готовы серверные интерфейсы для Ajax‐овых запросов; структура страницы должна такой, чтобы для аналогич‐ ных кусков HTML не приходилось реализовы‐ вать аналогичные, но не одинаковые куски JS‐ кода. Скорее всего должны быть созданы шаблоны страниц, где видно как будет выгля‐ деть страница после какого‐то действия поль‐ зователя. По сути должен быть организован эффек‐ тивный обмен информацией между всеми разработчиками. Как организовать такой диа‐ лог в команде, состоящей из десятков человек, я не знаю; но, для команды из трех‐четырех человек это сделать вполне реально (хоть и сложно). Чтобы не уменьшать скорость доставки контента и оформления, JS‐файлы (лучше все‐ го, конечно, один JS‐файл) должны быть под‐

1. найти DOM‐элементы, требующие «оживления» (далее — компоненты); 2. определить, что это за компонент; 3. обеспечить подключение необхо‐ димого кода JavaScipt; 4. следить за очередностью подклю‐ чения файлов; 5. не позволять нескольких загрузок одного файла. Если вы дочитали до этого места ;) то вам лучше всего продолжить чтение на странице Модульность в JavaScript, динамическая загрузка на сайте www.jsx.ru. Именно там я позаимствовал этот алгоритм. Свой вариант решения я лучше не буду рекламировать, т.к. фактически, в процессе выполнения задачи, был поставлен эксперимент, конечный резуль‐ тат которого ясен не на все 100% (пока, вроде бы всё работает отлично =) Расскажу о пунктах 3 и 4. Поиск необходимых DOM‐элементов дол‐ жен нам дать список названий JS‐компонент. Названия компонент должны однозначно соответствовать названиям файлов на сервере, в которых содержится код для них. Так же нам может понадобиться загрузить некоторые дополнительные CSS‐правила для найденных компонент для каких‐то визуальных эффектов, не необходимых на первом этапе загрузки контента и оформления. Cписок названий компонент можно объеди‐ нить в один запрос к серверу. В итоге после загрузки контента должны загрузиться файлы вида «static.site.net/jas/componentName1.css; componentName2.css» и «static.site.net/jas/componentName1.js; componentName2.js». У данного подхода есть два недостатка: (1) в папке /jas/ через некоторое время может сге‐ нериться очень много файлов, что теоретиче‐ ски может уменьшить время доступа к ним на

сервере; (2) иногда на странице может ока‐ заться очень много компонент, при чём так много, что длинна имени запрашиваемого объединённого файла перевалит за возмож‐ ности файловой системы (например, 255 сим‐ волов у Ext3) — в этом случае потребуется разбить один запрос на несколько последова‐ тельных.

YSlow: Performance Grade: A (100) Сначала именно так я хотел назвать ста‐ тью, но затем она выросла в нечто большее, чем просто «оценка производительности сай‐ та». Теперь я уверен, что такую оценку могут получить только страницы без рекламных баннеров и счётчиков или дефолтные страни‐ цы nginx или Apache с сообщением о том, что страница не найдена. Невозможность достижения отличной оценки производительности не даёт нам по‐ вод пренебрегать клиентской оптимизацией. Ведь шагВлево‐шагВправо от оптимального пути может означать немедленный расстрел: Главная страница моего блога на liveinternet.ru: Performance Grade: F (30) Главная страница Хабра: Performace Grade F(38) Главная страница моего блога на Я.ру: Performance Grade: F (42) Пост в офицальном блоге Google: Performance Grade: F (56) Главная страница моего блога в ЖЖ: Performance Grade: D (66) Это не просто цифры — это вероятность того, что когда‐нибудь кто‐нибудь другой реа‐ лизует свою идею, раскрутит проект и отберёт вашу аудиторию, какими бы популярными сейчас ни были Хабр и ЖЖ. Спасибо за внимание.

5


ni4

Информационная безопасность → RSA, SHA и AES: кто есть кто и почему http://habrahabr.ru/blogs/infosecurity/39653/

Как я заметил, на хабре и вообще в этом

3DES, AES, и т.д… Используются для шифрова‐

пись. В практических реализациях обе три :)

самом интернете, хабр содержащем, многие

ния больших объемов данных. Кстати, они

эти операции используют алгоритмы описан‐

путают эти аббревиатуры и относят все в кучу,

разделяются на блочные шифры и поточные.

ные в пунктах 1 и 2.

посему порой встречаются перлы из разряда

Блочные — это которые могут шифровать

типа «что лучше — MD5 или RSA», «шифрова‐

только блок фиксированной длины (DES/3DES

пользуемым, известным и вообще первым из

ние с помощью SHA» или «программа исполь‐

— 8 байт, AES — 16), и поточные — просто

используемых есть RSA. Абзац ниже можно

зует мощное шифрование на базе алгоритмов

работают с данными побайтно, и шифрование

пропустить, если не интересно «как это рабо‐

3DES или RSA» (к последнему сразу хочется

каждого байта зависит от предыдущих (на‐

тает», и перейти к следующему если интерес‐

добавить, что «мощное шифрование на базе

пример, RC2, RC4). Как зашифровать файл

но «как это используется».

алгоритма N» может действительно иметь

блочным шифром? Можно шифровать по оче‐

смысл только если эти алгоритмы правильно

реди каждые 8 байт, но это неэффективно,

ризации больших чисел. Собственно, ключе‐

использованы).

поскольку например для двух одинаковых

вым материалом есть секретная экспонента D

блоков данных результат будет также одина‐

(которая вычисляется при помощи P и Q), от‐

ковым, и отсюда злоумышленник может из‐

крытая экспонента E, модуль N = P*Q, где P и Q

влечь дополнительную информацию. Поэтому

простые числа (вернее сказать, псевдопро‐

На самом же деле, эти алгоритмы можно разделить на такие группы: 1. Алгоритмы хеширования (дайджест —

Начнем с шифрования. Тут наиболее ис‐

Алгоритм базируется на проблеме факто‐

алгоритмы) — используются для подсчета

используют различные режимы шифрования,

стые, поскольку генерация больших простых

некоторого уникального идентификатора со‐

при которых каждый следующий блок файла

числе тоже та еще задача). P и Q часто также

общения фиксированной длины, как‐то: 128

каким‐то образом связывается с предыдущи‐

являются частью секретного ключа, поскольку

бит (MD5), 160 бит (SHA1, RIPEMD‐160, etc) и

ми — например, xor с результатом шифрова‐

позволяют ускорить вычисления. Для шифро‐

более. Обладают тем свойством, что разным

ния.

вания берется число (оно же строка байт),

сообщениям соответствуют (с большой долей вероятности, ибо все‐таки пространство воз‐

меньшее N (существенно меньшее не реко‐

3. Асимметричные алгоритмы. RSA, DSA,

мендуется, поскольку упрощает взлом), возво‐

можных сообщений гораздо больше фиксиро‐

DH, ECDSA… Тут во многих книгах пишется что в

дится в степень E по модулю N, ну и собствен‐

ванных 160бит) разные хеши, и генерация

них используется два ключа — один для шиф‐

но все. Для оптимизации используется стан‐

сообщения с заданным наперед хешем (или

рования, другой для дешифрования. Что лично

дартное небольшое значение для E, равное

сообщения по хешу) есть весьма сложной в

меня долгое время вводило в глубокий ступор.

65537 (раньше было поменьше), от этого стой‐

плане временных ресурсов задачей.

На самом деле ключа не ДВА, а ОДИН, состоя‐

кость алгоритма не понижается. Далее резуль‐

Также алгоритмы хеширования использу‐

щий из двух связанных частей, одна из кото‐

тат шифрования возводится в степень D, и

ются для сравнения паролей без хранения

рых секретная и только при ее помощи можно

получаем тоже самое значение которое мы

оных в чистом виде, а также генерации ключей

расшифровать данные. Публикация же откры‐

шифровали, благодаря свойствам D.

к симметричным алгоритмам шифрования (см.

той части не позволяет раскрыть сию секрет‐

дальше).

ную. Эти свойства базируются на сложных, не

тами E и D (сначала использовать D, а потом —

Кстати, отсюда и пошло «шифрование пароля

решенных на данный момент, математических

E), так также получим исходное число. Именно

при помощи MD5» — конечно, если вместо

проблемах — дискретное логарифмирование

такая схема и используется для цифровой

пароля хранится какая‐то непонятая строка,

(по a^p mod n, имея a и n нужно восстановить

подписи — только владелец секретной части

еще и закодированная в base64 или шестна‐

p), и факторизация (есть произведение двух

ключа может ее сгенерировать, но зато любой

Тут стоит заметить, что если поменять мес‐

дцатеричными цифрами, сразу думается о

больших простых чисел — p и q, нужно по

другой человек может проверить (имея E).

шифровании.

нему восстановить p и q). Не решенных, это в

Благодаря этому свойству генерация цифровой

смысле отсутствия алгоритма решения за по‐

подписи RSA в литературе также называется

ния. Ну, тут все более‐менее просто — один

линомиальное время, перебор никто не отме‐

шифрованием.

ключ (просто строка байтов фиксированной

нял.

2. Симметричные алгоритмы шифрова‐

длины), им шифруется блок данных и им же он и расшифровывается. Представители — DES,

Основное использование — шифрование (включая обмен ключами), и цифровая под‐

Как используется RSA? Следует заметить, что поскольку размер шифруемого блока ог‐ раничен размером ключа (например, 2048бит,

6


что есть 256 байт), и процедура такого шифро‐

«расшифровывает» цифровую подпись и срав‐

подходит в качестве ключа к алгоритму шиф‐

вания занимает гораздо больше времени чем

нивает извлеченный хеш с реальным хешем

рования (не тот размер, использование только

шифрование блока этих же данных симмет‐

сообщения.

символов значительно уменьшает пространст‐

ричным алгоритмом (хотя, казалось бы, за раз

Касательно DSA. DSA используется

во возможных ключей), используется хеш от

зашифровать можно гораздо больше), напря‐

*только* для цифровой подписи и базируется

пароля. Хеш позволяет получить то, что нужно

мую для шифрования данных RSA не исполь‐

на проблеме дискретного логарифмирования,

— строку байтов заданного размера (хеш

зуется.

что позволяет перенести алгоритм на любую

можно или обрезать до заданного размера,

Вместо этого генерируется случайный

группу, например группу точек эллиптических

или применив несколько раз, получить более

ключ для симметричного алгоритма, и переда‐

кривых (в результате чего получаем ECDSA :> ).

длинную строку). Раньше использовался пря‐

ваемые данные шифруются им.

Тут все посложнее чем в RSA, да и я уже устал

мой хеш от пароля, сейчас как правило ис‐

набирать текст, так что подробностей писать

пользуют немного другую методику — к паро‐

не буду, да и врядли кто до сюда дочитает ).

лю добавляют некоторые случайные байты,

Потом, используя открытый RSA‐ключ по‐ лучателя данных, этот симметричный ключ шифруется и передается получателю вместе с

Из особенностей следует заметить, что

что позволяет защититься от подбора пароля

хеш сообщения используется в DSA напрямую,

по уже посчитанным хешам. Кроме того, па‐

рации шифровании этот симметричный ключ

посему может использоваться *только* 160‐

роль последовательно хешируется несколько

дополняется, чтобы по размеру подходить под

битный хеш (SHA1, как собственно и описано в

(вплоть до тысяч) раз, что для единичного

размер ключа). Таким кстати образом можно

FIPS‐186‐2). Соответственно, поскольку стой‐

применения при правильном пароле практи‐

зашифровать файл для нескольких получате‐

кость алгоритма зависит от всех составных

чески не влияет на производительность, но

лей. И таким образом расшифровать симмет‐

ключа, не имеет смысла использовать DSA‐

пропорционально кол‐ву раз увеличивает

ричный ключ и прочитать сообщение смогут

ключи размером более 1024 бит. Позже поя‐

время перебора паролей. Далее, полученным

только владельцы соответствующих секретных

вилось дополнение стандарта, позволяющее

ключом можно шифровать не сам

ключей.

использовать более длинные хеши (SHA2 —

файл/сообщение, а ключ, которым зашифро‐

224, 256, 384, 512 бит) и соответственно боль‐

ван файл/сообщение. Такая методика исполь‐

зашифрованными данными (при этом в опе‐

Это касательно шифрования. Насчет циф‐ ровой подписи, так тут все наоборот. Владелец

ший размер ключа, но это доступно пока еще

зуется например в PGP, и позволяет шифро‐

секретного ключа пишет сообщение, считает

не во всех реализациях.

вать сообщение для нескольких получателей, с

от него хеш (поскольку само сообщение, в

4. Использование паролей. Ну и напосле‐

общем говоря, гораздо длиннее ключа), и

док о паролях, которые также можно исполь‐

«шифрует» (подписывает) уже хеш от сообще‐

зовать не только для идентифика‐

ния и письмо вместе с этой подписью отсылает

ции/аутентификации, а и для шифрования

получателю. Получатель, имея открытый ключ,

сообщений. Поскольку сам по себе пароль не

разными паролями или даже асимметричны‐ ми ключами. Вот собственно кратко о главном

.

7


developer Блог → Фреймворк или свои велосипеды? http://developer.habrahabr.ru/blog/39729/ Вообще это копипаст ответа на топик:PHP > Хватит изобретать велосипеды! Вынес я его в пост, потому что тут выраже‐ на частично противоположная позиция, и решил что можем о этом поговорить. я пред‐ почитаю изучать патерны а не готовые фрайм‐ ворки и если использовать готовые решения, то узко направленные либы, а не всеобемлю‐ щие монстры. Я тим лидер команды проекта incomeproject.com (это большая площадка для создания партнерских программ), могу ска‐ зать, что использование сторонних библиотек осложнено как минимум по таким причи‐ нам:чтобы использовать такую библиотеку в серьезном проекте ей нужно полностью дове‐ рять, чтобы ей доверять ее надо изучить и обкатать на каком‐либо «не важном» проекте, таких обычно нет. Нужно полностью понимать область при‐ менения, условия работы Фреймворка, мето‐ дологию решения проблем, которую он пред‐ лагает. если этого нет, то вы рано или поздно встанете в ситуацию когда Фреймворк не удовлетворяет ваших требований и нужно писать «костыль» тут то вы и попадете в ло‐ вушку когда нужно ставить еще и еще костыли. поставить костыль корректно (под нужным углом) и не нарушить логической целостности работы приложения основанной на FW вы все равно можете только в случае если понимаете идеологию решения задачи, которая заложена в Фреймворк. Таким образом что б начать пользовать Фреймворк вам нужно: 1. попробовать его где либо в слабо зна‐ чительном месте. 2. изучить всю доку и знать типичные примеры, желательно потусовать в сообщест‐ вах и узнать типичные проблемы 3. понять идеалогию решения (большой Фреймворк, много авторов, а значит много разношерстных решений) 4. осознать ВСЕ уровни абстракций ис‐ пользуемых в Фреймворке.

5. написать где‐то долго играющий, но опять же критичный проект на этом Фрейм‐ ворке. Вот, только теперь можно использовать данный Фреймворк в своих проектах… все что я тут написал — это мое мнение, моя позиция, но она основана на опыте человека, который написал системы на PHP (ну и не только php), работающие на свыше 5‐ти машинах как с функциональным распределением вычисле‐ ний, так и с распределением вычислений по данным и прекрасно масштабируемы. Доверие к С++, С и Java обусловлено вовсе не одним фактом бренда, который за ними стоит, хотя и им тоже, но еще и старостью технологии Java`е тока не давно сан сделал полную среду свою, а до этого так же были склады решений и все рылись в них, достаточ‐ но вспомнить эпопею с аспектным програм‐ мированием.

Почему я использую свои разра‐ ботки и предпочитаю изучать патерны, а не Фреймворки? 1. знание паттернов программирования дает вам не само блюдо, а рецепт как пригото‐ вить блюдо, вы вольны использовать любые поваренные приборы: PHP JAVA С++. 2. вы сможете добавить специи по сво‐ ему выбору, если вы работаете в команде, то у вас больше шанцев изменить рецепт до приго‐ товления, так чтоб ни у кого из членов коман‐ ды не было аллергии на отдельные его части. 3. вы можете использовать сезонные и свежие овощи! например, если только что появилась возможность использовать найм‐ спайсы, вы их любите, то вы уже можете вклю‐ чить их в состав своих блюд! я очень сомнева‐ юсь, что шеф повар вашего любимого Фрейм‐ ворка обладает достаточной гибкостью чтоб сделать это. 4. худеем — нужно меньше калорий… я думаю, что вам не зачем тащить с собой всю инфраструктуру Фреймворков просто, чтоб оно работало «как всегда» или на «всякий случай», вы же готовите!, а значит, на столе не должно быть ничего лишнего.

5. «используйте только соевый соус» — подумайте должны ли вы так строго соблю‐ дать рецепт?? а что если вам хочется кетчуп? отказаться от таматов? ограничения вызван‐ ные использованием готового фраймворка иногда оказываются очень серьезными и вам не нужными. Это только общие замечания, есть част‐ ные, например, вы знаете, что в вашем случае контекст задачи подразумевает упрощение какого — либо механизма, в рамках фрайм ворка это упрощение (логики, абстракций, производительности) обычно сложно сделать, но на вашей кухне вы можете себе позволить это.я выделяю такие плюсы/минусы:

Свои велосипеды Минусы: 1. нет сообщества, которое обсудит ВАШУ проблемму 2. велика вероятность «глупых» оши‐ бок 3. вы варитесь в собственном соку — не знаете новых методов если всегда все делаете сами 4. Сложно предать проект другим лю‐ дям Плюсы: 1. вы имеете полную свободу выбора, все что вы делаете вы можете сделать как вам угодно 2. в любом месте вы можете вставить новое решение и будете знать как это из‐ менит вашу систему 3. вы можете решить любую пробле‐ му! вы автор системы, вам подвластны решения 4. все органичения вам подвластны В итоге вы рискуете, но вы гарантированы от того чтоб зайти в тупик, а с Фреймворком (особенно большим вы не гарантированны).

8


magmoro MooTools → Классы в MooTools http://habrahabr.ru/blogs/mootools/39794/ Создать свой класс в MooTools очень про‐ сто: //Example 1 var someClass=new Class({ initialize: function(){ alert('Hello, world!'); } }); Всё, класс готов. Теперь можно создавать объекты данного класса: var classObject=new someClass(); Результат — алерт со словами: «Hello, world» пример 1 initialize — конструктор класса. Вызывает‐ ся автоматически при создании экземпляра класса. (не вызывается, если первый аргумент при создании объекта класса — $empty)

Здесь четыре метода(не включая конст‐ руктора) — draw, hide, show и toggle. • draw делает элемент крассным с синей границей • hide скрывает элемент • show показывает элемент • toggle изменяет види‐ мость элемента

Implements: [Options] означает — доба‐ вить все методы класса Options в данный класс. Класс Options имеет только один метод — setOptions.

Пример использования: var elMgr= new testClass('el'); elMgr.draw(); (function(){ elMgr.toggle(); }).periodical(1000); Результат — элемент делается красным, и мигает каждую секунду.пример 2. Обратите внимание, чтоб вызвать метод show из метода toggle используется this.show(); this — это магическая переменная.

У класса могут быть методы: //Example 2 var testClass=new Class({ initialize: function(element){ this.element=$(element); }, draw: function(){ this.element.setStyles({ 'background‐color': 'red', border: 'solid 1px blue' }); }, hide: function(){ this.element.setStyle('display', 'none'); }, show: function(){ this.element.setStyle('display', 'block'); }, toggle: function(){ this.element.style.display == 'none'? this.show(): this.hide(); } });

}); } });

Implements Магическое свойство Implements добавля‐ ет новые методы в класс. Классический при‐ мер — добавление метода setOptions. //Example 3 var exampleClass3=new Class({ Implements: [Options], options: { // опции по умолчанию bgColor: 'red', borderWidth: 1 }, initialize: function(element, options){ this.setOptions(options); this.element=$(element); }, draw: function(){ this.element.setStyles({ 'background‐color': this.options.bgColor, 'border‐style': 'solid', 'border‐color': 'black', 'border‐width': this.options.borderWidth

Если опции не заданы, будут использова‐ ны опции по умолчанию (цвет — красный, толщина границы — 1px). Примеры использования класса: var elMgr=new exampleClass3('el', { bgColor: 'yellow' }); пример 3 Implements обычно используется чтоб до‐ бавить методы в новый класс. А так добавля‐ ются методы в уже созданый класс: //example 4 someClass=new Class(); someClass.implement({ extraMethod: function(){ alert('Я — добавленный метод'); } }); (new someClass).extraMethod(); Результат — алерт: «Я — добавленный ме‐ тод» пример 4 Вопрос: «А если я добавлю метод, кото‐ рый уже существует, что произойдет?». Ответ: «В классе будет только новый метод, про старый можете забыть, его не вернуть.»

9


Options, Events и Chain. Пример c Options уже был. А вот с Events:

Extends Ещё одно магическое свойство — Extends. С помощью него создаюется новый класс рас‐ ширяющий существующий. Пример: Расширим класс из первого примера (Hello, world): //example 5 var extendedSomeClass=new Class({ Extends: someClass, initialize: function(){ this.parent();//вызываем метод initialize базового класса alert('extended Hello, world!'); } }); new extendedSomeClass();* This source code was highlighted with Source Code Highlighter. Результат — алерт «Hello, world!» из мето‐ да initialize базового класса и алерт «extended Hello, world!» пример 5 Вопрос: «А есть ещё какие‐нибудь магиче‐ ские методы, кроме Implements и Extends?» Ответ: «Нет, но можно добавить в Class.Mutators, пример — Binds Mutator»

Class.Extras В MooTools есть несколько классов, кото‐ рые очень часто используются. Это классы

//example 6 var exampleClass6=new Class({ Implements: [Options, Events], options: { // опции по умолчанию bgColor: 'red', borderWidth: 1 }, initialize: function(element, options){ this.setOptions(options); this.element=$(element); }, draw: function(){ this.element.setStyles({ 'background‐color': this.options.bgColor, 'border‐style': 'solid', 'border‐color': 'black', 'border‐width': this.options.borderWidth }); this.fireEvent('draw');//event draw } }); var obj=new exmpleClass6('el', { bgColor: '#561', borderWidth: 4 }); obj.addEvent('draw', function(){ alert('draw выполнен'); }); obj.draw();

В данном примере событие добавлено яв‐ но с помощью метода addEvent. Событие можно также добавить, указав его в options с префиксом on и первой прописной: var obj=new exampleClass6('el', { bgColor: '#561', borderWidth: 4, onDraw: function(){ alert('draw выполнен'); } }); пример 6 В options существует магическое свойство — initialize, выполняемое после конструктора класса: //example7 var someClass=new Class({ Implements: [Options], options:{ initialize: function(){ alert('after initialize'); } }, initialize: function(){ alert('initialize'); } }); пример 7 Основы изложены, если есть вопросы — задавайте. Ответы на все вопросы можно най‐ ти в документации. И помните, лучшая доку‐

addEvent — добавить событие fireEvent — выполнить событие

ментация — исходный код. архив с примерами

10


Lite перевод

Типографика → Десять смертных грехов веб‐типографики http://habrahabr.ru/blogs/typography/36654/ http://www.smashingmagazine.com/2008/08/11/top‐ten‐web‐typography‐sins/

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

1. Использование дефисов вместо тире em‐dash.

Если вам нужно прервать мысль, то делайте это с помощью символа (alt+0151), а не парой знаков «минус». Это, пожалуй, главный источник раз‐ дражения для всех редакторов.

2. Использование точек вместо многоточия.

Большинство шрифтов предоставляет специальный символ многоточия (alt+0133), который сделает ваш текст более аккуратным. Символ многото‐ чия помещает три точки в один символ, что особенно удобно для дальнейшей печати.

3. Использование неправильных кавычек

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

4. Двойной пробел между предложениями.

Практика двойных пробелов для разделения предложений, судя по всему, выходит из употребления. Всего несколько лет назад требовалось вруч‐ ную вставлять ASCII‐пробел чтобы совершить этот моветон. Но и сегодня некоторые CMS, если им позволить, могут совершить эту ошибку за вас. Не дайте им этого шанса! Используйте между предложениями исключительно одиночные пробелы.

11


5. Импровизированный символ копирайта.

Это не только выглядит уродливо и говорит о вашей лени, но и будет работать против вас в суде. Используйте настоящий символ (alt+0169) и запи‐ шите клиенту в счёт юридическую услугу. :)

6. Слишком много ударений.

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

7. Неправильное подчеркивание гипертекстовых ссылок.

Подчёркивание рисуется поверх нижней части ваших символов, затрудняя чтение. Вместо text‐decoration: underline; используйте border‐bottom: solid 1px #00f; для того, чтобы нарисовать линию под текстом.

8. Подправление шрифтов в Фотошопе.

Если ваш шрифт не имеет полужирное, курсивное начертания и капитель, то не старайтесь подделать их в Фотошопе. Это иногда срабатывает в пе‐ чатных материалах, но при экранном разрешении современных веб‐страниц это будет выглядеть криво.

9. Избегание символов с акцентом.

Я знаю, насколько они могут раздражать (особенно если вы пишите о мебели IKEA), но если чьё‐то имя включает в себя экзотические символы, то будьте вежливы и используйте именно их.

10. Неиспользование CSS для изменения регистра текста.

12


Caps Lock — неотъемлемый элемент крутизны, но если вы хотите отображать текст исключительно прописными (или строчными) буквами, то де‐ лайте это с помощью CSS‐свойства text‐transform. Это избавит вас от многих проблем в будущем, если вы вдруг захотите сменить стиль оформления. От переводчика: перевод сделан с любезного соглашения редактора Smashing Magazine. Я рекомендую подписаться на RSS этого сайта, так как ста‐ тьи у них весьма интересные и красивые. От переводчика 2: Самой собой, данный перевод не претендует на истину в последней инстанции. Почитайте комментарии, в которых немало ра‐ зумных уточнений и поправок.

13


Ordos

.NET → Использование провайдеров компиляции в asp.net http://habrahabr.ru/blogs/net/40047/

В качестве вступления В Asp.net любая интернет‐страница пред‐ ставляется в виде двух файлов: *.aspx и *.aspx.cs. В *.aspx‐файлах содержится html‐ подобная разметка самой страницы, а в *.aspx.cs‐файлах код на языке C#, который представлен в виде отдельного класса. В разметку страницы можно добавлять серверные элементы управления, например тегом <asp: Button ID=«MyButton» runat=«server» />. Причём с каждым таким объявлением бу‐ дет связана переменная, то есть в нашем слу‐ чае мы получим доступ к переменной типа Button и именем MyButton, хотя на первый взгляд эта переменная нигде не объявлена. (Хотя в первой версии Asp.net объявление переменных вставлялись в тот же файл.) На самом деле это не так. Класс, описаный в *.aspx.cs‐файле является частичным (он по‐ мечен модификатором partial), одна его часть описана в *.aspx.cs‐файле, а вторая находится во временном файле, который генерируется на основании просмотра *.aspx‐файла. Гене‐ рацией этого временного файла как раз и занимается провайдер компиляции.

Пишем провайдер компиляции 1. Определимся, что будет делать провай‐ дер компиляции. Чтобы особо не мудрить, пусть он выполняет преобразование xml‐файла вида: 1. <classes> 2. <class name=«С1»> 3. <property type=«int» name=«x1» val‐ ue=«17» /> 4. <property type=«string» name=«x2» val‐ ue=«Hello, World!» /> 5. </class> 6. <class name=«С2»> 7. <property type=«int» name=«x1» value=«‐ 5» /> 8. <property type=«string» name=«x2» val‐ ue=«Это строка!» /> 9. </class> 10. </classes>

в статический класс, содержащий констан‐ ты. 2. Создадим новый проект. В качестве типа проекта выберем «Class Library», назовём его «MyLib». 3. Все провайдеры компиляции являются про‐ изводными от класса «System.Web.Compilation.BuildProvider», по‐ этом добавим ссылку на сборку «System.Web» и используемые пространства имён. Конструктор класса ничего не выполняет, а вот метод «GenerateCode» нам потребуется пере‐ определить. В итоге должно получиться сле‐ дующее: 1. using System; 2. using System.Web.Compilation; 3. using System.Xml; 4. using System.IO; 5. using System.Web.Hosting; 6. 7. namespace MyLib 8. { 9. public class MyBP: BuildProvider 10. { 11. public MyBP() { } 12. 13. public override void Generate‐ Code(AssemblyBuilder assemblyBuilder) 14. { 15. //В переменную writer будем записы‐ вать генерируемый код 16. using (TextWriter writer = assemblyBuild‐ er.CreateCodeFile(this)) 17. { 18. //Создаём xml‐документ используя путь к анализируемому файлу 19. XmlDocument xml = new XmlDocument(); 20. xml.Load(VirtualPathProvider.OpenFile(b ase.VirtualPath)); 21. 22. //Получаем все классы 23. XmlNodeList classes = xml.GetElementsByTagName(«class»); 24. foreach (XmlNode _class in classes) 25. { 26. //Получаем название класса 27. string cName = _class.Attributes[«name»].Value; 28. if (cName == null || cName.Length == 0) continue; 29. 30. //Получаем поля класса 31. string cProperties = «»; 32. 33. //Получаем все поля 34. XmlNodeList properties = _class.ChildNodes;

35. foreach (XmlNode property in proper‐ ties) 36. { 37. if (property.Name != «property») continue; 38. 39. //Получаем тип поля 40. string pType = proper‐ ty.Attributes[«type»].Value; 41. if (pType == null || pType.Length == 0) continue; 42. 43. //Получаем название поля 44. string pName = proper‐ ty.Attributes[«name»].Value; 45. if (pName == null || pName.Length == 0) continue; 46. 47. //Получаем значение поля 48. string pValue = proper‐ ty.Attributes[«value»].Value; 49. if (pValue == null || pValue.Length == 0) continue; 50. 51. //Если поле имеет строковой тип, берём его в кавычки 52. if (pType == «string») pValue = string.Format(«\»{0}\«», pValue); 53. 54. //Добавляем поле 55. cProperties += string.Format(« public const {0} {1} = {2}; „, pType, pName, pValue); 56. } 57. 58. //Добавляем класс 59. writer.Write(“ public static partial class „ + cName + “ { „ + cProperties + “ } „); 60. } 61. } 62. } 63. } 64. } Компилируем и получаем сборку. 4. Создаём новый сайт (Назовём его MySite). Первое, что нужно сделать, создать папки bin и App_Code. В папку bin скопируем только что созданную библиотеку. Теперь нужно подклю‐ чить провайдер компиляции. Для этого идём в файл Web.config и в разделе compilation до‐ бавляем блок: 1. <buildProviders> 2. <add type=“MyLib.MyBP, MyLib» exten‐ sion=«.cc» /> 3. </buildProviders> Это определение говорит, что для файлов с расширением «cc» будет использован про‐ вайдер компиляции MyLib.MyBP, который будет взят из сборки MyLib«.

14


сять, когда файл обработается) в любом C#‐ коде можно будет использовать классы „C1“ и 5. Создаём файл „my.cc“ в папке „App_Code“ с „C2“ и их константные поля. (Результаты мож‐ xml‐кодом, вроде того, что приведён выше. но увидеть на скриншотах) Через некоторое время (обычно секунд де‐ 6. Скриншоты: Документ, обрабатываемый провайдером компиляции:

Появились классы „C1“ и „C2“:

15


И их поля:

Ну и в качестве концовки

PS: Я не нашёл способа не помещать про‐

Литература: Дино Эспозито „Asp.net 2.0 Углублённое изучение“.

вайдер в отдельную сборку, а просто добавить

Безусловно данный пример не может пре‐

класс в папку App_Code. В данном случае воз‐

Огромное спасибо выражаю пользователю

тендовать на полноценный провайдер компи‐

никает ошибка о невозможности загрузить

zabr за советы и помощь, а так же всем, кто

ляции, а показывает только общую идею, в

тип.

помог опубликовать этот топик.

коде я опустил многие проверки, обработку

исключений пожертвовал оптимальностью

Надеюсь, что найдутся люди, которые

ради сокращения кода.

знают решение данной проблемы.

16


murr

Web‐разработка → Ajax‐машина http://habrahabr.ru/blogs/webdev/40023/

Знали ли разработчики LiveScript из Netscape о том, какое влияние окажет их язык, позже переименованный в JavaScript, на лицо интернета — веб‐сайты, или, может быть, они твердо на это рассчитывали, но факт остается фактом — JavaScript на сегодняшний день является одним из самых важных и распро‐ страненных языков в мире. В то время, как на стороне сервера трудит‐ ся разношерстная компания языков в лице php, perl, python, ruby, .net, java и многих дру‐ гих, на стороне клиента JavaScript существует буквально в гордом одиночестве. Фактически, из маленького дополнения к html, JavaScript превратился в полноправного члена банды «html+css+js», который, зачастую, уже коман‐ дует остальными, сверкая золотым браслетом с надписью «ajax» и делая недовольное лицо $( ) при случае. Данный материал не является попыткой объять необъятное, скорее, это попытка хоро‐ шенько необъятное полапать.

О чем статья и для кого она предназначена В этой статье мною была предпринята по‐ пытка описать комплексный способ построе‐ ния Rich Internet Applications с помощью JavaScript — паттерн «AJAX‐машина». Целевая

аудитория статьи — разработчики RIA и сочув‐ ствующие им программисты и менеджеры. На сегодняшний день потребность в Rich Internet Applications возникает в самых разных облас‐ тях веб‐разработки: браузерные игры, персо‐ нальные менеджеры, системамы товаро‐ и документооборота, системы управления биз‐ нес‐процессами — т.е. любое, веб‐ приложение, требующее сложной логики на строне клиента. В RIA‐виде зачастую пережи‐ вают реинкранацию даже традиционно на‐ стольные приложения: почтовые клиенты, IM, всевозможные редакторы и даже операцион‐ ные системы! Хочу сразу предупредить уважаемого чи‐ тателя о том, что данный материал:

во‐первых, не является развлека‐ тельной статьей, зачастую повествование идет достаточно сухо, к тому же, требует от читате‐ ля некоторых познаний в области веб‐ разработки;

• во‐вторых, написан мною лично, по‐ этому субъективен, хотя я старался быть мак‐ симально непредвзятым в процессе; • в‐третьих, из‐за стремления к крат‐ кости многие вещи освещены слабо, либо же, не освещены вовсе; • и, наконец, в‐четвертых, мне хоте‐ лось бы честно предупредить, что я могу не знать всех тонкостей и нюансов освещаемой темы, поэтому с радостью приму помощь в комментариях.

Ко всему прочему, я уверен, что не явля‐ юсь первооткрывателем идеи; свою задачу я вижу в некоторой систематизации материала и попытке скромными силами донести до ува‐ жаемого читателя суть идеи. Хотелось бы под‐ черкнуть особо, что областью компетенции статьи является только процесс разработки Rich Internet Applications; эта статья совершен‐ но не претендует на вмешательство в подход к разработке классических веб‐сайтов: порта‐ лов, блогов, новостных лент и прочих. Итак, с позволения читателя, приступим!

Нужен ли JavaScript для веба? Читатель может справедливо отметить, что я начал статью с весьма нескромного абза‐ ца, наделив js статусом важного и очень рас‐ пространенного языка. Соответствует ли это истине в действительности? Очевиден тот факт, что js по умолчанию считается поддерживаемым на компьютере, если там присутствует полноценный графиче‐ ский браузер. На сегодняшний момент — это огромное число компьютеров. Однако есть ли у js шансы на признание со стороны крупных компаний, как у языка зрелого и, в полной мере, достаточного для написания RIA? Пред‐ лагаю читателю несколько аргументов:

Кому нужен JavaScript? Adobe AIR

AIR (Adobe Integrated Runtime) — это среда для запуска приложений, позволяющая использовать HTML/CSS/JavaScript, Adobe Flash и Adobe Flex для переноса веб‐программ (RIA) на настольные ПК. AIR‐приложения могут обмениваться информацией с интернетом, использовать некоторые особенности ОС, на которой запускаются (к примеру работать с треем/доком), а так же хранить данные локально, с помощью БД SQLite. По сути же, AIR пред‐ ставляет собой браузер на основе движка WebKit, со специфичными возможностями, доступными через JavaScript‐ API. Поддерживаемые платформы: Microsoft Windows NT, Mac OS X, альфа‐версия для GNU/Linux.

17


iPhone

iPhone — семейство мобильных телефонов, работающих на модифицированной ОС MacOS X. Первоначально фирма создатель — Apple — не позволяла сторонним разработчикам писать нативные приложения для iPhone, пред‐ лагая создавать оптимизированные веб‐приложения(html+css+js). Лишь спустя некоторое время вышел iPhone SDK, позволивший писать полноценные «десктопные» программы, однако возможность создавать веб‐приложения нику‐ да не исчезла, и по сей день актуальна.

Google Gears

Google Gears — открытая разработка от Google, позволяющая использование веб‐приложений в режиме оф‐ флайн. Поддерживаются все популярные бразуеры:, Firefox, Internet Explorer, Safari (сомнения возникают с Оперой, но они обещали) и, само‐собой, Chrome. Gears представляет собой специальный плагин, который заставляет браузер работать с локальным кэшем страниц (на основе SQLite), периодически синхронизируя кэш с онлайн источником. Мостик между Gears и клиентским кодом перекинут с помощью JavaScript.

Mozilla Prizm

Mozilla Prizm — разработка компании Mozilla, использующая движок Firefox. Если коротко, то Призма, в основе, позволяет делать две вещи — создавать на рабочем столе ярлыки веб‐сайтов и открывать их в независимом окруже‐ нии (отдельный процесс браузера, со скрытыми системными меню и т.д.), как будто это программа на вашем ло‐ кальном ПК. В связке с Google Gears способна составить конкуренцию AIR от Adobe, или даже наоборот, дать фору, потому что у FF+GG получается кроссплатформенное решение — 100% поддержка Linux, MacOS и Windows — да еще и с открытым кодом.

Google V8

V8 представляет собой высокопроизводительный интерпретатор JavaScript, реализующий стандарт ECMA‐262. Работает на Windows XP, Vista, Mac OS X 10.5 (Leopard) и Linux‐системах на процессорах IA‐32 и ARM. Hint! V8 реали‐ зован на C++ и может использоваться как отдельный интерпретатор или как встроенный в любое приложение на C++. Всем известно, что V8 встроен в Chrome по умолчанию. Заявляется, что интерпретатор очень быстрый благодаря трансляции кода в инструкции процессора «на лету» (JIT).

TraceMonkey

TraceMonkey — Новый быстрый движок JavaScript для Firefox, так же основанный на принципе JIT. Работает на процессорах x86, x86‐64, и ARM — к слову, как и V8, он может полноценно работать и на некоторых типах мобильных устройств. По всем признакам, появится в FF к концу года, хотя попробовать в деле его можно прямо сейчас.

18


Что умеет JavaScript? Дабы не увязнуть в длительном описании всех парадигм, которые поддерживает js, всех его возможностей, синтаксических контрукций и прочего, приведу несколько небольших примеров. Для ознакомления с языком их явно не хватит, однако, некоторое представ‐ ление о языке они все же помогут сформиро‐ вать. Функция может принимать произвольное количество аргументов function add(){ var sum = 0; for(var i = 0; i < arguments.length; i++){ sum+= arguments[i]; } return sum; } add(1,1,1,1,1); // вернет 5 add(2, 3); // вернет 5 Функцию можно вызвать и без аргумен‐ тов совсем function sayMyName(name){ name = name ||'неизвестно'; return'Мое имя: ' + name; } sayMyName('Дэвид'); // вернет 'Мое имя: Дэвид' sayMyName(); // вернет 'Мое имя: неизвестно' Функция, как объект первого класса function add(a, b){ return a + b; } function sub(a, b){ return a — b; } function doAction(action){ return action(2, 1); }

doAction(add); // вернет 3 doAction(sub); // вернет 1 Замыкания function someAction(){ var firstAction = function(){ return 'Hello,'; } var secondAction = function(){ return firstAction() + ' Habr!'; } return secondAction; } var act = someAction(); act(); // вернет 'Hello, Habr!' ООП с нюансами Спасибо Iskin function Food(type){ this.type = type; } var foo = new Food('orange soda'); var bar = new Food('cheeses'); foo.type; // вернет 'orangeSoda' bar.type; // вернет 'cheeses' Динамическое изменение объектов function Food(type){ this.type = type; } var foo = new Food('orange soda'); var bar = new Food('cheeses'); Food.prototype.say = function(){ return 'ORLY! This is ' + this.type + '!'; } foo.say(); // вернет ORLY! This is orange soda! bar.say(); // вернет ORLY! This is cheeses!

живаемых множеством людей по всему миру, из самых популярных можно выделить: JQuery, Prototype, Mootools, ExtJs, Yahoo UI. Любая из этих библиотек прямо сейчас готова стать основой для написания пользовательско‐ го интерфейса RIA. Извиняюсь перед читате‐ лем за отсутствие описания, к сожалению, это большая тема для отдельной статьи, поэтому привожу только ссылки. Надеюсь, эти аргументы достаточно убе‐ дительны для того, что бы считать js признан‐ ным, полноценным и удобным языком, под‐ ходящим для написания RI приложений. А теперь, если дорогой читатель не уснул, я перехожу описанию того, ради чего и затевал статью.

AJAX‐машина Концепция паттерна: Всю логику храним на сервере, весь интерфейс формируем у кли‐ ента. Приложение, созданное по паттерну, реализует трёхзвенную архитектуру. Загрузка приложения (всего кода html, css и js происхо‐ дит один раз, при первом обращении. Спасибо shiko_1st и jodaka Что бы читателю было проще понять суть, опишу ее кратко: браузер клиента делает за‐ прос на приложение. Ему сразу же отдается единственная html страница, все стили, весь необходимый js‐код для приложения и, воз‐ можно, вся статическая графика. После загрузки каркасной dom‐модели документа, JavaScript отрисовывает интер‐ фейс; кроме того, js заведует коммуникациями с внешним миром, посредством ajax‐запросов. В свою очередь, сервер занимается только выдачей статики и обработкой ajax‐запросов от клиента. В идеале, сервер не должен уметь писать в поток вывода ничего, кроме JSON. Предложенная архитектура изображена с помощью следующей схемы (изображена моими скромными силами, да простит меня читатель):

Для языка существует большое количество качественных свободных библиотек, поддер‐

19


На схеме наличествуют 3 уровня, соответ‐ ственно: Зеленый или Клиентский уровень. 1. На этом уровне приложение создает пользова‐ тельский интерфейс в браузере, обрабатывает действия пользователя и посылает запросы на сервер. Для этого уровня работают художники, дизайнеры и js‐программисты. Так же, на зе‐ леном уровне может быть и другой сервер, в случае, если вы открыли API для межсерверно‐ го взаимодействия. 2. Красный или Уровень протокола. Красный цвет символизирует критичный уча‐ сток в разработке AJAX‐машины — хороший формат обмена данными позволит сделать клиент и сервер независимыми друг от друга, легко распределять нагрузку на несколько серверов, добавлять новые возможности, без переделок архитектуры. Красный уровень обеспечивается http(s) транспортом, обмен идет в виде JSON‐пакетов. JSON выбран не зря: во‐первых, он более компактный по размеру передаваемых данных, по сравнению с чистым XML, а во‐вторых, это родной формат данных для js. 3. Синий или Уровень сервера. Здесь трудятся «серверные» языки, так же, как и программисты на этих языках :) На схеме была предпринята попытка изобразить общий вид масштабируемого решения, с роутером запро‐ сов или (и) балансировщиком нагрузки и не‐ сколькими серверами. Роутер — это входная точка (Front Controller) сервера, так же, он должен отдавать статику. Синий уровень явля‐ ется самым гибким с точки зрения архитекту‐ ры, уровнем AJAX‐машины. К примеру, здесь можно поставить один очень мощный сервер с FastCGI или же два сервера с php, разделив между ними функционал, или вообще, десяток

одинаковых по функционалу серверов с Ruby. Для сервера можно выбрать любой язык или даже несколько разных языков, удовлетво‐ ряющих поставленным задачам, с учетом того, что от них потребуется выводить только отве‐ ты в виде JSON и динамическую графику, если в ней есть необходимость.

Аспекты В лучших традициях велосипедостроения, все еще не потерявшему интерес читателю можно предложить хороший способ модуль‐ ного деления логики — аспекты. Аспект — это логически неделимый процесс, происходящий с вашим приложением. Что бы прекратить заумные формулировки, приведу примеры аспектов: «Регистрация», «Новости», «Автори‐ зация», «Сообщения». В идеальном случае, один аспект не должен ничего знать об ос‐ тальных, взаимодействуя только с БД или файловой системой напрямую. Грамотно спроектированная структура аспектов и связей между ними позволяет разнести самые «тяже‐ лые» по производительности аспекты на раз‐ ные сервера, или(и) выделить одному аспекту несколько серверов с балансировкой нагрузки между ними. Очень интересная тема для размышления, в контексте работы с несколькими серверами БД, однако выходит далеко за рамки этой статьи, ровно как и обеспечение безопасности, к сожалению. Касательно безопасности хочу лишь сказать банальность, проверенную на

практике: без четкого осознания всей коман‐ дой того, что клиент находится в руках врага, а сервер представляет собой осажденную кре‐ пость, без резервного копирования, без меха‐ низма логирования и без хорошего системного администратора проект лучше не начинать вовсе. Для большой системы логи, по моему мнению, целесообразно хранить только в БД, однако у опытного читателя могут быть свои соображения, которыми, я надеюсь, он поде‐ лится в комментариях.

Базы данных Все современные СУБД позволяют писать и выполнять хранимые процедуры, и разра‐ ботчику крупной системы противопоказано пренебрегать этой возможностью. Выработав четкие правила именования процедур и аргу‐ ментов, можно смело перекладывать все тя‐ желые запросы на саму СУБД. Совершенно не рационально и крайне расточительно получать от сервера БД огромную выборку с тем, что бы, после дополнительной обработки, пере‐ дать клиенту три значения. Хочу уверить ува‐ жаемого читателя, не знакомого с прелестями хранимых процедур в том, что:

• во‐первых, в написании таких проце‐ дур нет ничего сложного; • во‐вторых, они дают, зачастую, гораз‐ до большую свободу для манипуляций дан‐ ными, чем диалект SQL для конкретной СУБД;

20


• в‐третьих, позволяют осуществлять черновую обработку и отсеивание данных на сервере БД, не повышая трафик между, собст‐ венно, сервером БД и сервером приложения; • в‐четвертых, значительно проще вы‐ звать одну процедуру, чем запрос на 400 строк с различным подстановками параметров (пе‐ чальный случай из практики).

Сценарий работы Ajax‐машины JavaScript рисует для пользователя форму авторизации, пользователь вводит логин и пароль, на сервер отправляется JSON‐пакет вида:

Аспект принимает данные, и устраивает свою проверку, на соответствие полей пакета эталонным. Если все верно, он авторизует пользователя Vasiliy с паролем ********, и отправляет следующий пакет клиенту: { action: 'authorization', status: 'authorize', options: { user_name: 'Vasiliy Pomidorov', permission: 'super_user' }, date_in: '25082008‐221500', date_out: '25082008‐221501' } Js на стороне клиента получает пакет, вы‐ водит какое‐нибудь банальное сообщение в виде: «Добро пожаловать, Vasiliy Pomidorov» и разблокирует дополнительные действия для super_user'а.

{ action: 'authorization', status: 'request', options: { login: 'Vasiliy', pass: '********' } } Пакет следует через сеть к роутеру, кото‐ рый, как минимум, проверяет пакет на мини‐ мальный и максимальный допустимые разме‐ ры и на количество запросов от узла в единицу времени (что бы исключить перебор). В слу‐ чае, если все хорошо, переправляет данные аспекту «Авторизация» (это может быть мо‐ дуль, класс, программа, отдельный сервер и еще что‐нибудь), к примеру, в очередь, в виде: { action: 'authorization', status: 'in_queue', options: { login: 'Vasiliy', pass: '********' }, date_in: '25082008‐221500' }

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

зованного пользователя до выяснения обстоя‐ тельств, в крайних случаях применимо блоки‐ рование по ip и маске подсети (в случае DoS/DDoS атак).

Эпилог Прежде всего, благодарю тебя, читатель, сумевшего пройти через ряды немного зануд‐ ного, но, надеюсь, полезного текста — Спаси‐ бо! Хотелось бы быть уверенным в том, что кому‐то данный материал действительно по‐ может сформулировать свои мысли, других подтолкнет на путь разработчиков Rich Internet Applications, а может даже, повлияет на созда‐ теля гениального и ужасно уникального стра‐ тапа (тешу себя надеждой :) Очень жаль, но за рамками статьи оста‐ лось много интересных материалов: тут и сравнение по пунктикам JavaScript и Adobe Flash, плюсы и минусы «больших» веб‐ фреймворков для создания RIA, лавирование между SOAP и REST, задачи и проблемы про‐

{ action: 'authorization', status: 'deny', options: { code: 99 //неверный логин или пароль }, date_in: '25082008‐221500', date_out: '25082008‐221501' } В случае критичной проблемы, к примеру: флуд пакетами, постоянные разнообразные ошибочные запросы от узла и т.д., следует принять более жесткие меры: вынести преду‐ преждение или вовсе заблокировать автори‐

цесса создания системы скриптов для автома‐ тического тестирования и разворачивания клиентского js‐кода, централизованное ис‐ пользование микроформатов… Много, ох как много интересных тем мож‐ но осветить, описать, откомментировать, от‐ бросить за ненадобностью или принять на вооружение, отхоливарить, в конце‐концов, на страницах Хабрахабра :) Дело за тобой, ува‐ жаемый читатель!

21


KalGaN Web‐разработка → Верстка для мобильных устройств http://habrahabr.ru/blogs/webdev/40128/ Общая информация Так как мобильных устройств существует великое множество, то одна модель может поддерживать какие‐либо возможности HTML/CSS, а другая наоборот — либо не под‐ держивать, либо поддерживать неправильно. Но большинство устройств среднего и уж тем более hi‐end класса поддерживают HTML/CSS в той или иной степени. Таким обра‐ зом, язык WML для разработки сайтов под мобильные устройства устарел и практически не используется. На смену ему постепенно приходит общепризнанный стандарт в разра‐ ботке сайтов — XHTML/CSS. Кодировка — стро‐ го UTF‐8 (No BOM).

DOCTYPE, используемый для мо‐ бильных устройств Практически везде на известных мобиль‐ ных сайтах, таких как Google, Яndex, использу‐ ется DOCTYPE XHTML Mobile 1.0: <?xml version="1.0" encoding="UTF‐8"?> <!DOCTYPE html PUBLIC "‐//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml‐ mobile10.dtd"> Также, иногда встречаются сайты с DOCTYPE XHTML Basic 1.1: <?xml version="1.0" encoding="utf‐8"?> <!DOCTYPE html PUBLIC "‐//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml‐ basic/xhtml‐basic11.dtd"> На мой взгляд, предпочтительнее использо‐ вать первый вариант.

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

<style type="text/css"> body { background‐color: #E9E9CC; font‐family: sans‐serif; font‐size: small; } </style> Я не уверен насчет этого, но вполне возможно, что таким образом можно достичь совмести‐ мости с некоторыми устаревшими мобильны‐ ми устройствами. В то же время, например, браузер Opera Mini вполне справляется с этим. Верстка должна быть организована таким образом, чтобы в случае необходимости кон‐ тент оставался читабельным даже при невоз‐ можности подключения устройством стилей. Сокращенная запись свойств Есть мнение, что стили вроде padding и margin нужно прописывать отдельно, исполь‐ зуя padding‐left, padding‐top, margin‐right и т.д. Точно так же следует поступать со всеми свой‐ ствами, которые имеют короткую запись. На‐ пример красный цвет фона стоит лучше запи‐ сать как background‐color: #ff0000;, а не background‐color: #f00; и тем более не background: #f00;. Фон элементов Нежелательно использовать изображения в качестве фонов, т.к. многие устройства их могут просто не поддерживать. Если они все‐ таки используются, то необходимо задавать подходящий под фон цвет и проверять, как будет смотреться сайт без изображения. Изображения Все изображения на сайте желательно за‐ ключать в тег <img> и не забывать добавлять атрибут alt, потому что загрузка изображений на устройстве может быть отключена, и вместо него нужно вывести замену текстом, ну и в конце концов, — мы ведь XHTML используем. ;‐) При подготовке изображений желательно ужимать их до минимального размера. При добавлении изображения в документ необхо‐ димо указывать его размеры атрибутами width и height.

В итоге, каждое изображение, вставлен‐ ное в документ должно иметь вид: <img src="image.gif" width="40" height="20" alt="Текстовая замена" /> Таблицы Старайтесь избегать сложных, в том числе вложенных таблиц, т.к. некоторые браузеры могут не справиться с их рендерингом и вы‐ вести кашу вместо таблицы. Также нельзя использовать атрибуты cellpadding и cellspacing, они не включены в DOCTYPE. И ни в коем случае не следует применять таблицы для верстки страниц. Таблицы не удобны в применении на маленьких экранах: чтобы прочитать объёмную таблицу, приходится применять горизонтальную прокрутку, чего тоже следует избегать учитывая, что разреше‐ ние экранов мобильных устройств несравнимо меньше, чем у настольного монитора. Списки На просторах интернета я наткнулся на упоминание о том, что некоторые браузеры, в частности встроенный браузер в телефонах Nokia некорректно отображает нумерованные и маркированные списки. Возможно это и так, но я считаю, что использовать списки можно и нужно, потому что при отключении стилей, информация остается строго структурирован‐ ной и хорошо воспринимается пользователем. Шрифты Мобильные устройства в большинстве своем имеют очень плохую поддержку шриф‐ тов, поэтому полагаться на то, что текст будет отображен именно тем шрифтом, который был задан в стилях не стоит. Но указывать хотя бы гарнитуру (serif или sans‐serif) все равно нужно. Размер шрифтов желательно задавать в относительных единицах или, что еще лучше указывать аргументы свойства font‐size в зна‐ чениях small, medium, или large.

22


Плавающие элементы

Нельзя использовать плавающие элемен‐ ты. Большинство браузеров просто не умеют их обрабатывать. Т.е. при создании верстки старайтесь не использовать такие свойства, как float, clear, overflow, clip.

• с полностью отключенными стилями и изображениями Для тестирования сайтов удобно пользо‐ ваться эмулятором Opera Mini, а также встро‐ енной функцией в Opera (для десктопа) в ме‐ ню «Вид» ‐> «Небольшой экран».

Ссылки • Mobile Web Best Practices 1.0 (W3C Recommendation) • Руководство по проектированию wap/web‐интерфейсов мобильных устройств

Мобильные браузеры Тестирование Тестирование необходимо производить в нескольких режимах:

• • •

с загрузкой изображений и стилей без загрузки изображений без загрузки стилей

• •

• Opera Developer Community — Mobile Info • •

Opera Mini (Java)

UCWEB (Java)

Internet Explorer Mobile (Windows Mo‐ bile 5/6 Pocket PC)

• •

Open Mobile Alliance

Статистика использования мобиль‐ ных браузеров

Opera Mobile (Symbian S60 2.x, Win‐ dows Mobile 5/6 Pocket PC)

• •

Web Browser for S60 (Symbian S60)

Safari (iPhone, iPod Touch) Nokia S40 Browser (Nokia S40 OS)

23


enartemy Web‐разработка → Алгоритмы организации тэгов http://habrahabr.ru/blogs/webdev/40320/ Тэги – неотъемлемая часть всех современ‐ ных сайтов и косвенный признак принадлеж‐ ности сайта к пресловутому Вэб‐Два‐Ноль. В статье я хочу рассказать об способах и алгоритмах тегирования информации. Итак, при организации тэгов существует несколько слабых и узких мест, а именно:

добавление и изменение принадлеж‐ ности тэгов к объекту.

• • • • •

создание и изменение самих тэгов. отображение тэгов на старице. поиск по тэгам. назначение алиасов тега построение облака тегов

К сожалению, универсальный алгоритм, который легко бы решал все эти проблемы автору не знаком. Далее о самих алгоритмах.

Нормальное соотношение мно‐ гое‐ко‐многим. Существует огромная таблица с тэгами, существуют огромные таблицы с тегируемой информацией. Связь между ними осуществля‐ ется через третью таблицу, которая получается очень большого размера. Так, если статей у нас 50000, а тэгов 10000, при условии что каж‐ дая статья в среднем связана с 4‐мя тэгами, получаем размер таблицы в 200000. Плюсы: нет проблем с построением облака тэ‐

гов

• •

нет проблем с алиасами.

нет проблем с созданием и изменени‐ ем тэгов

нет проблем с «выпадающим списком

тэгов»

• добавление и изменение принадлеж‐ ности тэгов к объекту затрудненно, поскольку требуется отдельный INSERT или DELETE на каждую изменяемую связь. Еще нужен INSERT при создании тэга. Если некоторые тэги в единственном числе (что часто бывает), то они будут оттягивать на себя ресурсы (увеличивая размеры таблиц), не неся при этом почти ни‐ какой практической пользы. •

получение и отображение тэгов тре‐ бует JOIN‐объединение 3‐х огромных таблиц. Из примера выше: таблица в 50000 join табли‐ ца 200000 join таблица 10000. Это будет рабо‐ тать медленно уже с этими данными. Учиты‐ вая то, что реально требуется сделать join еще 2‐3 большие таблицы (например, таблицу пользоватлей и таблицу рейтинга), получается совсем не радужная картина. Да, я в курсе, что можно кэшировать, но сейчас не об этом.

поиск по тэгам требует опять объеди‐ нения больших таблиц

С помощью полнотекстового по‐ иска

Минусы:

Алгоритм приведен в моей статье «Полнотекстовый поиск и его возможности» Теперь о том, как это делается непосред‐ ственно по отношению к тэгам. В поле с пол‐ нотекстовым индексом лежат сами тэги в том виде, как они были записаны. Выборка объек‐ тов происходит исключительно по этому полю. Исходя из этого же поля строится принадлеж‐ ность объекта к тэгам. Это означает, что если тэг русский, то и ссылка на него должна со‐ держать русские буквы. А с этим возникают проблемы, т.к. они могут кодироваться c по‐ мощью urlencode, а это зависит уже от коди‐ ровки. Т.е. один и тот же тэг в зависимости от того, в какой кодировки страница, должен быть декодирован по‐разному. Можно конеч‐ но использовать транслит русских слов в анг‐ лийские, и в писать их в поле наряду с русским

словами. Тогда тэг будет отображаться на русском, а ссылка на него будет в латинице, и поиск будет идти тоже в латинице. Плохой выход, но выход. Плюсы:

• • •

нет проблем с выводом тэгов нет проблем с поиском по тэгам

нет проблем добавлением и измене‐ нием принадлежности тэгов к объекту

• нет проблем с алиасами (точнее есть, но они решаемы) • •

отпадает проблема создания тэга

легко можно делать поиск не по од‐ ному, а по нескольким тэгам, а так же вычис‐ лять похожие материалы Минусы:

• переименовать или удалить тэг просто так не получится, это требуется в полях всех объектов, которыми назначены тэги • с построением облака тегов очень большие проблемы. Можно решить так: обра‐ батываются все «тэговые» поля таблиц, анали‐ зируется частота присутствия отдельного тэга (эх, был бы доступ непосредственно к самому полнотекстовому индексу, как было бы хоро‐ шо) и на фоне этого строится облако. После чего кэшируется на длительный промежуток времени. •

сложно сделать «выпадающий список

тэгов» Как вариант, совмещение того и другого метода. То есть поиск по полнотекстовому индексу, а частоты использования и сами тэги в отдельной таблице. Ну, или вариации на эту же тему. Это решает проблемы с выпадающим списком и облаком, но создает сложности при выводе, добавлении и создании тегов.


Lite перевод

Разработка → Архитектура приложений – горячие точки http://habrahabr.ru/blogs/development/40660/ http://blogs.msdn.com/jmeier/archive/2008/09/22/architecture‐frame.aspx

Как часть нашего проекта, мы свели вместе информацию об общих подходах к разра‐ ботке архитектуры приложений. Общие подходы представяют собой набор «горячих точек» (hot spots). Однако это не просто горячие точки. Эти горячие точки преставляют собой ключевые вопросы, проблемы и рекомендации. Все вместе они помогают вырабатывать более эффектив‐ ные с технической точки зрения архитек‐ туры. Этот список является частью более общей структуры App Arch Meta Frame. Думайте о нём, как о важной ветке большо‐ го дерева.

Категории

Следующие категории являются горячими точками в архитектуре приложения:

• •

• • • • • • • •

Аутентификация и авторизация (Authentication and Authorization) Кэширование и состояние (Caching and State) Взаимодействие (Communication) Композиция (Composition) Параллельные вычисления и транзакции (Concurrency and Transactions) Управление конфигурацией (Configuration Management) Связанность и сцепление (Coupling and Cohesion)

Горячие точки соответствуют разным сквозным функциональностям, исполь‐ зующимся при создании приложений и, соответственно, разным наборам паттернов и практик. Например, Enterprise Library обычно включает блоки, отвечающие за кэширование, управление исключениями, ведение логов, валидацию и т.д. Категори‐ ям также соответствуют разнообразные анти‐паттерны, самый плохой из которых — это анти‐паттерн «переделать заново» («do over»). :)

Доступ к данным (Data Access) Работа с исключениями (Exception Management) Ведение логов и мониторинг (Logging and Instrumentation) Взаимодействие с пользователем (User Experience) Проверка данных (Validation) Поток операций (Workflow)

Ключевые вопросы Эта таблица перечисляет ключевые вопросы для каждой горячей точки: Категория

Аутентификация и авториза‐ ция

Кэширование и состояние

Ключевые вопросы

• • • • • • • • • • • • • • • • • •

Как хранить идентификационные данные зарегистрированных пользователей? Как аутентифицировать запросы? Как авторизовывать запросы? Как передавать идентификационные данные пользователей между слоями приложения?

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


• • •

Взаимодействие

• • •

Композиция

Параллельные вычисления и транзакции

Как передавать информацию между слоями приложения? Как совершать асинхронные операции? Как передавать секретные данные?

Как спроектировать структуру приложения? Как спроектировать слабую связанность между модулями? Как работать с зависимостями в слабосвязанном режиме?

(прим. переводчика): Тут автор продублировал предыдущую категорию. Если ошибка будет исправлена в оригинале, то исправлю и перевод.

Управление конфигурацией

Связанность и сцепление

Доступ к данным

• • • • • • • • • • • • • • •

Работа с исключениями

• •

Ведение логов и мониторинг

• •

Взаимодействие с пользовате‐ лем

• • • •

Проверка данных

Поток операций

• • • • • • •

Как определить какая информация подлежит конфигурированию? Как определить где и каким образом сохранять конфигурационную информацию? Как работать с секретной информацией? Как работать с конфигурационной информацией в кластере?

Как разделить функцональности? Как структурировать приложение? Как выбрать подходящее разбиение на слои? Как задать границы между частями системы?

Как управлять соединениями БД? Как управлять исключениями? Как улучшить производительность? Как улучшить управляемость? Как работать с бинарными данными (BLOBs)? Как использовать пейджинг (paging) для записей? Как управлять транзакциями?

Как обрабатывать исключения? Как сохранять информацию об исключениях?

Как определить какую информацию писать в лог? Как сделать запись в лог настраиваемой?

Как повысить эффективность выполнения задач? Как улучшить отзывчивость интерфейса? Как улучшить возможности приложения для пользователя? Как улучшить внешний вид приложения?

Как определить где и когда проводить валидацию данных? Как проверять длину, диапазон, формат и тип данных? Как ограничить вводимые данные и сообщать о неправильных значениях? Как обезопасить (sanitize) выводимые данные?

Как решать проблемы параллельных вычислений в потоке операций? Как обрабатывать ошибки в потоке операций? Как координировать процессы в потоке операций?

Ключевые проблемы Эта таблица сводит вместе ключевые проблемы для каждой горячей точки: Ключевая проблема

Категория Аутентификация и авторизация

• •

Хранение идентификацонных данных в открытом виде в файлах. Передача идентификационных данных в открытом виде по сети.

26


• • • • • • •

Кэширование и состояние

Взаимодействие

• • • • • • •

Композиция

• •

Параллельные вычисления и тран‐ закции

• • • • •

Управление конфигурацией

Связанность и сцепление

• • • • • • • • •

Доступ к данным

Работа с исключениями

Ведение логов и мониторинг

Взаимодействие с пользователем

Проверка данных

• • • • • • • • • • • • • • •

Аккаунты с излишними привилегиями. Долгоживущие сессии. Смешивание персонализации и аутентификации. Использование единственного контроллера доступа (gatekeeper). Отсутствие ограничений на доступ к системным ресурсам для приложения. Отсутствие ограничений на доступ к БД кроме определённых хранимых процедур (stored procedures). Неадекватное разделение прав доступа.

Промахи кэша. Отсутствие устаревания (expiration) данных в кэше. Плохая архитектура кэша. Отсутствие синхронизации кэша, необходимого для хорошего масштабирования системы.

Повышенный сетевой трафик и задержки из‐за «тяжёлых» сообщений межу слоями. Неудачные транспортные протоколы и форматы сообщений. Слишком большие объёмы данных в сетях ограниченной пропускной способности.

Тесно связанные модули Дублированный код

Блокирующие вызовы. Негранулированная блокировка данных (nongranular locks). Неправильная работа с потоками. Слишком долгое удержание блокировки данных. Неправильные уровни изоляции БД.

Небезопасные интерфейсы администрирования. Небезопасные конфигурационные хранилища. Хранение конфигурационных данных в открытом виде. Слишком много администраторов в системе. Слишком много привилегий для аккаунтов служб и процессов.

Ограниченная масштабируемость из‐за тесной привязанности к серверу и ресурсам. Смешивание уровней презентации и бизнес‐логики, ограничивающее возможни масштабиро‐ вания. Проблемы с дальнейшей поддержкой из‐за излишней связанности.

Использование отдельного логина/пароля для каждого пользователя когда в этом нет необхо‐ димости. «Тяжёлые» запросы к БД. Рассеянная по классам бизнес‐логика.

Оставление системы/приложения в нестабильном состоянии. Открытие секретной информации конечным пользователям. Использование исключений для работы логики. Запись в логи недостаточной информации об исключении.

Отсутствие логов и мониторинга. Слишком высокая детализация логов и мониторинга. Отсутствие настроек логов и мониторинга во время исполнения (run‐time). Отстуствие логов для критических бизнес‐операций.

Неэффективная поддержка задач пользователя. Плохое время отклика. Игнорирование пользователей с ограниченными возможностями.

Фильтрация ошибочных данных лишь на уровне приложения. Небезопасный вывод данных в HTML.

27


• • •

• • •

Поток операций

Небезопасное вставление данных в SQL. Проверка данных лишь на стороне пользователя. Использование имён файлов, URLов или имен пользователей для принятия решений насчёт безопасности.

Сильная связанность. Негибкие процессы. Проблемы с приоритетами и взаимными блокировками (race and deadlock issues).

Ключевые рекомендации Эта таблица приводит ключевые рекомендации для каждой горячей точки: Ключевые рекомендации

Категория

• • •

Аутентификация и авто‐ ризация

• • • • • • • • • • •

Кэширование и состояние

• • • • • • • •

Взаимодействие

• • • • • • • • • • • •

Подумайте над требованиям к регистрации. Разделите открытые всем и закрытые зоны. Используйте политики блокировки аккаунтов конечных пользователей (например при множественных ошибках в пароле). Поддерживайте настраиваемый срок действия пароля. Обеспечьте возможность отключения (disable) аккаунтов администратором. Не храните пароли. Требуйте «сильных» паролей. Не пересылайте паролей в открытом виде по сети. Защищайте cookies c идентификационными данными. Используйте несколько контроллеров доступа (gatekeepers). Ограничьте доступ пользователей к системным ресурсам. Подумайте над степенью детализации прав доступа.

Старайтесь не кэшировать создаваемые лишь для одного пользователя данные. Не кэшируйте данные, которые должны точно предоставляться пользователю и обновляться в реальном времени. Кэшируйте данные, которые меняются не очень часто или полностью статичны. Не кэшируйте очень «тяжёлые» ресурсы. Кэшируйте данные после преобразований, учитывая актуальность информации, на которой они основа‐ ны. Сравните применимость дизайнов с хранением состояния (stateful) и без такового (stateless). Обдумайте варианты хранения состояния. Минимизируйте размер данных в сессии. Освобождайте ресурсы сессии как можно быстрее. Старайтесь не запрашивать данные сессии из бизнес‐логики.

Выберите подходящий механизм удалённого взаимодействия. Делайте компактные и удобные внешние интерфейсы. Подумайте над тем, как передавать данные между слоями. Минимизируйте объём данных, передаваемых по сети. Используйте пакеты задач (batch work) для уменьшения количества вызовов по сети. Избегайте транзакций, работающих между границами частей системы. Обдумайте возможность асинхронного взаимодействия. Изучите возможность использования очередей сообщений. Оцените применимость подхода «выстрелил и забыл». Укорачивайте цепочки обработки вызовов с помощью кэширования. Это улучшит масштабируемость. Переместите асинхронность ближе к пользователю, интерфейсам служб и служебным агентам для обес‐ печения изоляции сервиса от внешних зависимостей. Если вы вынуждены сделать какую‐то функциональность синхронной, то подумайте, можно ли внутри сделать асинхронной её часть.

28


• • •

Композиция

• • • • • •

Параллельные вычисления и транзакции

Управление конфигураци‐ ей

• • • • • • • • • • • • • • •

Связанность и сцепление

• • • • • •

Доступ к данным

Работа с исключениями

• • • • • • • • • •

Ведение логов и монито‐ ринг

• •

Взаимодействие с пользо‐

• •

Избегайте использования динамических представлений (layouts), которые сложно загружать и поддер‐ живать. Будьте осторожны с зависимостями между компонентами. Используйте паттерны абстракции при пер‐ вой возможности для уменьшения потенциальных проблем с поддержкой системы в будущем. Постарайтесь использовать шаблоны с возможностью вставки данных (placeholders). Например, исполь‐ зуйте паттерн Template View для создания динамических веб‐страниц, обеспечивающих повторное ис‐ пользование и единообразие. Расмотрите возможность создания представлений из повторно используемых модулей. Например, ис‐ пользуйте паттерн Composite View для создания множества элементарных частей, работающих как гото‐ вые модули. Используйте хорошо известные паттерны для создания составных интерфейсов, содержащих отдельные модули пользовательских контролов. Модулям не следует прямо ссылаться друг на друга или на приложение, которое их загружает. Для взаимодействия с другими модулями и самим приложением надо использовать службы. Модули не должны отвечать за управление своими зависимостями. Желательно поддерживать добавление и удаление модулей как плагинов.

Относитесь к потоку (thread) как общему ресурсу. Создавайте пулы общих ресурсов или ресурсов, которых слишком мало. Запрашивайте ресурс как можно позднее, освобождайте как можно раньше. Изучите эффективность создания и уничтожения объектов. Рассмотрите управление пропускной способностью ресурсов. Снижайте возможные задержки путём минимизации времени блокировки ресурса. Соблюдайте баланс между высокоуровневыми (coarse) и низкоуровневыми (fine) блокировками. Выберите подходящий уровень изоляции. Избегайте выполняющихся долго атомарных транзакций.

Защищайте интерфейсы администрирования системы. Защищайте своё конфигурационное хранилище. Разграничивайте административные полномочия. Используйте минимально возможноые привилегии для аккаунтов процессов и служб.

Разбейте приложение на логические слои (layers/tiers). Правильно выберите расположение для частей приложения в зависимости от требований к надёжности, производительности и масштабируемости. С самого начала проектируйте систему со слабой связанностью. Проектируйте систему с сильным сцеплением. Используйте раннее связывание (early binding) где это возможно. Оцените сходство ресурсов (resource affinity).

Если ваше приложение использует единственную БД, то используйте специализированный провайдер вместо универсального для большего быстродействия. Если вы поддерживаете несколько видов БД, то вам необходим специальный уровень абстракции, кото‐ рый можно легко настроить под конкретное окружение. Попробуйте управлять пропускной способностью ресурсов. Изучите передачу в БД идентификаторов пользователей. Разделяйте запросы «только для чтения» и транзакционные. Не возвращайте данные, которые не будут использоваться.

Не показывайте пользователям данные, которые раскрывают внутренности системы. Не используйте исключения для управления потоком выполнения приложения. Используйте коды ошибок вместо исключений, где это возможно. Не перехватывайте исключения, которые вы не можете обработать. Учтите, что повторное бросание исключения (rethrowing) — дорогая операция. Сохраняйте как можно больше диагностической информации в ваших обработчиках исключений.

Постоянно ведите мониторинг. Сделайте логи настраиваемыми.

Проверяйте эффективность работы для разных сценариев. Работайте над улучшением времени отклика системы.

29


вателем

Проверка данных

• • • • • • •

Поток операций

• •

Отталкивайтесь от эффективного дизайна пользовательского интерфейса.

Проверяйте данные на длину, диапазон, формат и тип. Ограничивайте вводимые данные и сообщайте об ошибках. Обезопасьте вводимые данные. Не полагайтесь на проверку на стороне клиента.

Определите требования к управлению потоками операций. Если ими должен управлять бизнес‐ пользователь, то обеспечьте ему понятный интерфейс. Определите как будут обрабатываться исключения в потоке операций. Когда вы имеете с потоком операций, относящимся к людям, не забывайте о неопределённости челове‐ ческой натуры. Нельзя полагаться на то, что какая‐то задача будет выполнена в какой‐то срок и будет выполнена полностью. Используйте интерфейсы служб для работы с внешними провайдерами потоков операций. Используйте визуальные редакторы и метаданные для разаботки потоков операций вместо кода, если это возможно.

От переводчика: Люблю сжатый аналитический подход, поэтому и перевожу. :) И вообще рекомендую блог автора. Там много приятных для мозга списков и таблиц. Разумные поправки к переводу терминов приветствуются. Обсуждение спорных пунктов — тоже.

30


в номере использованы материалы с ресурса Хабрахабр, созданные авторами: Covex, ni4, developer, magmoro, Lite, Ordos, murr, KalGaN, enartemy автор проекта habradigest Владимир «XaocCPS» Юнев habradigest, Сентябрь 2008

31


Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.