Русские документы
Ежедневные компьютерные новости RSS rusdoc.ru  Найти :
Новости
Последние поступления
Книжный магазин
  Hardware:
Видеоустройства
Системные платы
Процессоры
Мобильные устройства
Аудиосистема
Охлаждение системы
Накопители информации
КПК и ноутбуки
Телефоны и связь
Периферия
Система
Сети
Разные устройства
 
  Programming:
Web-разработка
Языки программирования
Технологии и теория
Разработка игр
Программная инженерия
 
  Software:
Операционные системы
Windows 7
Базы данных
Обзоры программ
Графика и дизайн
   
  Life:
Компьютерная жизнь
Разные материалы
   
Партнеры
Публикация
Правовая информация
Реклама на сайте
Обратная связь
Экспорт в RSS Экспорт в RSS2.0
    Читать в Яндекс.Ленте



Функции наносят ответный удар

Раздел: Programming / PHP @ 05.09.2010 | Ключевые слова: php архитектура функции версия для печати

Автор: BreathLess
Источник: habrahabr

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

Вкратце, суть концепции — это перенос части unix way в программирование на PHP.
А конкретно, концепции простых программ, выполняющих одну функцию.

Предыстория такова.

Работая над многими системами и делая разнообразных ООП-монстров, используя фреймворки, я постоянно испытывал дискомфорт, и ощущение излишней многословности.
Интерфейс Hash, класс Abstract_Hash, потомок Hash_MD5…
В котором будет однострочный wrapper для стандартной функции.
Не слишком ли много для простого хеширования?

Обычно мне возражают, что это повышает readability, reusability и maintability кода.
Но представим, что нам нужно заменить конкретный механизм реализации, согласно паттерну Strategy?
Мы приходим либо к абстрактным фабрикам, либо к search-n-replace в коде.
Это никак не тянет на KISS, и лишь усугубляет проблему.
А если компоненты сильно связаны?
Я видел проекты, в которых были смешаны Zend Framework и Kohana, по принципу «реюзнем кодца». И, кстати, это еще и за деньги предлагалось.

Вступление затянулось, перейду к делу.

На помощь мне пришли простые функции. Обычные функции, имеющие одно предназначение.
Такие как:
function F_Standart_Random($Args)
{
return rand($Args[`Min`],$Args[`Max`]);
}

или
function F_MonteCarlo_Random($Args)
{
return mt_rand($Args[`Min`], $Args[`Max`]);
}

(Примеры выбрал попроще, чтобы не утяжелять статью)

Функции именуются через соглашение вида
F_ИмяРеализации_Функция($Args)
(в одной реализации может быть несколько функций, например, для шифрования, их четыре: шифрование, дешифрование, инициализация и установка вектора).

Хранятся в структуре вроде:
/Drivers/Generate/Entropy/MonteCarlo.php
где «Generate/Entropy» — это своеобразное «пространство имён».

Самое интересное начинается сейчас.

Вызываются они через класс-синглтон, назовём его Code. У класса Code есть один метод — E[xecute]. В данном случае я пожертвовал читаемостью в пользу краткости, т.к. вызовов этого метода, очень много.
В идеале, сделать короткий алиас, вроде _($Args), но gettext уже занял это имя.

Метод Е объявлен как
public static function E ($Namespace, $Function, $Args, $Driver = `Default`)


Что же он делает или может делать?

Список, который пойдет дальше, — это описание возможностей реального класса, но, дабы избежать обвинений в PR, прямой ссылки не будет.

Конфигурация — это всё

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

Из своей практики, вспоминается разворачивание приложения, написанного для PHP 5.2, на сервере с PHP 5.1, в котором нет нативной реализации JSON.
Замена нативной на свой велосипед заняла меньше минуты.


Также можно реализовать умную выборку, которая будет заменять конкретные реализации, в зависимости от времени суток, текущей нагрузки, географии клиента, тут ограничение — лишь Ваша фантазия.
Не лишним будет упомянуть и отказоустойчивость, ведь класс может перебирать драйвера (конкретные реализации), ловить исключения и корректировать свою конфигурацию.

Закешируй это

В подобной схеме, легко реализуется кеширование результатов выполнения любого кода.
Для этого нужно всего лишь добавить в конфигурацию указание, какое пространство имён / функция могут кешироваться и на какое время.
Можно реализовать это отдельным методом E[xecute]C[ached], чтобы не утяжелять логику основного метода.

Удалённый вызов функций

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

Отложенные вызовы

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

ACL на уровне функций

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

Сюда же можно добавить профайлинг, логгирование и многое другое.

Плюсы подхода, помимо уже указанных:


Минимализм

Функции проектируются максимально простыми, в духе unix, с расчётом на совместное использование.
Например, F_RSS2_Import принимает исключительно строки и позволяет самому разработчику выбрать, какой механизм получения RSS-фида выбрать.
Простые функции удобно отлаживать, они быстро работают и прекрасно комбинируются.
К сожалению, многие фреймворки грешат тем, что смешивают получение и обработку данных, это приводит к инверсии абстракции и многословности.

Добавление функционала через файловую систему.

Новая реализация не требует изменений в программном коде — лишь конфигурирование и копирование файла в нужное место. Своеобразный Convention over naming|configuration.

Независимость.

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

Это открывает широкие возможности для обмена кодом, решениями и наработками. К слову, для интеграции какого-то кода, нужно всего лишь обернуть его в функцию с именем по соглашению.
В своё время мне удалось перенести коллекцию из примерно 300 функций на систему, разработанную другим человеком, портировав на неё свой класс.
За полчаса удалось провернуть то же самое с Zend Framework.


Замечу, что использование чужих классов не так удобно — обычно приводит к bloatware, нарушению конвенций и т.п.

Скорость и ресурсы.

Это тема для холивара, но очевидно, что простые классы более затратны.

Минусы, их не мало.


Глобальность

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

Описание формата аргументов.

Точнее, его отсутствие.
Ассоциативный массив — не самая аннотированная структура данных. Спасают docblocks, но лишение возможности автодополнения в IDE может отпугнуть.
Хотя, по своему опыту, неудобств не замечал.

Overhead присутствует.

Не такой большой, как у классов, но, всё же, он есть.

Читаемость кода.

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

Объектно-ориентированный онанизм.

ООП ради ООП стало настолько привычным, что описанный мной подход вряд ли снискает популярность.

В рамках статьи примеры я указал простые, приведу список применений из реальных проектов: конвертирование (арабские-римские, СИ, XML, RSS, APML), обработка ввода, обработка вывода (смайлики, смарттеги, динамические теги в шаблонизаторах), генерация (случайные числа, uids, пароли), роутинг во фреймворках, слоты, получение данных (абстракция БД), условия, транспорты сообщений и.т.п.

Цель топика — лишь рассказать об этом методе организации кода, который мне здорово помогает.
Это не крестовый поход против ООП, не истина в последней инстанции и не руководство к действиям (оговорка здесь нужна, после моего первого топика, в котором меня обвинили, что я лично ввёл в заблуждение миллиарды джуниоров).

Это интересно:








версия для печатиРаспечатать статью


Вернуться в раздел: Programming / PHP


Реклама:
Читать наc на:

Add to Google
Читать в Яндекс.Ленте






Rambler's Top100
© Copyright 1998-2012 Александр Томов. All rights reserved.