Copy/paste и закомментированный код.

Август 14th, 2009

Две мысли в голове. Одна моя, другая позаимствованная.

С бейсбольной битой в руках разыскивается тот человек который первый в IDE добавил возможность copy/paste. Блин, жили бы, горя не знали, если бы не эта зараза.

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

Где поесть компьютеру и человеку?

Август 13th, 2009

Внимание!!! Данная статья посвящена только Харьковчанам, остальные кто прочтут ее будут прокляты и их будет вечно преследовать дух Ады Лавлейс.

Думаю, если вы компьютерщик (как любят называть нас поколение 30х того века) и не дай бог обладатель нотебука, то вы не раз наступали на грабли внезапно обнаруживая, что вы посередь города и у вас в батарее осталось 3%, а вам ну очень нужно отослать безумно важное письмо.

Так вот, теперь вы можете быть во всеоружии — узнать где можно не только зарядить компьютер, но и поесть самому, а так же попользоваться халявным WiFi.  Добро пожаловать на сайт Фон Вольт.

И да прибудет с вами сила (в смысле power).

Теория планного программирования.

Август 10th, 2009

Было как-то дело, что я обчитался книжкой по Аспектноориентированному программированию, проникся и понял как это круто. Увы, похоже в ближайшие сто лет попробовать мне это на практике не удастся.

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

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

Или например, у нас в целом модуле BankTransaction во всех интерфейсных функциях мы должны проверять, что клиент имеет право проводить транзакции. Аналогично, единственный метод — в начале каждого метода делать проверку.

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

И в целом, если объектоориентированное программирование крутится вокруг идеи выделения объекта и методов, чего можно делать с объектом. То аспектноориентированое программирование крутиться вокруг выделения идеи аспекта и собирания его из размазанного вида в одно место. Так, что вместо бегания по 100 функциям разных объектов и copy/paste одного  того же куска, мы можем сказать — делать то-то при входе в функции таких-то классов.

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

И вот, что я подумал. А ведь это чем-то похоже на объявление переменной объекта. Когда мы ее объявляем, то автоматически деструктор вклинивается в то место, где переменная выходит из области видимости.

Да, поясню слово вклиниваться. Я имею в виду, то, что мы не пишем никакого кода в определенном месте программы, но тем не менее есть код (на самом деле компилятор), который «знает», что в этом месте надо выполниться.

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

Но, это все так, отклонения от общей темы.

Дальше моя мысль прыгнула в следующем направление. Если вдуматься, все это развитие языков от низкоуровневых к процедурным, от процедурных к объектным, от объектным к аспектным двигалась в достаточно простом направление —  упростить работу программиста и свести воедино то, что было раньше разбросано по разным местам.Сначала копии кода сводились в процедуры, потом куча процедур работающих с похожими данным сводились в объекты. Объекты которые работают похожим образом сводились в иерархию объектов. Объекты работающие похожим образом, но с разными типами — в templat’ы. Естественно — это не единственная особенность развития языков программирования, но по крайне мере оно четко прослеживаемая.

Так, вот, возвращаясь к планному программированию. Моя идея следующая — херим все сущности, которые были введены раньше (функции, объекты, аспекты, модули, namespac’ы, templat’ы и т.п.) и вместо всего оставляем совмещая все это получаем коцепцию плана.

Итак, что такое план?

По большему счету, план — это набор кусков кода. План может пересекаться (вклиниваться) в другие планы. Включать куски других планов и т.п.

Основная идея, это построить их так, чтобы сделать код гораздо более податливым. Если сейчас код находится в классе X, похожий код в классе Y и Z, то начинается целая свистопляска, чтобы его объединить, или хотя бы свести в одно место (как с логированием).

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

Чтобы не углубиться окончательно в теоретические изъяснения, приведу пример. Хотим мы написать адресную  книгу. Как мы это делаем?

— Начинаем с того, что для любой программы есть стандартный пустой план — application, который содержит все остальные планы.

— В этот application план, мы добавляем UI план, в который добавляем MainWindow план. И например мы вписываем код, который читает файл, показывает табличку с именами на экране, а так же делаем чтобы можно было редактировать и сохранять файл.

— Мы обнаружили, что наш MainWindow план стал слишком жирным, выделяем Storage план, переносим туда весь код по работе с файлом (чтение, запись, временное сохранение измененных записей).

Пока звучит, точно как объектноориетированное, а то и процедурное? Согласен, но движемся дальше.

— Мы решаем, что нам надо добавить 5 полей. Начинаем их добавлять, и обнаруживаем, что мы нам нужно будет тупо copy-paste работу с полями для того, чтобы их отрисовывать в  MainWindow и сохранять, считывать в Storage. И вот тут наступает самое интересное, мы вводим новый план ContactField в который составляем из куска Storage по работе с полем и куска MainWindow по работе с полем.

Замечу, что ContactFiled содежит не копию кода, а зеркало кода. То есть, редактируя в ContactFiled оно редактируется в MainWindow или Storage. Итак, это первая выгода, что мы теперь можем просматривать код в том виде, который нас действительно интересует — либо с точки зрения UI (смотрим в MainWindow) или Storage или с точки зрения Field. На самом деле, теперь мы можем в этот план включать любые другие места где наше поле используется, передается, храниться и обрабатывается. То есть, всегда есть место где централизованно можно  видеть сущность.

— Движемся дальше. Так как мы знаем, чтона самом деле полей будет много, то план ContactField мы переименовываем в ContactFieldList и указываем, что туда должны актоматически вклиниваться все планы с названием ContactFieldList.ContactField*. Теперь внутри ContactFieldList мы можем делать новые планы, которые будут заниматься сохранием и отрисовкой и которым автоматически будут вклиниваться. Вот тут, наступает вторая выгода. Выгода состоит в возможности работы с планами в докомпиляционное время. То есть, то, что можно указать что все планы с таким-то именем должны вклиниваться. Современные языки предоставляют достаточно небольшое количество докомпиляонных средств.

Из мелких приятностей.  Любой вклиненный план можно «свернуть» при просмотре. В случае если нас не интересуют скажем детали той же проверки прав и логирования и мы их сворачиваем, то вместо кучи кода мы получаем небольшую пометку на полях, что кто-то вклинивается в этой точке и спокойно можем работать с значащим для нас кодом.

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

Самое важное, что я осознал, во время написания статьи, фактически планное программирование — это две вещи:

а) Мощная среда разработки, которая умеет делать много разных отображений кода и работы с этими отображениями.

б) Уменьшение количество сущностей (класс, процедуры, шаблоны, интерфейсы) и сведения их к минимальному количеству.

Надеюсь, кого-нибудь зацепила эта писанина. 🙂 Жду, комментариев, критики и горячих споров.

P.S. Насчет Mix-in и Closure. И то и другое продолжает решать проблему дублирования кода, но все таки не так радикально как предложено у меня 🙂

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


Никогда не делай хорошо другому.

Август 6th, 2009

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

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

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

Все таки удивительная вещь — дилемма заключенного. Все знают, как получить лучший результат кооперируясь, но при этом все предпочитают «гасить» друг друга, только для того, чтобы не дай бог кто-то получил чуть больше, чем ты сам.