
Немного позже, чем думал (что простительно, ибо дни выдались хлопотные) привожу свои варианты решения упражнения, которое я озвучил в предыдущем посте. Условие повторять не буду, по приведенной ссылке все описано.
В условии было сказано, что надо обрабатывать исключения в методах init(), run() и shutdown(). И хотя это явно не оговаривалось, по логике функционирования эти методы вызываются подряд. Следовательно, можно сделать так:
Ну или, чтобы не нарушать инкапсуляцию, этот код можно завернуть в статический метод в ApiDispatcher.
Достоинства решения:
Недостатки:
Следующее решение приходит в голову практически сразу после прочтения условия, и оно действительно хорошо подходит для решения задачи.
Именно его в комментариях предложил Vladimir Rusinov, за что ему спасибо:
Достоинства решения:
Недостатки решения:
Это решение в конечном итоге я и использовал в своем проекте. Сначала я приведу код, а потом дам дополнительные комментарии:
Здесь я явно использую класс Errors, в котором задефайнены константами все возможные коды ошибок. Кроме того, в нем есть метод, который позволяет по коду ошибки получить его текстовую расшифровку.
В PHP все исключения имеют по умолчанию два поля (есть и другие, но они нас не интересуют): $message = null и $code = 0, сообщение и код ошибки соответственно. Во всех наших исключениях мы переопределяем значение по умолчанию для кода ошибки, чтобы оно соответствовало типу исключения.
Теперь, когда мы создаем исключение, мы можем задать ему сообщение, которое описывает причину его возникновения, и, если надо, можем уточнить и код ошибки. Если же мы сообщение вручную не зададим - оно будет получено через класс Errors. В случае, если мы поймаем "не наше" исключение (типа простого Exception), у него код ошибки будет 0, и класс Errors успешно опишет его как "Unknown exception".
Достоинства решения:
Недостатки решения
Я привел целых три решения задачи и видно, что ни одно из них не является безоговорочно правильным. А это значит, что даже такая простая задача, как описано в этом упражнении, требует внимательного анализа требований к системе и ваших возможностей, как ее разработчика. В моем случае решение 3 оказалось наименьшим злом, и я использовал его. Но запросто может оказаться, что в другой ситуации оптимально "наивное" решение 1.
Хочу предложить программирующей части моей аудитории небольшую задачку, что называется, по мотивам реальных событий. Задачка просто на технику программирования, даже не на алгоритмы, к конкретному языку она, в общем-то, не особенно привязана, лишь бы в нем были предусмотрены исключения.
Есть корневой класс, условно назовем его ApiDispatcher, который управляет основным потоком исполнения. В нем есть три основных метода:
Каждый из этих методов в основном вызывает методы других объектов, из которых могут прилетать исключения. Исключений много разных, для конкретности будем считать, что десятка два, и для всех трех методов набор возможных исключений одинаков (все двадцать штук).
Так же будем считать, что нам на любом этапе доступен метод Client::reportError($error_code, $error_message), который обеспечивает вывод клиенту сообщения об ошибке и прекращение работы программы.
Теперь собственно формулировка проблемы: необходимо во всех трех методах обеспечить обработку всех возможных исключений, для каждого из исключений надо выдать код ошибки и ее текстовое описание, а потом вызвать Client::reportError() с соответствующими параметрами. Замечу, что у исключения может быть задан текст описания ошибки, и в таком случае желательно его сохранить, поскольку он скорее всего будет более информативен, чем стандартная заглушка. В принципе, вы можете модифицировать весь код системы, в т. ч. создавать новые классы и менять существующие, если это необходимо.
Естественно, решение "в лоб" не подходит, поскольку оно неизбежно приведет к большому количеству дублирующего кода.
Как бы вы решили такую задачу? Языки решения принимаются любые в пределах разумного: Java, PHP, C++. Не возбраняется использование языко-специфичных конструкций, если они действительно удобны — расширение кругозора никому лишним не будет ;-)
Я нашел два приемлемых решения, и опишу оба завтра, если их никто не назовет до меня.
Практически всем пользователям знакома утилита top, показывающая интерактивный список процессов, отсортированный по нагрузке на процессор. История этой утилиты идет от 1984 года, когда Уильям ЛеФевр написал такую утилиту для BSD 4.1. С тех пор top или его аналог есть практически в каждой UNIX-подобной ОС.
Годами доказав свою практичность, top вдохновил многих других программистов на разработку похожих утилит, относящихся к разряду must-have на любой Linux-машине, поскольку они дают возможность быстро оценить ситуацию в системе.
htop — это логическое развитие top. Его интерфейс сделан с помощью ncurses, и благодаря этому он предоставляет гораздо больше возможностей по визуализации процессов и общей загрузки системы, а так же значительно более интуитивный интерфейс настройки всего этого.
Эта замечательная утилита выручит вас, когда надо выяснить, кто же это так активно пишет на диск, что все остальные процессы едва ли не колом стоят: она выводит список процессов, отсортированный по скорости чтения/записи на диск. Полезно запускать ее с ключом -o, тогда она не будет засорять вывод процессами, которые на диск ничего не пишут.
Эта утилита аналогична предыдущей, но показывает она загрузку сетевого интерфейса. Надо заметить, что в отличие от двух предыдущих программ, она для работы требует прав root'а, и для запуска ей желательно указать имя интерфейса, который ей надо мониторить с помощью ключа -i.
Все три утилиты (htop, iotop и iftop) позволяют легко и быстро оценить положение дел на вашей машине даже в условиях отсутствия иксов или когда система бодро закапывается в своп и нужно срочно выяснить, почему: в такой ситуации дожидаться запуска графической утилиты — смерти подобно.
В прошлой заметке я сформулировал основные требования к движку блога. Теперь пришло время в общих чертах разобаться с реализацией. На начальном этапе здесь можно сказать совсем немного, поэтому пост будет небольшим.
На самом деле, для меня выбор фреймворка практически очевиден, поскольку я уже имел опыт разработки довольно сложного сайта на Yii Framework и он показал себя с лучшей стороны.
Помимо этого есть еще плюсы в его копилку:
Этот вечер я посвятил просмотру репозитория расширений и нашел там много полезного для себя и будущего движка :-)
Перечислю для истории все проекты, которые я рассматриваю как потенциальную базу для движка:
Кроме того, для всех этих проектов имеет место фактор априорного недоверия к неизвестным мне разработчикам, но это лишь второстепенный момент. В конце концов, мне все равно придется ознакомиться со всем исходным кодом движка.
Внимательное изучение этих проектов мне, видимо, еще предстоит, но я вижу два наиболее вероятных варианта:
Я до сих под еще не принял окончательного решения, но скорее всего движок будет приватным по двум причинам:
Вот уже чуть больше трех лет этот блог крутится на Drupal, но последнее время в все чаще задумываюсь о том, чтобы отказаться от него в пользу самописного движка. Причина этого желания состоит не в том, что в своей жизни я изобрел мало велосипедов, а в том, что Drupal — слишком мощный движок для моих целей.
За эти три года я достаточно много работал с Drupal'ом и могу с чистой совестью подтвердить: из него можно построить сайт абсолютно любой сложности и с любым мыслимим и немыслимым функционалом. Засада лишь в том, что такая мощь мне на этом блоге не нужна, тем более, что за нее приходится платить тяжеловесностью сайта. Поэтому в качестве отправной точки я решил составить список требований которые я предьявляю к движку блога. Этому и будет посвящен пост.
Движок предназначен для ведения (преимущественно) однопользовательских персональных блогов.
Требований, как оказалось, не так уж и мало, хотя далеко не все из них критичные. Поэтому в следующей заметке я уделю внимание техническим аспектам реализации движка.
Последние комментарии
/Alek$/ 3 дня 2 часа назад
/Alek$/ 3 дня 2 часа назад
/Vladimir Rusinov/ 3 дня 14 часов назад
/Vladimir Rusinov/ 3 дня 14 часов назад
/Alek$/ 1 неделя 11 часов назад
/Гость/ 1 неделя 12 часов назад
/Alek$/ 1 неделя 3 дня назад
/Наталья/ 1 неделя 3 дня назад
/Alek$/ 1 неделя 3 дня назад
/Alek$/ 1 неделя 3 дня назад