Подтвердить что ты не робот

Почему я должен использовать генераторы кода

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

Можете ли вы объяснить, почему я должен использовать их в своих проектах и ​​как они могут облегчить мою жизнь.

Примеры будут большими, и где я могу узнать эту тему еще немного.

4b9b3361

Ответ 1

По крайней мере, вы поставили вопрос с правильной точки зрения =)

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

Классическим примером этого является доступ к данным; вы могли бы генерировать 250 классов (1 для каждой таблицы в схеме), эффективно создавая решение для табличного шлюза, или вы могли бы построить нечто большее как модель домена и использовать NHibernate/ActiveRecord/LightSpeed ​​/[выбрать свой orm] для сопоставления модели с богатым доменом в базу данных.

Хотя и ручное решение, и ORM - эффективные генераторы кода, основное различие заключается в генерации кода. С ORM это неявный шаг, который происходит во время выполнения и поэтому является односторонним по своей природе. Для ручного решения требуется и явный шаг для генерации кода во время разработки и вероятность того, что сгенерированные классы будут нуждаться в настройке в какой-то момент, что создает проблемы при повторном генерации кода. Явный шаг, который должен произойти во время разработки, вводит трение в процесс разработки и часто приводит к коду, который нарушает DRY (хотя некоторые утверждают, что сгенерированный код никогда не может нарушать DRY).

Другая причина, по которой рекламируется генерация кода, поступает из мира MDA/MDE (Model Driven Architecture/Engineering). Я не вкладываю в это много акций, но вместо того, чтобы предлагать несколько слабо выраженных аргументов, я просто собираюсь кооптировать кого-то elses - http://www.infoq.com/articles/8-reasons-why-MDE-fails.

Генерация кода IMHO - единственное решение в чрезвычайно узком наборе проблем и всякий раз, когда вы его рассматриваете, вам, вероятно, следует взглянуть на реальную проблему, которую вы пытаетесь решить, и посмотреть, есть ли лучшее решение.

Один тип генерации кода, который действительно повышает производительность, - это "генерация микрокодов", где использование макросов и шаблонов позволяет разработчику генерировать новый код непосредственно в среде IDE и вносить вкладку/вводить свой путь через заполнители (например, пространство имен/имя класса и т.д.). Такое генерирование кода является особенностью resharper, и я использую его сильно каждый день. Причина, по которой преимущества микро-генерации вызывают неудачу в генерации большинства больших масштабов, заключается в том, что сгенерированный код не привязан к какому-либо другому ресурсу, который должен храниться в синхронизации, и поэтому, как только код будет сгенерирован, он точно так же, как и весь другой код в решение.

@John
Перемещение создания "базовых классов" из IDE в xml/dsl часто наблюдается при разработке большого взрыва - классический пример - разработчики попытаются перестроить базу данных в модель домена. Если генератор кода не очень хорошо написан, он просто вводит дополнительную нагрузку на разработчика, поскольку каждый раз, когда им необходимо обновить модель домена, им либо приходится переключать контекст и обновлять xml/dsl, либо им необходимо расширить модель домена и затем переносите эти изменения обратно в xml/dsl (эффективно выполняя работу дважды).

Есть некоторые генераторы кода, которые работают очень хорошо в этом пространстве (дизайнер LightSpeed ​​- единственный, который я могу думать о atm), действуя как двигатель для поверхности дизайна, но часто эти генераторы кода генерируют ужасный код, который не может быть сохранен (например, поверхности дизайна winforms/webforms, поверхность проектирования EF1) и, следовательно, быстро отменяет любые преимущества производительности, полученные от использования генератора кода в первую очередь.

Ответ 2

Ну, это либо:

  • вы пишете 250 классов, все почти одинаковые, но немного разные, например. для доступа к данным; занимает неделю, и она скучна и подвержена ошибкам и раздражает.

ИЛИ

  • вы вкладываете 30 минут в создание шаблона кода и позволяете движку генерации обрабатывать работу в течение 30 минут.

Итак, генератор кода дает вам:

  • скорость
  • воспроизводимость
  • намного меньше ошибок
  • намного больше свободного времени!: -)

Отличные примеры:

  • Linq-to-SQL T4 templates от Damien Guard, чтобы генерировать один отдельный файл для каждого класса в вашей модели базы данных, используя лучшие хранит Visual Studio 2008 секрет - T4 шаблоны

  • PLINQO - то же самое, но для генератора Codesmith

и еще бесчисленное количество...

Ответ 3

В любое время, когда вам нужно произвести большое количество повторяющихся шаблонов, генератор кода является парнем для работы. В прошлый раз я использовал генератор кода при создании пользовательского уровня доступа к данным для проекта, где скелет для различных действий CRUD был создан на основе объектной модели. Вместо ручного кодирования всех этих классов я собрал генератор кода с шаблоном (используя StringTemplate), чтобы сделать это для меня. Преимуществом этой процедуры было:

  • Это было быстрее (было создано большое количество кода)
  • Я мог бы восстановить код в капризе, если я обнаружил ошибку (иногда код может иметь ошибки в ранних версиях)
  • Меньше ошибок; когда у нас была ошибка в сгенерированном коде, она была везде, что означает, что ее можно было бы найти (и, как отмечалось в предыдущем пункте, было легко исправить ее и восстановить код).

Ответ 4

Использование GUI-сборщиков, которые будут генерировать код для вас, является обычной практикой. Благодаря этому вам не нужно вручную создавать все виджеты. Вы просто перетаскиваете их и используете сгенерированный код. Для простых виджетов это экономит время (я использовал это для wxWidgets).

Ответ 5

Действительно, когда вы используете почти любой язык программирования, вы используете "генератор кода" (за исключением сборки или машинного кода.) Я часто пишу мало 200-строчных скриптов, которые выкатывают несколько тысяч строк C. Там также программное обеспечение, которое вы можете получить, которое помогает генерировать определенные типы кода (например, yacc и lex используются для генерации парсеров для создания языков программирования.)

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

Например, вот очень длинный и утомительный файл, который я (не сделал) написал как часть моей работы, модифицирующей Quake2-основанный игровой движок CRX. Он принимает целочисленные значения всех #defined констант из двух заголовков и превращает их в "cvars" (переменные для игровой консоли.)
http://meliaserlow.dyndns.tv:8000/alienarena/lua_source/game/cvar_constants.c

Вот короткий Bash script, который сгенерировал этот код во время компиляции:
http://meliaserlow.dyndns.tv:8000/alienarena/lua_source/autogen/constant_cvars.sh

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

Ответ 6

Канонический пример этого - доступ к данным, но у меня есть другой пример. Я работал над системой обмена сообщениями, которая обменивается данными по последовательному порту, сокетам и т.д., И я обнаружил, что мне пришлось писать такие классы снова и снова:

public class FooMessage
{
    public FooMessage()
    {
    }

    public FooMessage(int bar, string baz, DateTime blah)
    {
        this.Bar = bar;
        this.Baz = baz;
        this.Blah = blah;
    }

    public void Read(BinaryReader reader)
    {
        this.Bar = reader.ReadInt32();
        this.Baz = Encoding.ASCII.GetString(reader.ReadBytes(30));
        this.Blah = new DateTime(reader.ReadInt16(), reader.ReadByte(),
            reader.ReadByte());
    }

    public void Write(BinaryWriter writer)
    {
        writer.Write(this.Bar);
        writer.Write(Encoding.ASCII.GetBytes(
            this.Baz.PadRight(30).Substring(0, 30)));
        writer.Write((Int16)this.Blah.Year);
        writer.Write((byte)this.Blah.Month);
        writer.Write((byte)this.Blah.Day);
    }

    public int Bar { get; set; }
    public string Baz { get; set; }
    public DateTime Blah { get; set; }
}

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

Я не буду публиковать код-код, это много загадочных вещей CodeDom, но в итоге я смог объединить всю систему вплоть до одного файла XML:

<Messages>
    <Message ID="12345" Name="Foo">
        <ByteField Name="Bar"/>
        <TextField Name="Baz" Length="30"/>
        <DateTimeField Name="Blah" Precision="Day"/>
    </Message>
    (More messages)
</Messages>

Насколько это проще? (Риторический вопрос.) Я наконец смог дышать. Я даже добавил несколько колоколов и свистов, чтобы он смог создать "прокси", и я мог бы написать такой код:

var p = new MyMessagingProtocol(...);
SetFooResult result = p.SetFoo(3, "Hello", DateTime.Today);

В конце концов я бы сказал, что это спасло меня, написав хорошие 7500 строк кода и превратив 3-недельную задачу в 3-дневную задачу (ну плюс пара дней, необходимых для написания кода-gen).

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

Ответ 7

Генератор кода полезен, если:

  • Стоимость написания и обслуживания генератора кода меньше стоимости написания и сохранения повторения, которое оно заменяет.

  • Консистенция, полученная с помощью генератора кода, приведет к уменьшению ошибок до степени, которая делает ее полезной.

  • Дополнительная проблема отладки сгенерированного кода не сделает отладки недостаточно эффективной, чтобы перевесить преимущества от 1 до 2.

Ответ 8

Как пример хорошего использования генератора кода?

Здесь используются t4-шаблоны (генератор кода, встроенный в визуальную студию) для создания сжатых css из .less файлов: http://haacked.com/archive/2009/12/02/t4-template-for-less-css.aspx

В принципе, он позволяет вам определять переменные, реальное наследование и даже поведение в ваших таблицах стилей, а затем создавать нормальные css из них во время компиляции.

Ответ 9

Для доменных или многоуровневых приложений генерация кода - отличный способ создать начальную модель или уровень доступа к данным. Он может объединить 250 классов сущностей через 30 секунд (или в моем случае 750 классов за 5 минут). Это оставляет программиста сосредоточиться на улучшении модели с отношениями, бизнес-правилами или получением представлений в MVC.

Ключевая вещь здесь, когда я говорю о начальной модели. Если вы полагаетесь на генерацию кода для поддержки кода, то настоящая работа выполняется в шаблонах. (Как указано Max E.). Остерегайтесь этого, потому что существует риск и сложность в поддержании кода на основе шаблонов.

Если вы просто хотите, чтобы слой данных был "автоматически создан", поэтому вы можете "сделать работу с графическим интерфейсом за 2 дня", тогда я предлагаю пойти с продуктом/набором инструментов, который ориентирован на данные или два сценарий приложения.

Наконец, имейте в виду "мусор в = мусор". Если весь слой данных является однородным и не абстрагируется от базы данных, пожалуйста, спросите себя, почему вы вообще пытаетесь получить слой данных. (Если вам не нужно выглядеть продуктивно:))

Ответ 10

Все говорят здесь о простом генерации кода, но как насчет генерации кода с помощью модели (например, MDSD или DSM)? Это поможет вам выйти за рамки простых генераторов ORM/элементов/генераторов шаблонов и в генерации кода концепций более высокого уровня для вашей проблемной области.

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

Как и 3GL и ООП, увеличение абстракции создавало большое количество ассемблерного кода на основе спецификации более высокого уровня, разработка, основанная на модели, позволяет нам снова увеличить уровень абстракции с еще одним усилением производительности.

MetaEdit + из MetaCase (зрелый) и ABSE от Isomeris (мой проект, в alpha, info at http://www.abse.info) - это две технологии на авангард генерации кода, управляемой моделью.

На самом деле нужно изменить менталитет (например, ООП, необходимый в 90-е годы)...

Ответ 11

Я фактически добавляю последние штрихи к генератору кода, который я использую для проекта, на который я был нанят. У нас есть огромные XML файлы определений, и за несколько дней работы я смог создать более 500 классов С#. Если я хочу добавить функциональность ко всем классам, скажу, что я хочу добавить атрибут ко всем свойствам. Я просто добавляю его в свой код-gen, нажимаю go и bam! Я закончил.

Это действительно хорошо, действительно.

Ответ 12

Существует много применений для генерации кода.

Написание кода на знакомом языке и генерация кода для другого целевого языка.

  • GWT - Java -> Javascript
  • MonoTouch - C# -> Objective-C

Написание кода на более высоком уровне абстракции.

  • Составители
  • Доменные языки

Автоматизация повторяющихся задач.

  • Уровни доступа к данным
  • Начальные модели данных

Игнорируя все предвзятые понятия генерации кода, он в основном преобразует одно представление (обычно более высокий уровень) в другое (обычно более низкое). Помня это определение, это очень мощный инструмент.

Текущее состояние языков программирования никоим образом не достигло своего полного потенциала, и этого никогда не будет. Мы всегда будем абстрагироваться, чтобы выйти на более высокий уровень, чем сегодня. Генерация кода - это то, что нас достает. Мы можем либо зависеть от создателей языка, чтобы создать эту абстракцию для нас, либо сделать это сами. Языки сегодня достаточно сложны, чтобы позволить кому-либо сделать это легко.

Ответ 13

Если с генератором кода вы также собираетесь использовать фрагменты, попробуйте разницу между вводом ctor + TAB и записью конструктора каждый раз в ваших классах. Или проверьте, сколько времени вы зарабатываете с помощью фрагмента, чтобы создать оператор switch, относящийся к перечислению со многими значениями.

Ответ 14

Если вам платят LOC и работают для людей, которые не понимают, что такое генерация кода, это имеет большой смысл. Между прочим, это не шутка - я работал с несколькими программистами, которые используют эту технику именно для этой цели. В любом случае, никто не получает LOC формально (что я знаю, во всяком случае), но программисты, как правило, ожидают, что они будут продуктивными, а сбивание больших объемов кода может заставить кого-то выглядеть продуктивно.

В качестве единственной слегка касательной точки, я думаю, это также объясняет стремление некоторых кодеров разбить единую логическую единицу кода на как можно большее количество различных классов (когда-либо наследуйте проект с LastName, FirstName и MiddleInitial классы?).

Ответ 15

Вот некоторые ереси:

Если задача настолько глупа, что ее можно автоматизировать во время записи программы (т.е. исходный код может быть сгенерирован с помощью script from, let say XML), то то же самое можно сделать и во время выполнения (т.е. некоторые представление этого XML может быть интерпретировано во время выполнения) или с использованием некоторого метапрограммирования. Таким образом, по сути, программист ленился, не пытался решить настоящую проблему, но сделал легкий выход и написал генератор кода. В Java/С# посмотрите на отражение, а в С++ посмотрите на шаблоны