February 10th, 2010

19. Удобство?

(В оригинале Convenience Is not an -ility)

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

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

  • Я не хочу, чтобы другим классам приходилось делать два вызова для того, чтобы сделать вот это.
  • Зачем мне нужна еще одна функция, если эта уже делает почти то же самое. Я лучше добавлю туда еще один параметр-переключатель.
  • Смотрите, все просто. Если второй параметр заканчивается на .txt, то функция автоматически решит, что первый параметр – это имя файла, и вторую функцию можно не делать.

Однако несмотря на благие намерения, это приводит к снижению читабельности кода, использующего такой API. Вызов такого метода:

parser.processNodes(text, false);

практически бессмысленен без знания подробностей реализации или чтения документации. И скорее всего, метод был написан для удобства его писавшего в противоположность удобству использующего. На самом деле фразу «Я не хочу, чтобы надо было вызывать два метода» следует читать как «Я не хотел писать два отдельных метода». Ничего радикально неправильного в удобстве нет, если говорить об удобстве как о противоядии к монотонности, неуклюжести или неповоротливости. Однако, если чуть глубже копнуть, то противоядием к перечисленным симптомам будет эффективность, логичность и элегантность, а вовсе не удобство. API предназначен для скрытия нижележащей сложности, и вполне логично ожидать, что проектирование хорошего API потребует определенных усилий. Написать один большой метод будет гораздо удобнее, чем продумать адекватный набор операций, но вот будет ли этот метод более удобен в использовании?

Сравнение API с языком может привести нас к лучшему пониманию того, какое решение следует принять. API должен предоставить словарь, дающий возможность вышележащему уровню задавать нужные вопросы и получать ответы. Необязательно, чтобы для каждого вопроса использовалось единственное слово. Разнообразие словаря может позволять использовать различия в значениях. Так, мы скорее предпочтем метод run вместо метода walk(true), даже если они будут полностью эквивалентными. Последовательный и хорошо продуманный словарь, используемый для API, сделает код следующего уровня более выразительным и понятным. Еще более важно, что если словарь можно будет комбинировать, то другие программисты смогут использовать API так, как вы и не подозревали – на самом деле отличное удобство для использования. Когда в следующий раз захотите объединить несколько вещей в один метод, вспомните, что в языке нет слов вроде УбратьВКомнатеИСделатьУроки, даже если вам такое слово кажется удобным для обозначения часто используемого действия.

Автор оригинала - Gregor Hohpe

Перевод мой, при использовании ссылка на мой живой журнал обязательна!

О бесплатном ПО и альтернативе фотошопу

Давно уже хотелось найти что-то бесплатное, могущее адекватно заменить фотошоп. И не надо сразу кричать про Gimp, сначала расскажу о задаче, решение которой хотелось найти прежде всего.

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

С появлением Nikon D60 необходимость тщательной постобработки резко снизилась, но все еще осталась. В основном из-за коряво работающего экспонометра, выставляющего экспозицию по теням, из-за чего света экспонируются неидеально. А когда снимаешь сильно динамичный сюжет, то вручную корректировать настройки так, чтобы фотка заняла весь диапазон яркости, ни шанса. Поэтому я настраиваю фотоаппарат так, чтобы света были недодержаными - это в отличие от передержки поправимо.

А при съемке в помещении с неуправляемыми внешними вспышками все еще сложнее - экспонометр вообще становится бесполезным. И учитывая динамичность сюжета и то, что снимаемые могут то приблизиться к вспышкам, то удалиться, или же ловя момент я нажму на спуск до того, как вспышки полностью перезарядились, экспозиция может сильно варьироваться. Опять же, настраиваю все так, чтоб в худшем случае не допустить пересвета, как следствие, потом приходится на большинстве фоток исправлять недодержку.

Такой подход, как вы уже поняли, делает необходимой постобработку. Причем довольно простую - то, что в фотошопе называется автоконтраст - "растягивание" диапазона по самому "широкому" каналу, так, чтобы ни в одном из каналов (RGB) не возникло передержки и чтобы цветопередача не менялась (ее можно довольно точно выставить на этапе съемки, если освещение не меняется в процессе). То же самое, но в каждом канале по отдельности, называется в фотошопе autolevels, и дает немного другой результат, не всегда лучше, чем было.

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

Начал искать. Сначала выбор пал на xnview, однако на практике оказалось, что непонятно как, но результат его автокоррекции иногда сильно ниже удовлетворительного. Плюс нет возможности настроить сжатие jpg при сохранении результата. Разочаровался.

Попробовал с десяток других приложений, в т.ч. и Gimp. Да, с его поддержкой скриптов можно реализовать что угодно, но садиться за разработку с нуля как-то не хотелось - с учетом стоимости потраченного времени проще купить готовое :) Готового решения в Gimp увы, нет даже близко.

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

Среди программ попался мне Lightbox. То, как он делает автокоррекцию, приятно удивило - результат автоматической коррекции яркости показался даже лучше, чем аналогичный в фотошопе. Лишь один момент портил все - отсутствие даже намека на автоматизацию...

Попробовав другие варианты и подивившись странностям их разработчиков (у кого-то вообще не было автокоррекции, у кого-то она работала через ж, у кого-то она работала только в каждом канале, меняя цветопередачу), уже начал склоняться к тому, что простого, качественного и бесплатного решения не существует.

И вдруг вспомнил, что недавно писал о другой программе, AutoHotKey, которая как раз и занимается автоматизацией!

Дальше было просто. Ставим AutoHotKey, читаем доки по командам, записываем скрипт, делая один раз все действия в Lightbox-e вручную, правим скрипт там, где это нужно, запускаем...

Упс, на второй фотке Lightbox благополучно валится с предложением отправить отчет в микрософт... Повтор сценария вручную подтверждает наличие в нем такого бага... Что же, бесплатный софт есть бесплатный софт. Интересно, есть ли этот глюк в платной версии?

Ладно, дописываем в начало цикла старт Lightbox-a, а в конец - его закрытие. И вуаля - все работает! Можно запускать автообработку и идти заниматься своими делами - единственный минус такого решения - невозможность использовать комп во время работы скрипта, поскольку он эмулирует движения мышью, клики и нажатия клавиш на клавиатуре.

Так что а)если поискать, можно найти бесплатный (или как минимум недорогой) аналог почти чего угодно и б)используя две программы в паре, можно получить сильно больше, чем дает каждая из них :)

Осталось найти аналог фотошоп LAB (хотя и нужен он гораздо реже)...