Используете ли вы инструменты генерации кода?
Используете ли вы инструменты генерации кода (кроме тех, которые используются для генерации прокси и от дизайнеров, встроенных в визуальную студию)?
Какие части вашего приложения вы генерируете?
Вы обычно катаете свой собственный генератор? Если да, то какой тип генератора вы пишете (шаблоны asp, coddom и т. Д.). Если нет, какие сторонние инструменты вы используете?
В настоящее время я работаю над несколькими различными проектами, каждый из которых использует собственный генератор кода, который обрабатывает все, от создания структуры базы данных, бизнес-объектов, DAL и BLL. Мне любопытно, что опыт других людей связан с такими инструментами.
21 ответ
Я нахожусь в философском лагере, который считает генераторы кода "неправильными", потому что они указывают на то, что должно стать частью языка.
Но это была большая часть этики Pragmatic Programmer - писать код, который пишет код, и на практике генерация кода работает хорошо, если сгенерированный код скрыт по умолчанию. Независимо от того, насколько философски чистым вы хотите быть, язык никогда не будет развиваться так быстро, как проблемы, которые вы хотите решить.
На ум приходит код, который генерируется при создании формы Windows в Visual Studio. Вы можете посмотреть на сгенерированный код, если хотите, но лучше не делать этого. Однако переход на декларативный язык с использованием WPF был более значительным, поскольку он более чист и более надежен в манипулировании декларативным кодом программно, чем императивный код.
Они должны были сделать то же самое с классами LINQ-To-SQL. Им нужен декларативный язык для классов, которые просто имеют свойства и не имеют собственного поведения. Вероятно, было бы проще сделать эти классы сущностей динамическими - автоматически изменяющимися при изменении базовой схемы базы данных.
Мы попытались использовать CodeSmith для генерации классов.NetTiers для всех таблиц в нашей базе данных, но столкнулись с двумя проблемами:
.NetTiers был раздут, и сгенерированный код был огромен. Я думаю, что инструменты генерации кода делают слишком легким создание существа.
Поскольку схема активно развивалась и изменялась, нам также пришлось много регенерировать, и в результате очень трудно было сохранить все под контролем исходного кода, потому что все файлы были регенерированы и заменены. Я оказался неуверенным, должен ли сгенерированный код вообще находиться в системе контроля версий.
Лучшее место для генерации кода должно быть на этапе компиляции или сборки, а не на этапе проектирования. Когда вы используете анонимный тип или метод в C#, компилятор выполняет генерацию кода на лету. Если вы генерируете код на этапе проектирования, вы получаете кусок материала, который должен обновляться каждый раз при изменении базовых параметров.
Дело не в том, что мы работаем в домене.net / web, но инструменты самодельной генерации кода на разных языках, разработанных для дома, являются важной частью нашей цепочки инструментов разработки. У нас есть два основных таких инструмента (с грамматиками, синтаксическими анализаторами и формальными определениями) и множество второстепенных, основанных на макросах, таких как m4 и perl. Все они в конце генерируют простой C, который изначально компилируется.
Специфичные для домена языки являются одним из ключевых инструментов повышения производительности труда программистов для любого крупномасштабного программного обеспечения в моем опыте. Если вы создаете такие вещи, как компиляторы, симуляторы или другое очень сложное программное обеспечение с множеством повторяющихся шаблонов, которые вообще не поддерживают базовые языки (что обычно означает переносимый C, а иногда и C++), инструменты генерирования кода - это то, что вам нужно. Я рассматриваю предметно-ориентированные языки как следующий шаг в обобщении: сначала вы разбиваете общие вычисления на функции (или подпрограммы, чтобы быть историческими), затем вы разбиваете общие функции на шаблоны или обобщения, если такая возможность доступна, и затем вы разбиваете еще больше общности и повторения кода в полноценный пользовательский язык.
Это все о сокращении объема кода, который вы на самом деле пишете, и об удалении любых утомительных повторений и кода без добавленной стоимости из процесса программирования. Как только шаблоны повторятся, примените язык, специфичный для домена!
Я начал откатывать свои собственные генераторы (доступ к данным, sprocs и т. Д.), Когда я выполнял классическую работу с осами (около 2001 года). Я медленно перешел на CodeSmith, так как с ним было намного легче иметь дело. Я все еще в основном просто генерировал все вещи типа слоя доступа к данным (включая sprocs) для моего кода.NET.
Пару лет назад я сделал переход от генерации макро кода (т.е. CodeSmith) к генерации микро кода.
Разница в том, что с CodeSmith я генерировал огромные полосы кода для своего приложения, все общие и все сразу. Это стало проблематичным для крайних случаев и регенерируется при изменении источника шаблона (т.е. структуры таблицы). Я также сталкивался со случаями, когда имелся большой запас несущего кода, который я не использовал, но был сгенерирован из моего шаблона. Все эти методы работали? Может быть, а может и нет. Внедрение и очистка сгенерированного кода было бы огромным трудом (т.е. после более чем одного года на одной и той же базе кода).
Micro Code Generation, напротив, позволяет мне генерировать именно те классы, которые мне нужны, в совершенно правильном сценарии, который я хочу. Основным инструментом, который я использую для этого, является ReSharper. Я делаю это путем написания своих модульных тестов перед написанием моего производственного кода. В этом сценарии ReSharper использует мой модульный тест в качестве шаблона для автоматической генерации скелета для производственного кода. Тогда это просто вопрос заполнения пробелов.
Для доступа к данным я больше ничего не генерирую. Я обнаружил, что хороший O/R M заменяет все, что я использовал для добавления в слой доступа к данным (например, NHibernate). Учитывая это, я никогда не буду писать или создавать другой уровень доступа к данным в моей жизни (я отказываюсь).
Плюс ко всему, я получаю преимущества от большого набора модульных тестов, среди прочего
Поскольку в собственном языке Fog Creek Software, Васаби, есть встроенные генераторы кода времени компиляции, мы используем их для автоматического создания основных элементов наших классов сущностей, которые отображаются в таблицы базы данных. Таким образом, вместо написания класса с дюжиной различных свойств и методов, мы можем просто написать:
<ActiveRecord("Kiwi")> _
Class CKiwi
End Class
и CKiwi будет иметь Load(ix As Int32), Commit() и поля / свойства для каждого столбца, определенного в его базовой схеме для таблицы Kiwi. Это избавляет нас от необходимости иметь огромные библиотеки O/R M, но позволяет быстро добавлять таблицы в наши продукты.
Генерация кода в духе компиляторов может быть великолепной. Генерация кода в духе "волшебников" в итоге оказалась плохой идеей.
- Мы используем генераторы кода для исключений
- Генерация DAO для CRUD-операций
- использовать JAXB для генерации кода
- Используйте XDoclet для создания локальных / домашних интерфейсов EJB
- Используйте шаблоны Velocity для создания документации для бизнес-моделей.
- Используйте Apache Axis для создания заглушек WSDL
Я создаю свои собственные инструменты для некоторых задач. Это весело делать и даже экономит время в долгосрочной перспективе. Для очень скучных задач это даже спасает ваше здравомыслие.
Самодельные генераторы кода отлично подходят для создания юнит-тестов из электронных таблиц конечных пользователей, которые содержат примеры того, как это должно работать.
См. Инструментарий для создания тестовых случаев для одного примера.
Мы использовали CodeSmith для создания наших hiberms NHibernate, наших сущностей и некоторых других вещей. Через некоторое время мы устали от этого потока, поэтому мы бросили его.
Генератор T4 бесплатен и заслуживает внимания.
Мы по-прежнему используем Castle CodeGenerator для генерации ссылок MonoRail.
Мы используем LLBLGen для создания нашего уровня доступа к данным. Вы указываете генератору на базу данных, которую вы используете, выбираете, какие таблицы вы хотите использовать, и он производит необходимые классы. Это все очень быстро и просто.
Я познакомился с ActiveWriter пару месяцев назад, и он мне очень помог, мне нравится гибкость этого подхода, он генерирует частичные классы, которые решают проблемы доступа к данным, и позволяет мне кодировать бизнес-часть классов. Я чувствую себя очень довольным, потому что экономит мне много работы, очень приятно менять схему, заново генерировать и продолжать.
У предыдущего работодателя у нас было домашнее приложение VB.NET, которое превращало файл определения схемы XML (XSD) в статическую библиотеку C++. Это значительно облегчило работу с типами данных C++ (bool, std::string и т. Д.), И весь интересный код XML был спрятан внутри этих сгенерированных классов.
У нас есть встроенный генератор кода, который заботится о доступе к базе данных. Каждый пишет хранимые процедуры и получает соответствующие методы, абстрагированные в классе шлюза.
Мы также генерируем веб-сервисы, чтобы правильно взаимодействовать с Flash - то есть обрабатывать исключения в разумной манере.
Наконец, у нас есть генератор исключений, который устраняет тяжелую работу, связанную с лучшими практиками исключений (тоннами конструкторов и т. Д.)
Я написал и использую инструмент генерации кода на основе Xslt. http://perfectstorm.codeplex.com/
При этом используется модель с одним корневым XML для генерации dal, procs, таблиц.
Мы только начали использовать Grails здесь, в офисе. Ранее у нас был набор собственных скриптов генерации JSF/Hibernate CRUD.
... Граальс побеждает. Генерация кода из Grails очень удобна и может запустить приложение CRUD примерно за 15 минут, фактически не помещая код в файлы кода!
Конечно, он МОЖЕТ генерировать реальный код в файлы кода, когда вы хотите изменить его. Большую часть времени, для обычного CRUD, вы можете просто изменить представления.
Я использовал один для создания сериализуемых объектов данных, которые могут быть преобразованы на разных платформах (Windows, Linux, Solaris, Mac, BSD и т. Д.). Это было внутреннее решение.
Если вы заинтересованы в LLBLGEN, что отлично, вы также можете оценить дозвуковой. Может быть, даже посмотрите, что Роб Конери говорит о каком-либо совпадении или взаимодействии между дозвуковым и t4.
Я создал собственную структуру генерации кода, которая генерирует прокси-классы для веб-сервисов на нескольких языках, таких как Java Script, Action Script, Java, C# и Objective C, я не использую шаблоны или инструменты, просто простой код C#, который генерирует код с некоторыми вспомогательными классами Генерация кода может действительно сэкономить много времени, но я думаю, что сгенерированный код должен быть максимально простым и не должен использоваться слишком много.
Я написал прекрасный инструмент, в котором эксперты в формате данных, для которого я написал парсер, могли бы отправлять свои собственные образцы через веб-форму, просматривать результаты и сообщать мне, правильно ли это.
Исходя из этого, будет сгенерирован тест jUnit. Прекрасный.
За исключением того, что никто не удосужился использовать его, и я не собрал никаких тестовых случаев вообще.
Как и некоторые другие, мы создали собственный генератор кода (Inon Datamanager/Viewmanager) для доступа к данным, обработки HTML-форм и определенных операций бизнес-логики. Ключ к тому, чтобы эта работа работала хорошо, - это спроектировать ее так, чтобы вам никогда не приходилось трогать или смотреть на сгенерированный код.
Таким образом, он почти становится частью языка - язык (в нашем случае Java) расширяется, чтобы включать в себя спецификацию модели предметной области и модель представления, а затем вы просто заполняете пользовательскую бизнес-логику реальным кодом Java.
Это дает нам правильные инструменты для общения с аналитиками и бизнес-пользователями, в то же время обладая способностью Java настраивать детали базового поведения.