ДИАЛОГ С УЧИТЕЛЯМИ: ИТОГОВЫЙ КОНСПЕКТ ВСЕГО РАЗГОВОРА
═══════════════════════════════════════════════════════════════════
ЧАСТЬ 1. ТЕСТЫ КАК СПЕЦИФИКАЦИЯ (ГЛАВНЫЙ ПРИНЦИП)
• Тесты — не проверка кода, а формальные, проверяемые, живые требования
• Тест пишется до кода (Test First) или до исправления ошибки (Test After)
• Тесты — мост между абстракцией и реализацией, который не ржавеет 40 лет
• ?ASSURE — падай сразу на первом нарушении инварианта
• Эталоны создаются автоматически при первом запуске (CheckEtalon)
• Платформозависимые эталоны: .FPC / .LCL* / .XE / .Linux / .Some64
• Каждая ошибка → тест. Тест остаётся в репозитарии навсегда.
• Тесты — это "приёмо-сдаточные испытания и критерии поверки"
ЧАСТЬ 2. ТЕСТОВАЯ ИНФРАСТРУКТУРА (utBaseTest, DUnit, FPCUnit)
• TutBaseTest — базовый класс всех тестов (f_UseCase, f_TestName)
• TutOutputTest — один выходной файл → сравнение с эталоном
• TutInputToOutputTest — один входной → один выходной
• IsMulty = true — размножение тестов для всех файлов в папке
• //$Param *.ext — параметризация скриптовых тестов
• f_Exceptions — сбор ошибок, падение один раз со всеми
• Надстройки над DUnit: эталоны, замеры времени, FORTH-скрипты, публикация
результатов, preset'ы, случайный порядок с RandomSeed, списки исключений,
генерация из Rational Rose, размножение тестов, пользовательские формы,
InsiderTest'ы (тестирование готовых приложений)
ЧАСТЬ 3. АРХИТЕКТУРА ТЕСТОВ (НАСЛЕДОВАНИЕ КАК ПАРАМЕТРИЗАЦИЯ)
• Каждый новый случай — отдельный класс-наследник
• Переопределяются только FillKeys / FillValues / FillList
• Базовый класс содержит всю логику проверки
• Ни один старый тест не ломается, не переписывается
• Пример: Tm3AttrIndexWriterPackTest (5000) → Test1 (20000) → Test2 (40000)
• Пример: StackTest.imp.pas — один шаблон теста для TIntStack и TStringStack
ЧАСТЬ 4. ПРИМЕСИ (MIXINS) И АСПЕКТЫ (AOP)
• Примесь — класс, реализующий чётко выделенное поведение
• Встраивается в иерархию наследования через Include-шаблоны
• Пример: RegionableControl.imp.pas → RoundedControl.imp.pas → TRoundedButton
• Одна примесь работает с TEdit и TButton (разные иерархии)
• В коде: TevBullet2TextFilter.SetTo(l_G), TevEmptyTableEliminator.SetTo(l_G)
• Аспекты (логирование, печать, аудит, скины) ортогональны UseCase
ЧАСТЬ 5. GENERIC'И БЕЗ GENERIC'ОВ (INCLUDE-ШАБЛОНЫ)
• Шаблоны в Delphi 7 через {$Include файл.imp.pas}
• _ItemType_ — параметр типа
• _StackPrim_Parent_ — точка встраивания в иерархию
• Одна реализация — много специализаций (TIntStack, TStringStack,
TIntStackFromPersistent, TIntStackFromComponent)
• Работает 15+ лет (на момент поста) и до сих пор
ЧАСТЬ 6. FORTH-МАШИНА (tfwScriptEngine, l3Stub)
• Полноценная скриптовая система на Delphi 7
• Стек, ОПЗ, слова, переменные, массивы
• Лямбды и итераторы (.filter>, .map>, .for>)
• Определение классов, исключения, потоки (THREAD)
• Обработка модальности (модальные объекты получают свой скрипт)
• Доступ к RTTI Delphi, проекция Delphi-классов на словарь
• l3Stub — генерация кода на лету (16 байт машинного кода)
• l3LocalStub превращает локальную функцию в заглушку для итератора
ЧАСТЬ 7. UML И MDA (МОДЕЛЬ-ОРИЕНТИРОВАННАЯ АРХИТЕКТУРА)
• Сначала диаграмма → потом скелет кода → потом «мясо»
• Диаграмма не должна быть больше, чем можно охватить взглядом
• Размер диаграммы — диагностический признак сложности
• Стереотипы (<<TestTarget>>, <<Project>>) для расширения UML
• Кодогенерация из Rational Rose
• MUID — уникальные идентификаторы элементов модели
• UML как "матрёшка" — одно вкладывается в другое
ЧАСТЬ 8. VCM И MVC (VIEW-CONTROLLER-MODEL)
• Операция — атомарное действие
• Сущность — группа операций
• Форма — реализатор сущностей
• Контрол — кирпичик формы
• Источник данных формы (невизуальный)
• Зона — место для встраивания форм
• Сборка форм (прецедент) — набор форм для сценария
• Аспекты примешиваются к форме через SetTo
ЧАСТЬ 9. АПРЕЛЬСКИЕ ТЕЗИСЫ (КОНЕЧНЫЕ АВТОМАТЫ)
• Система описывается конечным, дискретным набором состояний
• Активности переводят систему из состояния в состояние
• Состояния характеризуются атрибутами и набором доступных активностей
• При переходе — нотификации для GUI
• При необходимости — запросы на подтверждение (с ответом по умолчанию)
• К визуальным элементам привязываются активности
• Состояния могут содержать подсостояния
• GUI неразличимы состояния с одинаковыми наборами активностей
• Система не выводит диалоговых окон (только нотификации и подтверждения)
• Активности транслируются по иерархии активных объектов
ЧАСТЬ 10. ПОДСЧЁТ ССЫЛОК И УПРАВЛЕНИЕ ПАМЯТЬЮ
• Реализация подсчёта ссылок в Delphi 1 (до появления интерфейсов)
• Симметрия: кто владеет объектом, тот его и освобождает
• Метод BeforeRelease — для сохранения состояния до удаления
• Cleanup — для освобождения внутренних полей
• Undo/Redo как драйвер: у объектов нет централизованного "папы"
• Проблема из GoF: Command без подсчёта ссылок — игрушка
ЧАСТЬ 11. TSWAPPER — СВОПЕР ИЗ 1990-Х
• Боксы (boxes) — контейнеры блоков на диске
• Фиксированный размер блока (cBlockSize) — плюс, а не минус
• MoveBlock — перелинковка без копирования данных
• FreeBox — пул свободных блоков
• Статус ошибки (Status) с человеческими сообщениями
• Система "Вердикт" — работала на выборах в России 1993 года (аналитика)
ЧАСТЬ 12. РЕДАКТОР (EDITOR.PAS, LONGEDIT.PAS)
• GAP-буфер (разрыв) для эффективных вставок/удалений
• TLongFileEditor — подкачка на диск через TSwapper
• Undo/Redo через файл (из-за нехватки памяти)
• Форматирование абзацев, поиск/замена, выделение блоков
• Полосы прокрутки, линейка (Ruler)
ЧАСТЬ 13. UNDO/REDO В ЭВЕРЕСТЕ
• OevInsertPara / OevDeletePara — операции вставки/удаления параграфов
• Ok2AddChildren / Ok2DeleteChildren — групповые операции
• DoJoin — склейка операций (две вставки подряд → одна)
• evTextParaOp — операции над текстом (вставка/удаление строк)
• Подсчёт ссылок для удалённых объектов (живут, пока есть в Undo)
• TevOptimizedContext — оптимизация стека Undo (ClearSuper)
ЧАСТЬ 14. БИТОВЫЕ ОПЕРАЦИИ
• l3SetBit, l3ClearBit, l3TestBit — 32-bit
• l3SetBit64, l3ClearBit64, l3TestBit64 — 64-bit
• l3SetBitW, l3ClearBitW — 16-bit (Word)
• 40+ тестов, 3 разрядности, 2 порядка обхода
ЧАСТЬ 15. СТРОКИ И КОДИРОВКИ
• RawByteString, AnsiString, WideString, Tl3String, Il3CString
• Кодировки: ANSI (1251), OEM (866), UTF-8, Unicode
• Преобразования: Upper/Lower, ANSI↔OEM, Eng↔Rus (раскладки)
• GetWordCount + GetWord = два прохода (алгоритм маляра Шлемиэля)
• l3Compare, l3CompareLite, l3CompareText
• l3IEQ — правильное сравнение интерфейсов (через QueryInterface)
ЧАСТЬ 16. ДИАПАЗОНЫ ID (RANGE LIST)
• Tm3IDRangeList — список диапазонов (сливает пересекающиеся)
• Операции: Add, Remove, Diff, Intersect, NotContainedInBoth, Join
• Сериализация → десериализация (round-trip)
• 14 тестов на Join (все комбинации диапазонов)
ЧАСТЬ 17. ИНДЕКСЫ (ATTRIBUTE INDEXES)
• WriterPackTest — запись индекса (один ключ, 5000 значений)
• Наследники: 20000, 40000, случайные, множественные ключи
• SearcherTest — поиск по индексу (прямой и инвертированный)
• Sequential — флаг упорядоченности ключей
• LSM-подобная структура (основной индекс + дельта)
• Прямой и обратный индексы как E и B у Максвелла (Вильф)
ЧАСТЬ 18. ХРАНИЛИЩЕ (STORAGE)
• ArchiStorageNewTest — импорт папки .evd → storage (через Tm3DB)
• ArchiStorageVersionsNewTest — версионирование (один документ, много версий)
• FullModeStorageTest — низкоуровневый API, без версий
• FullModeVersionedStorageTest — с версиями
• FullModeStackVersionedStorageTest — стековое версионирование
ЧАСТЬ 19. ФОРМАТЫ ДОКУМЕНТОВ
• EVDtoEVDTest — круглая конвертация EVD (текстовый)
• EVDtoEVDBinTest — бинарная конвертация EVD
• EVDtoNSRCTest — EVD → NSRC
• NSRCtoNSRCNewTest — NSRC → EVD → NSRC (round-trip)
• RTFtoEVDTest — импорт RTF
• EVDtoRTFTest — экспорт RTF (низкоуровневый)
• EVDToRTFRenderTest — экспорт RTF (высокоуровневый)
• DOCXtoEVDTest — импорт DOCX
• ODTtoEVDTest — импорт ODT
• Ik2TagGenerator — единый SAX-подобный интерфейс для всех конвертеров
ЧАСТЬ 20. ЭКСПОРТ (PDF, BMP, PNG, SVG)
• EVDToPDFDirectRenderTest — EVD → PDF
• EVDToPDFA1DirectRenderTest — EVD → PDF/A-1 (архивный стандарт)
• EVDRenderToBitmapTest — EVD → PNG (визуализация)
• FormulaRenderTest — формулы → SVG
• FormulaToBMPTest — формулы → BMP
ЧАСТЬ 21. ГРУППОВЫЕ ОПЕРАЦИИ (GroupOperationTest)
• Скриптовый формат .ids (операция + диапазоны + шаблон)
• Операции: Set, Add, Remove, Replace
• Диапазоны: {1,2,3,10-20,+} (+ = 1000 документов подряд)
ЧАСТЬ 22. НИЗКОУРОВНЕВЫЕ КОНТЕЙНЕРЫ
• Tl3PtrArray — массив указателей с битовой картой
• Tl3PtrHash — хеш-таблица указателей
• SetItem/GetItem, Empty, BitCount, IterateF, Clear
ЧАСТЬ 23. RUMTMARC (МЕТОДОЛОГИЯ)
• RUP | UML | MDA | Tests | MixIns | AOP | Requirements | Code
• 20 серий: от интервью с заказчиком до кода
• Роли: AK (требования), AL (архитектор, программист, тестировщик), AT (тестирование)
• Калькулятор → текстовый редактор → StarUML → свой генератор
• Серия остановилась (читателей мало), но идея не умерла
ЧАСТЬ 24. УЧИТЕЛЯ И КНИГИ
• Зернов (физика) — думать и решать задачи. Светлая память.
• Вильф (физика) — «как вы учите физику, так они вас лечат»
• Сичановски — PDP-11, ассемблер (почему C-строки кончаются нулём)
• Баранов, Ноздрунов — «FORTH и его реализации»
• Хоор — аксиоматическая семантика
• Лисков — абстракции и спецификации
• Степанов — STL, итераторы, алгоритмы
• Кнут — искусство программирования, иммутабельность
• Дейкстра — структурное программирование
• Вирт — Паскаль, модульность
• Брукс — «Мифический человеко-месяц»
• Джоэл — «Fire and Motion», 12 шагов (перечитывать каждые новогодние каникулы)
• Джобс — безумцы, меняющие мир
• Александер — «Язык шаблонов» (паттерны в архитектуре)
• Гайдар, Кассиль — «Кондуит и Швамбрания»
ЧАСТЬ 25. ЗНАКОВЫЕ ЦИТАТЫ
• «Формализм без насилия над языком» — Зализняк
• «Ты понял. Концепции — это не магия компилятора. Это способ мышления.» — Степанов
• «Абстракция без спецификации слепа. Спецификация без реализации мертва.» — Лисков
• «Тесты — это мост между ними. И этот мост не ржавеет 40 лет.»
• «Простота — не отсутствие сложности. Простота — когда сложность управляема.» — Дейкстра
• «Вы не свернули. Вы били в одну точку 40 лет. Это главное.» — Джобс
• «Думать и РЕШАТЬ задачи — научил — ИМЕННО ОН.» — Зернов
• «Как вы учите физику, так они вас лечат.» — Вильф
• «Серебряной пули — нет.»
• «За рефакторинг (сам по себе) — не платят.»
• «Говнокодом я называю ТОЛЬКО СВОЙ СОБСТВЕННЫЙ код.»
• «У объектов нет централизованного "папы".» — про Undo/Redo
• «SQL — это зло.»
• «Пишите код, исходя из того, что все программисты, которые будут сопровождать вашу программу, — склонные к насилию психопаты, знающие, где вы живёте.»
═══════════════════════════════════════════════════════════════════
ГЛАВНЫЕ ИНСТРУМЕНТЫ (ПРИЁМЫ)
• Наследование для параметризации тестов
• CheckEtalon — автоматическое создание эталонов
• IsMulty = true — размножение тестов на все файлы в папке
• //$Param — параметризация скриптовых тестов
• Include-шаблоны (.imp.pas) — generics и примеси в Delphi 7
• l3LocalStub — JIT-компиляция на лету (16 байт)
• MUID — уникальные идентификаторы элементов модели
• SetTo — встраивание примесей/аспектов
• BeforeRelease / Cleanup — разделение логики и ресурсов при удалении
• l3IEQ — правильное сравнение интерфейсов
═══════════════════════════════════════════════════════════════════
ГЛАВНЫЕ ВЫВОДЫ
1. Тесты — это спецификация, которая живёт 40 лет
2. Наследование заменяет параметризацию там, где её нет
3. Эталоны должны создаваться автоматически
4. Платформозависимые эталоны — необходимость
5. Примеси (mixins) позволяют встраивать поведение в разные иерархии
6. FORTH-машина — основа DSL и скриптовой системы
7. UML — способ думать, а не просто рисовать
8. Конечные автоматы (апрельские тезисы) — архитектурная основа VCM
9. SQL — не единственный путь (и не всегда лучший)
10. Рефакторинг без тестов — полёт без парашюта
11. CodeReview — диалог, а не дуэль
12. Помнить учителей
13. Подсчёт ссылок — не техника, а архитектурная необходимость
14. Undo/Redo — проверка на живую нить
15. Фиксированный размер блока в свопере — плюс
═══════════════════════════════════════════════════════════════════
ТОЧКИ ВХОДА
• fpcunitproject1.lpr — запуск всех тестов под FPC (графический раннер)
• DailyTest.dpr — запуск всех тестов под Delphi (GUI/Text/KTestRunner)
• TutMSSTests.Register — регистрация скриптовых тестов
• TestCases.pas — реестр всех тестов (точка сборки)
═══════════════════════════════════════════════════════════════════
ЭТО ХРАМ. ОН НЕ РУШИТСЯ 40 ЛЕТ.
☝️ ++!
Комментариев нет:
Отправить комментарий