пятница, 31 мая 2013 г.

О VCL

Под влиянием "новомодных" тенденций слышу иногда "ах VCL это уже не модно, ах он должен вымереть как динозавры".

Если интересна МОЯ точка зрения - СКАЖУ - VCL по "архитектурности" и "практической вылизанности" - ЛУЧШАЯ библиотека, которую я видел.

А сравнивать - ЕСТЬ с чем - TurboVision, SuperVision, OWL, MFC, QT, UIKit. Что ещё забыл?

Ах да! FireMonkey! Я в FireMonkey пока ГЛУБОКО не погрузился, но я видел VGScene (предтеча FireMonkey) и ОСНОВАТЕЛЬНО ей переделывал.

Что сказать про FM? "АРХИТЕКТУРНО" она мне нравится БОЛЬШЕ, чем VCL. Концепция стилей, слоёного пирога и ОБЩЕЙ канвы - МНЕ СИЛЬНО нравятся.

Но пока FireMonkey - проигрывает VCL по "вылизанности" и стабильности. Но я думаю - "парни справятся с этой проблемой".

Я если найду время - начну глубоко погружаться в FM и тогда буду писать свои КОНКРЕТНЫЕ впечатления, замечания и рецепты по улучшению.

У меня есть "пара идей", которые я бы хотел сделать на FM. Правда у меня основной работы "вагон и маленькая тележка". Но я надеюсь, что я найду время.

Ну и раз уж я начал сравнивать - скажу ещё одно впечатление - КОНЕЧНО UIKit. Он - ХОРОШ. Особенно "для чайников". В нём МНОГО чего уж есть априори. И в нём есть "стройность концепции". Местами "кривая" лично для меня, но стройность и единообразие.

НО VCL - пока - лучший. Но с него - рано или поздно - всё равно надо слезать. Мне так почему-то кажется.

Где-то за неделю перепортировал все проекты с XE3 на XE4

Где-то за неделю перепортировал все проекты с XE3 на XE4.

Они - СОБИРАЮТСЯ. Но пока ничего - НЕ РАБОТАЕТ из-за -http://18delphi.blogspot.com/2013/05/xe4.html

Жду теперь когда Resolved превратится в Closed.

P.S. я кстати нашёл ТРИ workaround'а ошибки. Попробую завтра всё же ЗАПУСТИТЬ простейшие тесты под XE4. РУКИ ЧЕШУТСЯ на это посмотреть.

Метания с Indy XE3 vs. XE4 - страннЫ

Метания с Indy XE3 vs. XE4 - страннЫ.

To const array of  bytes, to TidBytes, то опять const array of  bytes.

Неаккуратненько. Прямо скажем.

четверг, 30 мая 2013 г.

"Дырявые абстракции" и property

http://russian.joelonsoftware.com/Articles/LeakyAbstractions.html

Есть property X : Integer read GetX write SetX.

И есть метод doSomething (var X: Integer)

ТУДА property передать НЕЛЬЗЯ!

Почему спрашивается?

Почему нельзя сделать compiler-magic типа

l_X := SomeObject.X;
SomeMethod(l_X);
SomeObject.X := l_X;

???

Зачем разрывать "дырявые абстракции"?

Чтобы "взорвать мозг программистам"? Или просто "не додумали"?

Или ЕЩЁ пример.

property X: SomeRecord

ПОЧЕМУ нельзя написать SomeObject.X.SomeField := SomeValue? Тоже, чтобы "разорвать абстракцию" или взорвать мозг программистам?

Почему нельзя сделать compiler-magic:

l_Rec := SomeObject.X;
l_Rec.SomeField := SomeValue;
SomeObject.X := l_Rec;

???

НЕ ПОНИМАЮ....

Я бы на месте Embarcadero "это" сделал бы...

P.S. Если уж сделали ARC в виде compiler-magic, то и ТУТ бы я это сделал бы...

Вот это - расстраивает...

http://qc.embarcadero.com/wc/qcmain.aspx?d=110364

Хотя... Если я правильно понял - может быть РАДУЕТ... Буду пробовать...

reference to совместимо с МЕТОДАМИ ОБЪЕКТОВ?! А с ЛОКАЛЬНЫМИ процедурами?! Если - ДА, то - РАДУЕТ! Буду пробовать.. у меня - ЕСТЬ НА ЧЁМ...

среда, 29 мая 2013 г.

Не могу пока написать "перехожу на Delphi XE4"

Не могу пока написать "перехожу на Delphi XE4".

Потому, что вот - http://18delphi.blogspot.com/2013/05/xe4.html

ОЧЕНЬ хотел бы написать такое....

P.S. Пока буду добиваться того, чтобы заработали ВСЕ тесты под XE3. Там похоже "мои" косяки в основном.

Offtopic. Google зовёт "зарабатывайте на блоге"

"

Здравствуйте!

Хотите зарабатывать на своих сообщениях в Blogger? Это возможно с AdSense – простой и понятной рекламной программой Google, встроенной в Blogger.
AdSense позволяет зарабатывать на контекстных рекламных объявлениях, которые появляются рядом с Вашими сообщениями в блоге.
В прошлом году владельцы сайтов и блогов, использующие AdSense, заработали более 7 млрд долларов – выгода очевидна."

Это вообще комильфо? По-моему - не очень...

Надо по-моему СИЛЬНО различать "желание донести свои мысли до других" и "желание заработать"... Как-то так...

Объекты "старого стиля" в XE4

Нет, я конечно "уважаю Остап Ибрагимыча". И читал в программном документе (http://18delphi.blogspot.ru/2013/04/delphi-language.html) постулат об отказе от object.

Но то, что "сотворили" в XE4 с object'ами (по сравнению с record'ами с методами) - выглядит скорее как ОШИБКА, нежели чем ЧЁТКО СПЛАНИРОВАННОЕ действо. Это - грустно.

Методы на record'ах, которые возвращаются из property - МОЖНО звать, а на object'ах, который возвращаются, через property - НЕЛЬЗЯ. Глупо имхо. Тем более, что пишут "var reference required". Ну ГЛУПО! Про property и var - я давно кстати пост хочу написать. НАПИШУ.

P.S. Embarcadero (нашему надёжному "причалу") тут ТВЁРДАЯ "двойка" (учитывая ещё и вот это - http://18delphi.blogspot.com/2013/05/xe4.html). ИМХО. НЕЛЬЗЯ выпускать НОВЫЙ компилятор в течении полу-года от старого. Тем более с ТАКИМИ различиями. Я бы СЕБЕ этого не позволил бы. Но я надеюсь, что "парни учтут ошибки и постараются так больше не делать".

Я то конечно - "выкрутился". Но только то, что ВЕСЬ интересующий код был нарисован в UML и то, что была возможность поправить ШАБЛОНЫ КОДОГЕНЕРАЦИИ - позволило решить проблему за ОДИН РАБОЧИЙ ДЕНЬ. Object я теперь генерирую в record, наследование в агрегацию, а методы, где не срасталось с наследованием сгенерировал в overload-Stub'ы. Если бы этого не было бы - думаю разборки затянулись бы на неделю.

Правда IfDef XE4 повсеместно это - УЖАС. Но по-другому - пока не так. Ведь существует масса проектов, которые пока на Delphi 7 приходится собирать.

Я бы на месте Embarcadero подумал бы о возвращении полноценного object. Хотя бы под директивой компилятора. Тем более, что отмазка "в LLVM такого нет" - не катит. Всё там есть. Достаточно на xCode посмотреть.

Теперь осталось дождаться момента - когда Embarcadero поправит ошибку с "открытыми массивами".

вторник, 28 мая 2013 г.

KOL и XE4

KOL и XE4.

Грустная история... Порезали полноценную поддержку object. Так что KOL - RIP. Для XE4.

В XE3 - ещё было всё хорошо.

Подсчёт ссылок. Чужая статья

https://plus.google.com/u/0/100996486893243136109/posts/Sfv861dRYVu

По-моему - очень.

Update. Что-то у меня комментарии Rouse к статье - не находят положительного отклика. Скорее я согласен с Романом.

А вообще - СТОИТ почитать ВСЕ комментарии и поразмыслить.

скажу ПРЯМО - мне реализация TComponent+Owner - НИКОГДА не нравилась
мне бы понравился ПОДСЧЁТ ССЫЛОК начиная с TObject

не ARC!!!

Что я собственно и делаю в своих библиотеках. Каждая ветка наследования - имеет счётчик ссылок. А TComponent я бы конечно переписал бы. Если бы можно было бы.

Например вот - http://18delphi.blogspot.com/2013/04/iunknown.html

P.S. Роман Янковский поднял ПРАВИЛЬНУЮ ТЕМУ. ПРОБЛЕМУ в реализации TComponent и TInterfacedObject - ЕСТЬ. И это надо ПРИЗНАТЬ. А не делать вид, что их нет. И мне не очень понятно - почему УВАЖАЕМЫЕ люди - "вымазали Романа грязью". Ну или я что-то не так понимаю. Наверное я "не дорос до их музыки".

Чужое. Короткое. Очень правильно :-)

http://juick.com/Kerk/2375930

Я вот давно думаю о другом.. Как бы "выпрыгнуть"... Как ПРАВИЛЬНО передавать знания?

суббота, 25 мая 2013 г.

Ссылка на статью: Практическое использование RTTI-атрибутов

http://teran.karelia.pro/articles/item_5981.html

Прикольно. И наверное - практически полезно :-)

У самого "руки чешутся" куда-нибудь "атрибуты приляпать"...

Что-то мне подсказывает, что это с UML явно как-нибудь пересечётся.

Правда идея с mock'ами на атрибутах меня лично - больше возбудила. Вот тут вроде было - http://www.gdcsoftware.com/index.php/testgrip/screenshots-and-screencasts/

Или тут - http://18delphi.blogspot.com/2013/04/blog-post_7108.html

Update! Вот ТУТ - http://stackoverflow.com/questions/8999945/can-i-write-parameterized-tests-in-dunit/9006662#9006662

"тест кейс для компилятора delphi"

Кто-то тут пришёл в блог по контексту "тест кейс для компилятора delphi".

Эх сам бы я хотел на такое посмотреть. Если оно конечно в природе существует.

Учитывая вот это - http://18delphi.blogspot.com/2013/05/xe4.html похоже - НЕ СУЩЕСТВУЕТ :-( грустно...

Похоже, что нету авторского JEDI под XE4

Похоже, что нету авторского JEDI под XE4. Или я плохо искал. Выложить свои правки?

Я пока обошёлся "малой кровью". Обработкой VER250 как VER240. И правкой ОДНОГО модуля - JclAnsiStrings - перед ambigous вызовами поставил квалификатор модуля AnsiStrings.

Кстати - как там с авторским правом? Могу я это выложить в общий доступ?

P.S. Похоже, что я всё же что-то - "недопортировал" - не всегда стек показывается - http://18delphi.blogspot.com/2013/06/blog-post_13.html

пятница, 24 мая 2013 г.

Delphi Language для мобильной разработки (ещё раз)

Изначальная ссылка тут - http://feedproxy.google.com/~r/Delphi2010ru/~3/b0xK9-SfJZ8/

http://embt.co/DelphiWP или вот - https://sourceforge.net/p/rumtmarc/code-0/HEAD/tree/trunk/Doc/delphilanguagemobiledevelopmentwhitepaper170413.pdf

"Говорят "будет один строковый тип, с подсчётом ссылок и immutable". Ну в общем - знакомо. И в общем - правильно. Для сравнения - NSString и Il3CString. immutable! Ещё раз - это правильно. Атомарные объекты не должны менять своё состояние." Строки ДОЛЖНЫ быть как ЧИСЛА. Атомарными объектами. Хотите изменить строку - вызывайте функцию преобразования.

Писал я тут - http://18delphi.blogspot.ru/2013/04/delphi-language.html

И ещё вспомнил - ЕЩЁ Барбара Лисков писала об этом в книге "Применение абстракций и спецификаций в разработке ПО".

Язык CLU.

Я общем - ничто - не ново. По-моему товарищи - в правильную сторону движутся. В сторону immutable-строк. Так кстати их и кешировать проще. Я это делал в своих скриптах. Просто тупо кешировал ВСЕ строки длиной < 400 символов. Рассматривая их как константы.

Даже когда из файла читается значение. Фабрика строк может выдать УЖЕ существующий объект. С увеличенным счётчиком ссылок.

Даже несмотря на ПОИСК строк в кеше - производительность скриптов - УВЕЛИЧИЛАСЬ.

Хотя... Подумалось... s[i] := XXX - тоже можно как ФУНКЦИЮ преобразования рассматривать. Это же вопрос "синтаксического сахара"? Или я что-то упустил?

!!! Падает простейший пример под XE4 !!!

http://qc.embarcadero.com/wc/qcmain.aspx?d=116040

Access Violation при запуске:

unit evFormats;

interface

type
  Tl3ClipboardFormat = Cardinal;
  Tl3ClipboardFormats = array of Tl3ClipboardFormat;

var
  evPlainTextFormats : Tl3ClipboardFormats = nil;
  evAllFormats : Tl3ClipboardFormats = nil;

implementation

uses
  Windows
  ;

function l3FormatArray(const anArray: array of Tl3ClipboardFormat): Tl3ClipboardFormats;
  {-}
var
 l_Len   : Integer;
 l_Index : Integer;
begin
 l_Len := Length(anArray);
 SetLength(Result, l_Len); // - вот тут ПАДАЕТ, да и отладчик показывает, что Result - Invalid
(* for l_Index := 0 to Pred(l_Len) do
  Result[l_Index] := anArray[l_Index];*)
end;

var
 cf_EverestBin : Tl3ClipboardFormat = 1;
 cf_EverestTxt : Tl3ClipboardFormat = 1;
 cf_RTF : Tl3ClipboardFormat = 1;
 cf_RTFLite : Tl3ClipboardFormat = 1;

initialization
 evPlainTextFormats := l3FormatArray([cf_UnicodeText, cf_Text, cf_OEMText]);
 evAllFormats := l3FormatArray([cf_EverestBin, cf_EverestTxt,
                                cf_RTF, cf_RTFLite,
                                cf_Bitmap,
                                cf_UnicodeText, cf_Text, cf_OEMText,
                                cf_hDrop]);

finalization
 evPlainTextFormats := nil;
 evAllFormats := nil;

end.


program tstXE4;

uses
  evFormats;

begin
end.

-------------------------------------
Достаточно даже вот так:


unit evFormats;

interface

type
  Tl3ClipboardFormat = Cardinal;
  Tl3ClipboardFormats = array of Tl3ClipboardFormat;

var
  evAllFormats : Tl3ClipboardFormats = nil;

implementation

uses
  Windows
  ;

function l3FormatArray(const anArray: array of Tl3ClipboardFormat): Tl3ClipboardFormats;
  {-}
var
 l_Len   : Integer;
 l_Index : Integer;
begin
 l_Len := Length(anArray);
 SetLength(Result, l_Len);
 for l_Index := 0 to Pred(l_Len) do
  Result[l_Index] := anArray[l_Index];
end;

var
 cf_EverestBin : Tl3ClipboardFormat = 1;
 cf_EverestTxt : Tl3ClipboardFormat = 1;

initialization
 evAllFormats := l3FormatArray([cf_EverestBin, cf_EverestTxt,
                                cf_UnicodeText, cf_Text, cf_OEMText,
                                cf_hDrop]);

finalization
 evAllFormats := nil;

end.
------------------------------------
!!!!

cf_EverestBin, cf_EverestTxt
заменяем на 1, 1
и - ВСЁ хорошо
по памяти ездят, когда "открытый массив" конструируют

Портят Result в l3FormatArray
---------
Даже вот так не падает:

 evAllFormats := l3FormatArray([cf_EverestBin, cf_EverestTxt,
                                cf_UnicodeText, cf_Text, cf_OEMText]);

P.S. мне кажется, что если были бы тесты - они бы это показали бы. Не такая уж редкая ситуация. Дарю Embarcadero - "первый тест". И в свою базу тестов это внесу.

P.P.S. Пока Embarcadero не поправит ошибку - буду окучивать XE3. Так что про XE4 видимо пока ничего не расскажу.

Можно ли смешивать VCL и FireMonkey?

Отвечу коротко - МОЖНО. Сам УЖЕ попробовал. "Окна они и в африке - окна". Естественно под Windows. Без МУЛЬТИПЛАТФОРМЕННОСТИ. Боюсь только, что Embarcadero это официально не приветствует.

Но как "переходные" решения - по-моему - можно применять. Если Embarcadero не будет какие-то санкции применять.

четверг, 23 мая 2013 г.

Посетил сегодня конференцию Embarcadero RAD Studio XE4 Start

Посетил сегодня с коллегами конференцию Embarcadero RAD Studio XE4 Start.

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

Чертовски был рад тому, что Всеволод презентовал этот мой блог. Он (блог) заслужил отдельного слайда презентации, со ссылкой на него и моей рожей :-) Человек 500-т это видело. Чертовски приятно, тем более, что я сам свой блог пока ОЧЕНЬ КРИТИЧЕСКИ оцениваю. Свою "хорошую статью" - я ещё не написал. Но - очень приятно. Буду работать над хорошими статьями, а не "наборами тезисов"...

Что удивительно - в перерыве подошли люди и задали вопросы. По делу. А с парой ещё - просто так "зацепился языками".

Жду кстати комментариев к блогу или по почте. Критические комментарии - ПРИВЕТСТВУЮТСЯ. Только конструктивные.

Ярослав Бровин приятно удивил проработанностью приложения под iOS. Показал ВСЁ. Кнопки. Тулбары. Таб-контрол. Датчики. Сенсоры. Геолокация. Телефонные звонки. Видео и аудио.

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

СЕРВИСЫ в FireMonkey - не что иное, как вариант Dependency Injection. Сам давно такое использую. Правильной дорогой движутся товарищи.

Правда я бы презентовал бы это не совсем так. Uses в компоненте к сервису - по-моему - не комильфо. Я слышал недовольные комментарии в зале. По-моему надо было сделать АКЦЕНТ на том, что как раз-таки КОМПОНЕНТЫ МОГУ не ЗНАТЬ про РЕАЛИЗАЦИИ сервисов. Т.е. мысль то конечно понятна - но немножко смазалась.

Но всё равно - ОЧЕНЬ КРУТО. Очень подробная презентация.

Новые возможности языка - не удивили. Про них я - читал и даже немножко откоментировал тут - http://18delphi.blogspot.com/2013/04/delphi-language.html. ARC - меня лично немного смущает. С опаской я к нему отношусь. Я бы предпочёл retain и release (Use/Free) ЯВНО и memorypool. Как у меня например - http://18delphi.blogspot.com/2013/04/iunknown.html (ну и там по ссылкам ещё кое что есть). Но что делать... Поживём - увидим. Но ОДНО! [Weak] ссылки - это УЖЕ ХОРОШО. Ну и ARC - явно ЛУЧШЕ "сборки мусора".

Дмитрий Арефьев рассказывал долго, обстоятельно и по делу. К сожалению было "ну это всё понятно". Понимаю - сжатый формат мероприятия.

Правда, к сожалению, мне лично - тема FireDAC (и вообще DataAccess) - мало интересна. У меня в этом разрезе - "свой мир". А так - здорово.

Опять немножко удивили вопросы из зала. Ну у людей же есть исходники (ну или будут). Некоторые вопросы можно было решить глядя в них.

НО что приятно - пара людей всё же задала вопросы организаторам про UML и тестирование. Не один я такой.

Я правда вопросы не задавал. Что-то не созрело ничего пока. "И так всё понятно".

В Казани в апреле правда всё было более "камерно" и одновременно - веселее. Правда может быть это у меня такое "первое впечатление" просто было. Ведь я не посещал подобные мероприятия с года 2000-го.

А в целом - здорово, что Delphi - вроде бы возрождается. Дай то бог.

Будет кому баг-репорты постить :-) С Борландом это правда плохо получалось...

P.S. Кстати - я не знаю почему я ничего там не сфотографировал...

VCM Sand Box

Тут надо описать работу с IsdsXXX и IdsXXX в разрезе поста "Чудесный ужас" (http://18delphi.blogspot.com/2013/05/blog-post_6566.html). И что у нас тоже есть "чудесный ужас". Но он КОНТРОЛИРУЕТСЯ моделью.

среда, 22 мая 2013 г.

Банальное. "Почему люди боятся изучения и использования "Процессов"".

Пока "процессы" - не распространены и не СТАНДАРТИЗИРОВАНЫ. Пока они МАССОВО не ПРЕПОДАЮТСЯ в ВУЗах. И не вошли ПОД КОЖУ разработчикам. Разработчики - БОЯТСЯ "процессов".

Почему?

Да потому! Потому, что они говорят - "я завтра уйду в другую организацию - и ЗАЧЕМ мне там ВАШ ПРОЦЕСС".

И они в чём то правы.

Что с этим делать - я пока - не знаю.

Я сам ЧЕСТНО говорю людям на собеседованиях - "на один-два года к нам приходить работать - нет смысла, МНОГОМУ научитесь, но можете потом это нигде не применить".

... to be continued ...

P.S. Интересно мне - сейчас "процессы" преподаются в ВУЗах? При мне это пытался делать только ОДИН человек - Нечаев.

P.P.S по мне - в ВУЗах гораздо ПОЛЕЗНЕЕ преподавать "четыре семестра "процессы"", чем "три семестра (зачем-то) абстракный C++".

P.P.P.S И ешё.. Никакую МЕТОДОЛОГИЮ или ПРОЦЕСС - нельзя НАВЯЗАТЬ или "заставить". Никакие инструкции - не помогут. По крайней мере в программировании. По крайней мере - пока. Ими можно только - "заразить"... На примере - "делай как я"...

По-моему - должно сменится несколько поколений, чтобы пришли люди (и чтобы МЫ их воспитали), которые знают, что такое "атлас машин и механизмов" или "номенклатура микросхем" - в ПРОГРАММИРОВАНИИ. Чтобы люди "забыли" слова "творец" или "художник" (опять же в программировании), и вспомнили слова "ремесленник" или "инженер". Опять же - в ПРОГРАММИРОВАНИИ.

Потому что "пока" - в ПРОГРАММИРОВАНИИ - нету "критерия истина". Единственный критерий - ОНО РАБОТАЕТ. Но это по-моему - не очень здорово... Никого не хочу обидеть. На дождь - глупо обижаться, но можно взять зонтик. Надо долго и нудно - РАБОТАТЬ. И с людьми - В ПЕРВУЮ ОЧЕРЕДЬ. И не "гнать коней".

Я не РАЗ задавал людям вопрос - "почему это сделано ТАК, а не "скажем так""... Вопрос! А не претензию. И БЫВАЛО, что я слышал ответ - "а что тебя не устраивает, ведь ВСЁ РАБОТАЕТ". И такие ответы ОБЫЧНО - ставили меня в тупик. Я конечно находил ОБЫЧНО контр-примеры. Но ПОНИМАЛ, что НЕ УБЕДИЛ! Потому что - "ВЕДЬ ВСЁ РАБОТАЕТ".. Против этого не попрёшь. По крайней мере в НАШЕЙ профессии. По крайней мере - ПОКА. Пока не будут выработаны "хорошие принципы" программирования. Доносимые на уровне ВУЗов. Мне так кажется...

ВСЁ ЖЕ РАБОТАЕТ... ОЧЕНЬ сложно с ЭТИМ спорить...

Offtopic. Очень много людей приходят в мой блог по контексту "Delphi XE4 crack"

Очень много людей приходят в мой блог по контексту "Delphi XE4 crack".

Друзья! По-моему - пора цивилизовываться.

21-й век же на дворе...

Ваши программы ведь ТОЖЕ будут искать "SuperProgramm crack".

УВАЖАЙТЕ труд ДРУГИХ людей.

Как мы внедряли RUP и почему у нас "это не получилось"

Как мы внедряли RUP и ISO9000 и почему нам "пришлось изобрести свой процесс" и в чём он состоит.

А также - XP, Agile и тесты и assert'ы.

И когда программисту "который всегда работает" читать об этом.

Кстати в своё время наша организация видимо потратила НЕМАЛО средств и МНОГИЕ разработчики прошли по нескольку курсов по RUP. У меня даже есть два или три сертификата.

То есть мы ОТНЮДЬ не "на коленке" подходили к внедрению.

Но! Очень многое из RUP разбивается о то, что "методология" вроде - есть, а НОРМАЛЬНЫХ инструментов - нету. Даже "родные" инструменты типа ClearQuest, ClearCase, RequisitePro и ДАЖЕ Rational Rose - оставляли желать ГОРАЗДО ЛУЧШЕГО. При этом стоили как САМОЛЁТ - на КАЖДУЮ лицензию. И покупка их IBM'ом ситуацию только усугубила.

И при всём при этом у них ещё и проблемы с русским языком и русской кодировкой. Особенно в CQ и RP.

В итоге - вместо ClearQuest (и отчасти RequisitePro) был куплен чужой продукт и СИЛЬНО ПЕРЕРАБОТАН. Фактически - УЖЕ написан свой. Вместо ClearCase - CVS и SVN. С UML - пока есть проблемы. Есть свои решения, но "недоразвитые" и компромиссные.

Ну и всё же проблема даже не в этом.

Проблема в том, что к RUP - "НЕЛЬЗЯ ПОДХОДИТЬ КАК К ДОГМЕ" (http://18delphi.blogspot.com/2013/05/uml_16.html). Это не СРАЗУ удаётся ВСЕМ понять.

Там прописаны - РЕКОМЕНДАЦИИ. Весь Development Case пытаться писать - ЛУЧШЕ ДАЖЕ НЕ БРАТЬСЯ. Не нужен он.

То же касается и ролей и взгляда на фазы.

УЖЕ - получается "свой процесс".

Ну и "человеческий фактор". Не знаю как на западе, но кое что я написал тут - http://18delphi.blogspot.com/2013/05/offtopic-rup.html и тут - http://18delphi.blogspot.com/2013/05/blog-post_22.html  .

При ВСЁМ при этом - в НАШЕЙ организации получилось - БОЛЕЕ ЧЕМ НЕПЛОХО. Но НЕ RUP! А "свой процесс".

Местами даже УЛУЧШАЮЩИЙ RUP. И учитывающий и "отечественную специфику" и специфику организации.

Но местами - ещё не до конца проработанный.

При этом наиболее стандартизированы были самые узкие места - кодирование, моделирование и тестирование.

А также - УПРАВЛЕНИЕ ИЗМЕНЕНИЯМИ.

Это пожалуй САМАЯ сильная сторона "нашего" процесса. У нас любой разработчик может увидеть - ПО КАКОЙ ЗАДАЧЕ был изменён тот или иной код, с точностью до даты и строк кода. В базе знаний. В исторической перспективе. И не просто "комментарий к коммиту", а именно ПРИВЯЗКА изменений К ЗАДАЧЕ.

Управление требованиями - пока - далеко от идеала. Но тут надо отдавать себе отчёт, что практически все заказчики - "внутренние", а это накладывает определённую специфику. Далеко не всегда можно "провести формальную грань", ЗАФИКСИРОВАТЬ требования (хотя бы на время) и "подписать договор. Да и требования (как ни странно) - СИЛЬНО разнообразнее, чем к "просто коробочным продуктам". Большая технологическая цепочка, кроме "просто написания софта". Но мы работаем над этим.

Да и "продуктов" на самом деле - ДАЛЕКО не один. Взаимосвязанных. Что тоже накладывает свой отпечаток. И взаимосвязи там далеко даже не как в Word и Excel и VBA. Там зачастую бизнес-логика перетекает из одного продукта в другой. Или "входом" одного продукта служит "выход" другого. И ИНОГДА - stakeholder'ов - СРАЗУ ОЧЕНЬ МНОГО. С РАЗНЫМИ интересами. На первых порах даже с взаимоисключающими. Это не говоря об ошибках и пользовательских пожеланиях.

Да и продукт - МУЛЬТИПАРАДИГМЕННЫЙ. Не то что Word. ТИПОВ объектов с РАЗНЫМИ наборами ОПЕРАЦИЙ - ОЧЕНЬ много.

Это кстати отчасти объясняет - почему нельзя сделать продукт слёту "похожим на браузер", с его вкладками и минималистичностью интерфейса, что в последнее время является как бы "трендом". Продукт - НА ПОРЯДКИ сложнее. По смыслу своему. На порядки - профессиональнее. По наполнению и количеству РАЗНЫХ объектов.

Пока коротко скажу - как Я вижу то, что мы в итоге получили - мы получили БОЛЬШОЙ процесс "типа RUP" в рамках которого в отдельных фазах работает что-то "типа XP". Ну это - МОЙ взгляд - на совсем дилетантском уровне.

... to be continued ...

P.S. Вот тут - http://18delphi.blogspot.com/2013/07/xe4.html ОЧЕНЬ правильно

вторник, 21 мая 2013 г.

Offtopic. неКороткая заметка: Почему RUP и "прочие западные практики" не ложатся на российскую почву

http://ru.wikipedia.org/wiki/RUP

Я долго думал об этом.



И не раз ловил себя на мысли, что все "продвинутые западные практики" в БОЛЬШИНСТВЕ своём основаны на "демократизме" и "разговоре на равных". А также на вовлечённости  "заказчика" (и прочих заинтересованных лиц, в частности и разработчиков) в процесс.

Так вот сколько я видел в своей практике - У НАС (в России) - такого - НЕТ.

Ну НЕ ЧИТАЮТ заказчики диаграммы. И НЕ ДЕТАЛИЗИРУЮТ требования. НИГДЕ, в России. Я лично - такого не видел. И не участвуют в приёмке.

Заказчиками выступают, либо "сильно занятые люди", либо "очень творческие", которым "не до мелочей".

Я это видел кстати ОЧЕНЬ и ОЧЕНЬ давно, когда писал АРМ для канцелярии полка милиции. Году в 94-м.

УМНЫЕ люди пишут - "надо привлекать к разработке stakeholder'ов и выяснять у них ВСЕ детали, чтобы они становились частью команды разработчиков". Я что-то не так понимаю? Может быть. Но я ТАКОГО в своей практике - НЕ ВИДЕЛ. Stakeholder'ам ИНТЕРЕСНО общаться с разработчиками - ТОЛЬКО пока "идея кипит и брызжет". Как только появляются "тысячи нудных и неудобных мелочных вопросов" - интерес - ПРОПАДАЕТ. Что - ЕСТЕСТВЕННО. Интересно же красить "крупными мазками", а детали.. В деталях же - дьявол зарыт... А он - неинтересен.

Это с одной стороны.

А с другой - все эти практики предполагают "командную работу", когда опять же - ВСЕ ВОВЛЕЧЕНЫ в процесс. И КАЖДЫЙ может чем-то поступиться в угоду общему делу. Но какая командная работа может быть, когда у нас - "каждый второй" - гений (это типа самоирония и сарказм в одном флаконе)? Какое "общее дело", если "я лично это вырастил"?

Code Review и указание на необходимость рефакторинга - "это удар по самолюбию". Именно поэтому я на эти темы в последнее время стараюсь говорить "осторожно" (насколько я вообще способен к такой осторожности).

Да и потом. Мы же можем "писать код без ТЗ вовсе". Не нужны нам такие мелочи как ТЗ. Нам так "интереснее". А ТЗ - "отнимают время". А тесты - "тем более". Знакомо?

То есть с ОДНОЙ стороны - все "западные практики" предполагают некий "демократизм" на этапе ОБСУЖДЕНИЯ, а с другой - "собранность и САМОКОНТРОЛЬ" - на этапе РЕАЛИЗАЦИИ. Ни того, ни другого я в России что-то не наблюдаю.

Я конечно передёргиваю (и никого конкретного не имею в виду). Может кстати и "на западе" так же?

Но я просто пытаюсь передать ОЩУЩЕНИЯ. Возможно я неправ. Как любит говорить один мой знакомый - "с этой мыслью надо переспать"...

Тут ИМЕННО дело в "ощущениях", а не в КОНКРЕТНЫХ фактах.

Просто я читаю книги УМНЫХ людей, а по факту - вижу "всё наоборот". И это (что самое странное) - кажется - ОЧЕНЬ естественным. Мол - "ваши западные практики" - нам не указ.

То ли дело в менталитете, то ли в исторической "тоталитарной системе" (хотя это бред по-моему).

То ли я лично - идеализирую "западные практики".

И я не говорю о той организации в которой работаю я. Я говорю о "настроениях вообще". Я много общаюсь с людьми из других организаций. И вижу, что практики "не ложатся" - не по причинам "непонятости" или "неудобности", а именно по причинам "филосовской" несовместимости.

Разрыв очень большой между "технарями" и "генераторами идей".

В итоге приходится "изобретать свои практики". А может это и правильно... Всё должно расти на СВОЕЙ почве.

P.S. Я думал об это же ещё 17-ть лет назад когда работал в Diasoft. Отчасти поэтому я оттуда и ушёл. Может я чего-то так и не понял...

P.P.S Почему-то многие у нас в стране не готовы к "парадигме конвейера" для программной разработки. Это я вижу по вопросам, которые мне задают. Просто - если "конвейер", то вопрос не может "ждать две недели". Или ТЗ - не проработано. У нас в организации кстати - "конвейер". По большей части. Не без проблем, но всё же...

P.P.P.S Просто например вопросы "а зачем тестирование" - повергают меня лично в шок. Хочется спросить - "а зачем методы поверки в технике"?

P.P.P.P.S Не сочтите кстати, что я "брюзжу" (что мне свойственно). Наоборот. Я пытаюсь конструктивно посмотреть на реалии. И делать из них выводы. Глупо же обижаться на дождь, но можно например взять зонтик.

P.P.P.P.S Кстати - "западные подходы" - на западе то работают?

P.P.P.P.P.S Почему вообще возник этот вопрос? Да потому, что программирование в отличии от техники (http://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%B2%D0%B5%D1%80%D0%BA%D0%B0) или фармацевтики (http://ru.wikipedia.org/wiki/Good_Manufacturing_Practice (у меня мама кстати GMP плотно занимается - http://pharmpersonal.ru/publs/statji/arxiv/podgotovka-personala-ne-problema.html http://www.gmp-club.com/ru/about/gratitude.html хотя сейчас уже и не в рамках СКИФ)) - это "изотерика"... Работает - "и ладно" - практика - критерий истины.. Способы поверки - неочевидны... Пока по крайней мере...

На закуску - http://ru.wikipedia.org/wiki/ISO_9000

"Регламенты и инструкции" - МОЖНО написать. Но КАК "заставить" ВСЕХ им следовать? Чтобы не получалось как на "слайде" в начале поста...

Кто-то НЕ ЗАХОЧЕТ в силу своего положения, а кто-то "обидится" - потому что - "гений"..

И главное - КАК не ОШИБИТЬСЯ в НАПРАВЛЕНИИ "куда идти"? Чтобы не получалась "методология ради методологии", а "тесты - ради тестов", а "инструкция - ради галочки"...?

"А "заставишь" - в инструкциях и регламентах ВСЕГО не предусмотришь... И тогда, на любое отступление все будут спрашивать "что делать?"
И получим "ручное управление"?"

Чудесный ужас №2

Первая серия была тут - http://18delphi.blogspot.com/2013/05/blog-post_6566.html

Я конечно уважаю "Остап Ибрагимыча".

И я могу найти - МИЛЛИОН доводов - почему, код приведённый ниже - написан так, а не иначе. НО! Очень сложно будет убедить меня, что он "не пахнет".


Чудесный ужас №2:
....
    property ActiveControl: TWinControl read FActiveControl write SetActiveControl
      stored IsForm;
...
procedure TCustomForm.Loaded;
var
  Control: TWinControl;
begin
  inherited Loaded;
  if ActiveControl <> nil then
  begin
    Control := ActiveControl;
    FActiveControl := nil;
    if Control.CanFocus then SetActiveControl(Control);
  end;
end;
и ХЕ:
procedure TCustomForm.Loaded;
var
  Control: TWinControl;
begin
  inherited Loaded;
  if (ActiveControl <> nil) and ((Parent = nil) or not (csDesigning in ComponentState)) then
  begin
    Control := ActiveControl;
    FActiveControl := nil;
    if Control.CanFocus then SetActiveControl(Control);
  end;
– называется - "чота мы залатали"... Но глаз - даже не резануло.. :-( Жалко, что у людей не сработало "чувство запаха".
А ведь 80% этого "ужаса" снялось бы введением метода ForceSetActiveControl.
Но у меня есть МНОГО претензий к коду Borland'а в части обработки фокуса, особенно при наличии докинга.
... to be continued ...

P.S. До придумки Apple в xCode - ShowContextMenuForView, BecomeFirstResponder и CanBecomeFirstResponder - этому коду конечно далеко. Apple - "умнее" - он исходные коды не даёт. А то бы - я наверное многое бы там почерпнул....

P.P.S. А для докинга там есть продолжение. ActiveControl - не всегда в итоге устанавливается. Ибо CanFocus не всегда true.

P.P.P.S Опять спросили "ЗАЧЕМ я всё это пишу". Да ни зачем собственно. Просто чтобы привлечь внимание к вещам, которые меня волнуют. Заставить задуматься. А не потому, что я верю в то, что "кто-то исправит" или "кто-то прислушается". Просто есть хороший повод показать - как я бы делал бы и как я бы не делал бы.

пятница, 17 мая 2013 г.

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

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

http://habrahabr.ru/post/169389/

Вообще - я конечно хорошо жил, когда "интернетов не читал"... fido - по-моему - посолиднее всё же было...

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

P.S. И по-моему Open Tools API - так никто по сути и не переплюнул. Или я чего-то не понимаю...

Чудесный ужас (или - все допускают ошибки)...

Нет. Я конечно очень уважаю "Остап Ибрагимыча" (разработчиков Borland'а). И это не пустые слова. Мне до их уровня - ещё расти и расти. Но у меня в голове всё никак не укладывается вот это:


  TControlActionLink = class(TActionLink)
  protected
    FClient: TControl;

...

  TWinControlActionLink = class(TControlActionLink)
  protected
    FClient: TWinControl;

....

- может быть я чего не понимаю или "не так воспитан".

По мне - одноимённые protected поля в соседних классах - это не комильфо. Особенно если они выполняют ОЧЕНЬ СХОДНЫЕ функции. Куда лучше было бы хотя бы назвать одно поле FClientControl, а другое - FClientWinControl. На мой вкус. Не говоря уж о ненужном дублировании данных.  Всегда вообще-то можно приведение типов написать. И проверку в момент присвоения (AssignClient). Не говоря уж о то, что эта ссылка - НИГДЕ не чистится. А тут имеем БОЛЬШИЕ проблемы с Detsroy. Я правда пока ещё не нащупал - какие именно. Нащупаю - обязательно напишу.

Но по мне этот код и производные от него - "дурно пахнут". Простите уж.

Я думал - хоть под XE это переделали... Ничего подобного :-(

(+)


  TToolbarButton97ActionLink = class(TControlActionLink)
  protected
    FClient: TCustomToolbarButton97;


- получается, что Borland "задал дурной тон", а другие его - банально подхватили. Без критической оценки.

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

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

Хотя не перестаю уважать разработчиков Delphi. Хорошее дело делают.

P.S. К коду FireMonkey - у меня тоже есть ряд претензий. Я их позже озвучу. Когда глубже вникну в проблему. Ну или напишу, что их нет, если пойму, что это так или убежу себя в том, что их нет.

P.P.S. Я объяснил свою позицию вроде. Буду рад, если кто-то объяснит её ошибочность.

P.P.P.S. Тут кстати явно в языке бы добавить "шаблонную типизацию с наследованием". Как-то так:

  TControlActionLink = class(TActionLink)
  template type TClientType = TControl;
  protected
    FClient: <TClientType>;
  private
    procedure AssignClient(aClient : <TClientType>);

...

  TWinControlActionLink = class(TControlActionLink)
  override template type TClientType = TWinControl;

....

С контролем всего этого хозяйства компилятором. У меня кстати подобное есть. В скриптовой машине. Правда там не статически, а в run-time это проверяется. Ну хотя бы в run-time - сейчас-то ведь не лучше. Сейчас по сути в run-time и происходит.

А ещё я бы TActionLink - сделал бы вложенным классом. Тоже с "шаблонной типизацией с наследованием". И различал бы abstract class и не abstract class. И требовал бы типизацию для неабстракных классов.

TControl = class(TCompenent)
 template type TControlActionLink = class(TActionLink)
  template type TClientType = TControl;
  protected
    FClient: <TClientType>;
  private
    procedure AssignClient(aClient : <TClientType>);
 ...
 end;
 ...
end;
 
 
TWinControl = class(TControl)
 reimplement template type TControlActionLink = class(TControl.TControlActionLink)
  override template type TClientType = TWinControl;
 end;
...
end;

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

Ввести
function TClientType_Class: TControl; virtual;

Определять её в КАЖДОМ классе, где переопределён TClientType:


class function TControl.TControlActionLink.TClientType_Class: class of TControl; virtual;
begin
 Result := TControl;
end;
 
class function TWinControl.TControlActionLink.TClientType_Class: class of TControl; override;
begin
 Result := TWinControl;
end;
 
class function TControl.TControlActionLink_Class: class of TControl.TControlActionLink; virtual;
begin
 Result := TControl.TControlActionLink;
end;
 
class function TWinControl.TControlActionLink_Class: class of TControl.TControlActionLink; override;
begin
 Result := TWinControl.TControlActionLink;
end;



Вместо:
 FClient := aValue;
компилировать:
 FClient := aValue As TClientType_Class;

Вместо:
 FActionLink := TControlActionLink.Create(Self);
компилировать:
 FActionLink := ControlActionLink_Class.Create(Self);

Ну как-то так. Ну и по рекурсии конечно.

Ну и при статическом обращению к полю FClient и FActionLink - раскрывать их тип в зависимости уже от контекста. Для TControl подставлять одно, для TWinControl - другое. Всё кстати - срастается.


СЛОЖНО - да. Но не невозможно. У себя в скриптах - я пожалуй такое сделаю. Не вижу там препятствий.

Это конечно тоже - "Чудесный ужас". Но из другой оперы. Разрыв шаблонов.

В шаблонах кодогенерации я кстати уже сделал подобное. В шаблонах VCM (не путать с MVC, хотя это из той же оперы, только View->Controller->Model(->Data)). А я то и смотрю, что что-то - знакомое. Когда я до конца это расписал. Привести пример с картинками и кодом?

P.P.P.S. Подозреваю, что всё, что я описал - в каком-нибудь "экзотическом" языке программирования - УЖЕ есть. Мне вообще - пока не удалось - что-нибудь РЕАЛЬНО новое придумать.

О кодогенерации

Вот код, он генерируется с ОДНОГО "квадрата на модели":


program SearchTest;
 
uses
...
  ;
 
{$R SearchTest.res}
 
begin
 {$IfDef nsTest}
 g_CVSPath := 'w:common\components\SearchTest';
 {$EndIf nsTest}
 //#UC START# *511B4CA100B2CVSPath*
 //#UC END# *511B4CA100B2CVSPath*
 TAutoTestsSuite.Register;
 try
  if KTestRunner.NeedKTestRunner([TToK]) then
   KTestRunner.RunRegisteredTests
  else
  if System.IsConsole then
   TextTestRunner.RunRegisteredTests
  else
   GUITestRunner.RunRegisteredTests;
 except
  on E: Exception do
  begin
   {$If defined(MTDORB) AND defined(NoKPageTool)}
   if TKBridge.Exists then
    TKBridge.Instance.Logout;
   {$IfEnd}
   l3System.Exception2Log(E);
   Halt(2);
  end;//Exception
 end;//try..except
 if (TestsExitCode <> 0) then
  Halt(TestsExitCode);
end.


А генерируется он так:

// реализация абстрактного стереотипа Delphi интерфейсы и реализация::MDAGenerator
// Реализация на Delphi(.pas)
+ impl.pas
R  
//#UC START# *470F15B800CBfor470382290251*
//#UC END# *470F15B800CBfor470382290251*
 
// реализация абстрактного стереотипа Delphi интерфейсы и реализация::MDAGenerator
// Родные Delphi интерфейсы (.pas)
+ intf.pas
R  
//#UC START# *470F1571031Cfor470382290251*
O [{"%f_pas_UnitFileName(%S)"!=""}[{%S{finished}!=true}NOT_FINISHED_]%f_pas_UnitFileName(%S)]
C %S%f_pas_UnitPath()
 %f_clear_list(TOTAL_USES)
 %f_pas_OpenUnitInterface(%S)
 
 [{%S{console}=true}
 
 {$APPTYPE CONSOLE}
 ]
 
 [{%SS=VCMTestTarget}
 <{}{%D#f_IsVCMGUI()=true}
 %D%f_OutExtIntfUses()
 %f_cycle_break(%S)
 >
 ]
 
 %S%f_pas_TotalUses()
 [{%S{need UC in project}=true}
 n%U[{manualuses}n]
 ]
 %f_pas_CloseUses(%S)
 %f_clear_TotalUses(%S)
 
 [{%S{console}!=true}
 {$R [{%S{finished}!=true}NOT_FINISHED_]%f_pas_UnitName(%S).res}
 [{%S{needs second icon}=true}n{$R main_icon2.res} // вторая иконка приложения]
 
 ]
 [{%S{need UC in project}=true}
 %U[{manualres}n]n
 ]
 
 begin
 [{%S%f_IsTest()=true}{
  %U[{manualcode}n ]
 }
  {$IfDef nsTest}
  g_CVSPath := '%f_str_replace(%SR%Sd,/,\)';
  {$EndIf nsTest}
  %U[{CVSPath}n ]
 [{%S{need UC in project}=true}{
 [{%SS=VCMTestTarget}{
 [{%S{no scripts}!=true}
  TAutoTestsSuite.Register;\n
 ]
  try
   if KTestRunner.NeedKTestRunner
 ([<{, }{%C#f_IsTestResults()=true}%f_pas_TypeName(%C)>])
  then
    KTestRunner.RunRegisteredTests
   else
   if System.IsConsole then
    TextTestRunner.RunRegisteredTests
   else
    GUITestRunner.RunRegisteredTests;
  except
   on E: Exception do
   begin
    {$If defined(MTDORB) AND defined(NoKPageTool)}
    if TKBridge.Exists then
     TKBridge.Instance.Logout;
    {$IfEnd}
    l3System.Exception2Log(E);
    Halt(2);
   end;//Exception
  end;//try..except
  if (TestsExitCode <> 0) then
   Halt(TestsExitCode);
 }
  TF1AutoTestSuite.Register;
 <{}{%D#f_IsVCMGUI()=true}
 %D%f_OutApplicationBody()
 %f_cycle_break(%S)
 >
 ]
 }
  %U[{manualcode}n ]
 ]
 ]
 %f_pas_CloseUnit(%S)
 <{}{%CV!=PrivateAccess&%C#f_IsClassInner()!=true&"%CO"!=""}%CX>
//#UC END# *470F1571031Cfor470382290251*

-- по-моему - всё понятно.

четверг, 16 мая 2013 г.

На что надо обратить внимание при портировании с Delphi 7 на Delphi XE3


1. String = WideString
PChar = PWideChar
Char = WideChar
– это - более чем весело (особенно PChar <> PByte, ведь ни для кого не секрет, что многие использовали PChar Не как "указатель на символ", а как "указатель на byte к которому применима адресная арифметика". Fail тут - обеспечен).
Я "тупо" взял и поменял всё это на AnsiString, PAnsiChar, AnsiChar. Поиском/заменой. А потом - поменял обратно - там где не собралось - в стандартных классах. Там где override. Типа KeyDown. Ну и естественно поменял - шаблоны кодогенерации.
2. FormatSettings - теперь запись с полями и методами. ShortDateFormat теперь равно FormatSettings.ShortDateFormat etc.
3. менеджер памяти - другой. Со всеми вытекающими. Кстати при ПРАВИЛЬНОМ подходе - позволяет найти много ошибок в старом коде "не сходя с места".
4. канва почему-то несколько по-иному себя ведёт
5. NativeInt etc. И их несовместимость с Integer и Cardinal. ДАЖЕ в 32 битах.
6. Часть функций API стали принимать/возвращать беззнаковые значения, вместо знаковых. И наоборот.
7. Записи по умолчанию на 8 байт выравниваются. Если вы использовали, что-то типа THackControl или записи на диск - тут надо быть внимательным.
8. Forms -> VCL.Forms etc.

Ну и ссылка от Embarcadero. Не совсем в тему, но полезная:
http://docwiki.embarcadero.com/RADStudio/XE4/en/Converting_32-bit_Delphi_Applications_to_64-bit_Windows

Банальное об UML и моделях вообще

Первое что хочу озвучить - НИЧТО НЕ ДОГМА. Ни TDD, ни UML, ни вообще "хорошие практики программирования". Всё - ЭВОЛЮЦИОНИРУЕТ. Это надо ПОНЯТЬ. То что считалось хорошим - завтра может быть уже "устаревшей практикой" и наоборот.

Хочу рассказать СВОЙ взгляд на проектирование проектов на "модели".

Так как я для СЕБЯ это понимаю. И так - как я это пытаюсь презентовать это вновь прибывшим коллегам устно.

Я не буду пытаться рассказать о "космических технологиях" или <<стереотипах>> или устройстве нашей кодогенерации. Тем боле, что ПОКА - что-то не получается.

Хочется сказать БАНАЛЬНЫЕ вещи, которые на самом деле - являются основой и из которых вытекает всё остальное.

"САМЫЙ НАУЧНЫЙ СПОР - это СПОР О ТЕРМИНАХ"...

Повторю ещё раз:

"САМЫЙ НАУЧНЫЙ СПОР - это СПОР О ТЕРМИНАХ"...

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

Например:
Эта библиотека может зависеть от этой? А эта от этой? А циклические зависимости тут возможны?

В какую папку поместить компонент X - в common\rtl или в rtl\common?

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

Где граница между подсистемами? Это ещё данные? Или УЖЕ бизнес-объект? Или КОНТРОЛЛЕР? Или может ПРЕДСТАВЛЕНИЕ? Как они должны зависеть друг от друга?

Как проекты могут зависеть друг от друга?

Фабрики? Dependency Injection? Как? Зачем и почему?

Шаблоны GoF? Где и как?

И пишутся ИНСТРУКЦИИ. И ведутся СПОРЫ. И все "друг друга пинают" за несоблюдение инструкций. Аппелируют к регламенту. Шучу конечно. Но в каждой шутке... Но - "тыкать в инструкцию" - это ведь некоструктив. И это - НИКАК не улучшает производительность труда.  А что иначе делать? Или забить на инструкцию?

И главное - ВСЕ МЫ ЛЮДИ. Мы НЕ УМЕЕМ тупо соблюдать инструкции. Особенно многостраничные. Даже ЕСЛИ ЗАХОТИМ. А мы ведь - ХОТИМ. Но не МОЖЕМ.

А как требования трассируются на код? Какой участок кода выполняет это требование? А это требование протестировано? Как?

Вопросы.. Вопросы..

А как вообще должны называться проектные папки? "Самый научный спор - это спор о терминах".

Рут проекта где должен находится? В стандартизованном месте или как захочется разработчику?

А вот этот код это уже реализация прецедента? Или ещё представление? Или что-то ещё? И где вообще собственно реализация прецедента?

И через ВСЁ это - я прошёл. И не раз.

И могу сказать, что модель - это конечно не "серебряная пуля". Но это ОТВЕТ на МНОГИЕ вопросы.

Модель - снимает многое из этой "пены на волне". Она - ВЕДЁТ разработчика в ПРАВИЛЬНОМ направлении. Она де даст поставить циклические зависимости - ТАМ ГДЕ ЭТО НЕВОЗМОЖНО. И даст - там где возможно.

Она не даст нарисовать бизнес-объект на уровне данных. Просто физически. И она не даст нарисовать зависимость от данных к представлению. Что компилятор Delphi - НИКАК не контролирует.

Повторюсь - "модель и её шаблоны - не ДОГМА". Но они служат "ремнями безопасности" или даже скорее "тьюторами" для тех раз разработчиков, которые ХОТЯТ СОБЛЮДАТЬ ПРАВИЛА, но которым тяжко каждый раз сверяться с инструкцией.

Вот как-то так. Это - вершина айсберга. Далее конечно есть "шаблоны проектирования" или "параметризация классов" или "устойчивые проектные решения", но это - ДАЛЬНЕ. Но в первую очередь - это то, что проектирование на модели умеет вести разработчика нужной колеёй.

Например (опять же - это не догма) - модель не даст провести связь к данным миную контроллер или бизнес-объект. Просто ФИЗИЧЕСКИ не даст. Ну если правила игры (шаблоны) такие.

Да! модель (на первый взгляд) - "бьёт по рукам" разработчикам (Embarcadero кстати тоже не прочь "дать по рукам" - http://18delphi.blogspot.com/2013/04/delphi-language.html, и это кстати, на мой взгляд - "правильно"). Она ограждает их от "неверных" решений ( в данной конкретной среде). Но! Надо не забывать только одну вещь - среда тоже - НАСТРАИВАЕМА. Ничто - не догма. Всё МЕНЯЕТСЯ.

Нужны циклические зависимости? На этом уровне? Окей - давайте - введём. Если они ОБОСНОВАННЫ. Но! Das Ordnung muss sein. Если решили так - то - решили. До следующего ревью мета-модели. Которое конечно надо "делать на лету, но всё же дискретно и ВСЕМИ заинтересованными участниками процесса. А не "тихо гундеть в углу". И "в минуты передышки".

НО! При этом. В каждый конкретный момент времени есть - "ощущение порядка и автоматического соблюдения договорённостей". Мне лично - это нравится. Не нравятся договорённости - давайте их менять. Но они - ДОЛЖНЫ БЫТЬ! Какие-то. Должны быть "общие правила игры". В общем - не суть важно - какие. Хотим "стоять на голове" - давайте стоять на голове. Но - ВСЕ вместе, а не КАЖДЫЙ в свою сторону. Дурацкие договорённости? Дурацкие! Но - должны быть. Хотя бы какие-то. И АВТОМАТИЧЕСКИ валидируемые. Чтобы не углубляться "в самый научный спор" на этапе разработки.

Вот как-то так я всё это вижу. Рассказывать дальше про UML и модели? Или я не найду отклика?

P.S. UML тут кстати не совсем причём. Даже может "совсем не причём". Он лишь одна из реализаций. А вообще говоря - надо бы иметь средства мета-мета-программирования (проектирования).

среда, 15 мая 2013 г.

Предварительная статистика по портированию на Delphi XE3

Предварительная статистика и итоги по портированию на Delphi XE3 с Delphi 7:

1. Сделано более 5000 коммитов.
2. Найдено два десятка ошибок в СТАРОМ коде.
3. Написано три десятка новых тестов.
4. Выяснено, что менеджер памяти в XE3 гораздо лучше, чем в Delphi 7.
5. Десяток классов нарисовано на модели.
6. Поправлен десяток шаблонов кодогенерации с учётом специфики XE3.
7. Вчерне заработано 8 проектов собранных под XE3. При этом их версии собранные под Delphi 7 (из ТЕХ ЖЕ САМЫХ исходников) - НЕ РАЗЛОМАЛИСЬ.
8. Порядка 100 тестов из ~2000 ещё не проходят.
9. Поправлен десяток страниц документации.
10. Стало окончательно понятно - зачем нужны "атомарные" тесты.
11. Выяснено, что несколько ошибок VCL - так и не поправлено.
12. Выяснено как получать размер куска памяти распределённого новым менеджером памяти (ну это хоккей конечно).
13. Выяснено, что "заглушки" (http://18delphi.blogspot.com/2013/03/blog-post_5929.html) взамен "анонимных функций" - продолжают работать.
14. Выяснено, что "Generic'и без Generic'ов" (http://18delphi.blogspot.com/2013/03/generic-generic.html) - продолжают работать.
15. Выяснено, что старая VGScene - прекрасно собирается и работает под XE3 И смешивается с контролами VCL.

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

Портирование на Delphi XE3 прошло не зря и в общем - удачно

Скоро приедет более десятка ключей на Delphi XE4. Так что - будем работать дальше.

Визуализатор прогресса


unit afwLongProcessVisualizer;
 
interface
 
uses
  afwInterfaces,
  l3Base,
  l3AsincMessageWindow
  ;
 
type
 TafwLongProcessVisualizer = class(Tl3Base, IafwLongProcessVisualizer)
 private
 // private fields
   f_Wnd : Tl3AsincMessageWindow;
    {* Собственно окно с сообщением.}
 protected
 // overridden protected methods
   procedure Cleanup; override;
     {* Функция очистки полей объекта. }
 public
 // public methods
   constructor Create(const aCaption: IafwCString;
    anAttachWnd: THandle = 0;
    anInitialTimeout: Cardinal = afw_lpwTimeout;
    anImageList: TafwCustomImageList = nil;
    anImageIndex: Integer = -1); reintroduce;
     {* Создает экземпляр класса. }
   class function Make(const aCaption: IafwCString;
    anAttachWnd: THandle = 0;
    anInitialTimeout: Cardinal = afw_lpwTimeout;
    anImageList: TafwCustomImageList = nil;
    anImageIndex: Integer = -1): IafwLongProcessVisualizer; reintroduce;
     {* Создает экземпляр класса в виде интерфейса IafwLongProcessVisualizer. }
 end;//TafwLongProcessVisualizer
 
implementation
 
// start class TafwLongProcessVisualizer
 
constructor TafwLongProcessVisualizer.Create(const aCaption: IafwCString;
  anAttachWnd: THandle = 0;
  anInitialTimeout: Cardinal = afw_lpwTimeout;
  anImageList: TafwCustomImageList = nil;
  anImageIndex: Integer = -1);
begin
 inherited Create;
 f_Wnd := Tl3AsincMessageWindow.Create(aCaption, anImageList, anImageIndex,
                                       anAttachWnd, anInitialTimeout);
end;//TafwLongProcessVisualizer.Create
 
class function TafwLongProcessVisualizer.Make(const aCaption: IafwCString;
  anAttachWnd: THandle = 0;
  anInitialTimeout: Cardinal = afw_lpwTimeout;
  anImageList: TafwCustomImageList = nil;
  anImageIndex: Integer = -1): IafwLongProcessVisualizer;
var
 l_Inst : TafwLongProcessVisualizer;
begin
 l_Inst := Create(aCaption, anAttachWnd, anInitialTimeout, anImageList, anImageIndex);
 try
  Result := l_Inst;
 finally
  l_Inst.Free;
 end;//try..finally
end;
 
procedure TafwLongProcessVisualizer.Cleanup;
begin
 FreeAndNil(f_Wnd);
 inherited;
end;//TafwLongProcessVisualizer.Cleanup
 
end.