Мне стыдно у вас такое спрашивать... но я всё равно спрошу.
Зачем нужна кодогенерация?
Разве это не автоматизированный копи-пейст?
Ну, исключая случаи, выходящие за пределы возможностей инструмента: там, сериализация в C++ или сгенерировать Data Object по XML-ю.
И просьбочка: если видите что-то полезное в моём аглицком блоге про .NET, немного Java, WiX, OOP, OOD и немного всё остальное - поставьте на него ссылку, пожалуйста.
Зачем нужна кодогенерация?
Разве это не автоматизированный копи-пейст?
Ну, исключая случаи, выходящие за пределы возможностей инструмента: там, сериализация в C++ или сгенерировать Data Object по XML-ю.
И просьбочка: если видите что-то полезное в моём аглицком блоге про .NET, немного Java, WiX, OOP, OOD и немного всё остальное - поставьте на него ссылку, пожалуйста.
Tags:
(no subject)
12/3/08 12:47 (UTC)Хотя вопрос не вполне ясен. О какой именно кодогенерации идет речь? О вещах типа примеров из http://rsdn.ru/article/dotnet/codegen.xml ?
P.S. А вообще я склоняюсь к мысли, что если что-то с помощью стороннего кодогенератора делается заметно проще, чем средствами языка - это либо дефект языка, либо использование его средств не по назначению. Особенно сильно на эту мысль наводят библиотеки типа stl/boost (чего стоит одна реализация shared_ptr, не говоря уж о вещах типа boost::lambda): уж больно коряво некоторые вещи реализуются на темплейтах C++.
Сорри за некоторую сумбурность...
(no subject)
12/3/08 12:59 (UTC)Да, луче автоматически, но ещё лучше написать единожды.
В целом, моя мысль та же - либо дефект/неспособность платформы, либо программиста.
О статье.
"избавиться от нее штатными средствами ООП не удается" - хи-хи.
"отсутствием в языках .NET generic" - уже неактуально. Дженерики нас спасут.
Пройдёмся по примерам:
* "типизированных коллекций" - generics уже есть;
* "бизнес-классов" - это и есть Data Objects. Поведение всё равно не сгенерируешь.
* "прокси для удаленных объектов" - это и есть сериализация. Если в платформе нет reflection-а. Пример в статье - сериализация в XML, мнэ, удивляет.
Кодогенерация в typed datasets в .NET меня убивает. А есть люди, которые её хвалят - удобно, говорят, к хранимым процедурам обращаться... А я и процедуры не люблю, лишние сущности.
(no subject)
12/3/08 13:32 (UTC)- Дельфи (насколько я могу судить, использование C# или еще какого .net языка ситуацию принципиально не меняет).
- Предопределенный формат файла (лежат поля данных в определенном порядке)
- Есть несколько версий формата файла (различаются по первому полю version)
- Значения полей соответствуют полям или свойствам некоторой формы (включая массивы и биты для boolean-полей).
- Решение "в лоб" #1: написать чтение/запись для каждой версии.
- Решение "в лоб" #2: создать тип данных вроде struct (по типу на каждую версию), написать процедуры переписывания данных из полей/свойств в эту структуру (для каждой версии) и сериализовать ее как массив байт.
- Решение "в духе ООП": создать классы-обвязки для основных типов полей/свойств (с общим предком), создать для каждой версии объект-контейнер (который хранит ссылки на все сериализуемые поля/методы в нужном порядке), в нужный момент создавать такой объект и дергать его методы Load/Save/Import
- Решение, которое выбрал я:
-- Создать для каждой из версий файл, в котором все сериализуемые поля/свойства записаны как строки типа int Form1.Property1
-- Генерить простой код сериализации по этим файлам и включать его директивой include в качестве процедуры.
По сути похоже на ООП-метод, но явно проще.
(no subject)
12/3/08 13:36 (UTC)(no subject)
12/3/08 13:46 (UTC)Вот только:
1. reflection под рукой не было.
2. кодогенерация в данном случае была _очень_ простой и порождала столь же простой (и достаточно оптимальный - нет нужды раскручивать reflection на каждое сериализуемое поле) код.
Ну и главный вопрос: будет ли при этом описание формата файла не сложнее такого:
--- cut ---
integer TrackBarBrightness.Position
integer TrackBarContrast.Position
integer TrackBarGamma.Position
integer TrackBarScaleX.Position
integer TrackBarScaleY.Position
integer TrackBarVolume.Position
integer TrackBarGain.Position
BeginFlags
Bit SpeedButtonSpectrum.Down
Bit SpeedButtonCurve.Down
Bit SpeedButtonEdge.Down
Bit SpeedButtonFilter.Down
Bit SpeedButtonMirror.Down
Bit SpeedButtonUpsideDown.Down
Bit SpeedButtonMicro.Down
EndFlags
integer Selection1
integer Selection2
integer SpectrumPos
--- cut ---
(что немаловажно, часть integer'ов - поля, часть - свойства, причем не всегда свойства непосредственно сериализуемого объекта)
(no subject)
12/3/08 14:51 (UTC)Описание могло бы быть в XML или текстом вроде:
---
Version 1.1
Class Form1
field TrackBarBrightness.Position=BrightnessValue
...
---
Да, сам код будет посложнее, но он будет единым и не будет усложнять процедуру сборки продукта.
(no subject)
12/3/08 15:02 (UTC)Да, что я не понял из описания гибернейта: оно генерит оптимальный код или просто работает с объектами через reflection? Так-то, кажется, имеем ровно ту же кодогенерацию, но в рантайме...
(no subject)
12/3/08 15:07 (UTC)Гибернейт, да, работает через reflection. Но он оптимизирован, так что генерит всё, что надо, и даже больше.
(no subject)
13/3/08 07:45 (UTC)Да, а "оптимизирован" - в смысле, когда мы грузим мапу, она один раз получает ссылки на требуемые поля/методы свойств через reflection, а дальше уже работает напрямую?
На самом деле, грань между кодогенерацией и другими подходами достаточно зыбкая. Можно ведь и генерацию объекта по XML-описанию считать кодогенерацией =).
P.S. А уж что считать кодогенерацией в функциональных языках - просто непонятно =)
(no subject)
12/3/08 20:09 (UTC)Т.е. кодегенерация - это полезная разновидность копи-пейста.
(no subject)
12/3/08 20:11 (UTC)(no subject)
13/3/08 11:08 (UTC)Т.е. получается что дешевле держать зоопарк неуниверсальных технологий и склеивать их до кучи при помощи контролируемой делокализации, и платить специалистам в этих технологиях умеренную зарплату, чем держать одну суперуниверсальную технологию и платить специалистам в этой технологии завышенные зарплаты (из за завышенных требований по знаниям).
Особенно это актуально для проэктов с заниженными требованиями к атрибутам качества (т.е. к сайтикам и "базкам данных").
Резюме: Неуниверсальные технологии + контролируемая делокализация позволяют удешевить разработку за счёт ухутшения атрибутов качества по сравнению с применением суперуниверсальной технологии.
(no subject)
13/3/08 05:54 (UTC)Самый распростринённый вариант кодогенерации, ИМХО, макросы Коммон Лиспа (в Схеме есть свои макросы). Там они используются не только для копи-паста, хотя и для него тоже, может даже чаще для него (по сути). На эту тему есть статья "The Art of Metaprogramming". Довольно интересная.
Это не считая использования кодогенерации для всяческой оптимизации.
Кстати, где ссылку ставить?
(no subject)
13/3/08 05:55 (UTC)(no subject)
13/3/08 10:10 (UTC)С лиспом я практически не знаком, увы мне. То есть, дальше первой половины букваря я не ушел и макросов не видел. А <до user="aleksijb"/>, которого я глубоко уважаю, говорит, что макросы - это главная фича Лиспа.
Статью почитаю, спасибо.
Оптимизация - это да, но это отдельный разговор и там тоже можно потыкать пальцем в "дыру".
А ссылку где угодно, в своём ЖЖ, например. Желательно SEO-шную, с контекстом внутри, типа <a href="http://victorsergienko.com">тут про .NET, WPF, и программирование вообще</a>
(no subject)
14/3/08 04:02 (UTC)В Лиспе главная фича - то, что списком является ВСЁ, и это всё можно модифицировать в рантайме. Правда, не знаю, использует ли эту возможность эоть кто-то в рабочем коде :). Ну, макросы примерно тем же и занимаются...
Вообще, если поискать по википедии, можно найти немало любопытного про кодогенерацию. Например то, что макросы и прочие code snippets во всяких IDE - это тоже кодогенерация. Я эту ммысль вчера недодумал. Хотя, ты наверняка скажешь, что это тот самый копи-паст. На это могу ответить: "включи воображение!" ;).
Ссылку в ЖЖ повесил - заходи посмотри. :)
(no subject)
14/3/08 10:00 (UTC)Я сейчас, правда, никого не читаю - некогда.
Да, и это - кодогенерация, и я ими не пользуюсь. Воображение пока в отключке, скажи явно, для танкистов, пожалуйста %)
"Дыра" - это отсутствие возможности. Так в С++ нет RTTI :]
(no subject)
18/3/08 03:31 (UTC)Несколько хороших практичных примеров кодогенерации есть в "Практике программирования" Кернигана и Томпсона.
Что-то я не представляю, каким образом кодогенерацией можно заменить RTTI. Шаблоны, что ли? Я всегда считал, что их смысл несколько в другом, а вообще-то это тоже хороший пример кодогенерации. Если в Java generics сделаны принципиально по-другому, то это зря :).
(no subject)
14/3/08 21:15 (UTC)Хороший пример применения кодогенерации там, где она действительно полезна.
Vala - высокоуровневый язык, в основе объектной системы которого лежит Гномовский GObject,
и который транслируется затем в обычный портабельный Си (с правильным юзанием GObjectов,
что делать вручную достаточно трудоёмко).
(no subject)
24/3/08 20:45 (UTC)Например является ли рефакторинг кодогенерацией? А если мы добавляем свой рефакторинг?
Или компилятор. Ведь он тоже занимается кодогенерацией. Мы могли бы отказаться от транслирования(кодогенерации) и строить абстракции снизу постепенно слой за слоем, получился бы интерпретатор.
Мне этот вопрос видится в контексте компилятор vs интерпретатор.