Кодогенерация UML->Python (Django)

    Четыре года назад, устроившись на новое место работы, увидел учетную систему приличных размеров на python + wxWidgets + MSSql. Весь исходный код генерировался автоматически на основе UML диаграмм. Спустя несколько лет, я настолько проникся таким способом разработки, что и в собственных проектах на Django стал использовать автогенерацию кода.
    Давайте в общих чертах рассмотрим, как выглядит процесс создания «кодогенерируемого» проекта?


    Для начала нам нужно найти UML редактор с большими возможностями. Я использую Sybase Power Designer. В нем можно практически все.
    Сразу после установке PowerDesigner может генерировать C++, Java, C#, Visual Basic проекты. Написать свой кодогенератор совсем не сложно, так что немного повозившись пишем и используем свой.

    Все готово для рисования первого класса:


    Давайте назовем его Foo и добавим ему метод __call__:


    Пусть наш метод будет печатать значение одного переданного ему параметра:


    Теперь посмотрим, что мы будем иметь на выходе кодогенератора для созданного класса:


    Кодогенератор исходный код каждого класса размещает в отдельный модуль. Модуля располагаются согласно иерархи пакетов.
    Пока ничего впечатляющего мы не сделали и кодогенератор не оправдал своего существования.
    Давайте расширим наш пример еще двумя классами CheckHelper, PrintHelper. И покажем, что Foo имеет с ними связи типа composition:


    Посмотрим на генерируемый код:

    # -*- coding: cp1251 -*-

    #***********************************************************************
    #* Module: foo.py
    #* Path: foo
    #* Author: danil
    #* Modified: 11 ноября 2009 г. 10:50:37
    #***********************************************************************
    import checkHelper
    import printHelper

    class Foo(object):
      
      
      class __C_CheckHelper(object):
        def __get__(self, obj, cls):
         if obj is None:
           return checkHelper.CheckHelper
         value = getattr(obj, '#checkHelper', None)
         if value is None:
           value = checkHelper.CheckHelper()
           setattr(obj, '#checkHelper', value)
         return value
        def __set__(self, obj, value):
         raise AttributeError
        def __delete__(self, obj):
         setattr(obj, '#checkHelper', None)
      checkHelper = __C_CheckHelper() #B #B
      
      
      class __C_PrintHelper(object):
        def __get__(self, obj, cls):
         if obj is None:
           return printHelper.PrintHelper
         value = getattr(obj, '#printHelper', None)
         if value is None:
           value = printHelper.PrintHelper()
           setattr(obj, '#printHelper', value)
         return value
        def __set__(self, obj, value):
         raise AttributeError
        def __delete__(self, obj):
         setattr(obj, '#printHelper', None)
      printHelper = __C_PrintHelper() #B #B
      
      def __call__(self, val):
        if self.checkHelper(val):
          self.printHelper(val)


    * This source code was highlighted with Source Code Highlighter.


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

    Давайте подытожим, что нам дает такой подход к разработке проектов:
    1. Скорость разработки за счет автоматической генерации типовых кусков кода.
    2. Простота чтения проектов, навигация по UML диаграммам значительно проще, нежели чтение исходных текстов в файлах.
    3. Легкость модернизации за счет быстрого отслеживания всех связей между объектами.

    Это лишь обзорная статья, если хабросообществу интересно, напишу step by step пособия по генерации django проектов.
    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 45
    • 0
      Очень интересно, пишите!
      • +14
        Вряд ли быстрее будет разработка, скорее наоборот.
        Но пишите, интересно.
        • +3
          Мне думается, что тут акцента надо не на быстроту ставить, а на то, что проект имеет явную структуру, а потому легче привлекать новых членов в команду разработчиков, передавать проект, выкладывать как open source.
          • 0
            если для проекта делается аналитика в виде UML-диаграмм, то для большого проекта генерация исходного кода по ним может быть неплохим стартом для работы кодера.

            возможные бонусы:
            — сокращается время на то, чтоб проект начал собираться (имеется ввиду первая сборка проекта);
            — наличие визуального представления структуры будущего проекта и документация интерфейсов (главное при отклонении реализации от модели, своевременно ее обновлять), важно когда вы пишите код и используете чужой модуль которого еще нет :-)
          • +1
            Только классы исходя из диаграмм классов можно генерить?
            • +2
              Можно все. Кодогенератор очень красиво настраивается под свои нужны.
              • 0
                А подсветка синтаксиса и прочие плюшки есть?
          • +2
            Да, было бы интересно почитать ещё
            • +10
              Вы бы в самом начале указали ценник на PowerDesigner, у многих желание кодогенерацией заниматься надолго пропадёт. Кстати я смотрю на скриншотах у вас 12 версия :).
              • +4
                Да, действительно, Power Designer стоит немало (от 230 000 руб). Я недавно перешел с 11 на 15 версию.
              • +8
                Не проняло.

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

                А тут мы имеем какую-то сгенерированную жуть.

                Наверное, это все какие-то стандартные и ожидаемые доводы против таких штук) В любом случае, для себя лично практической пользы не увидел.
                • +2
                  На мой взгляд UML диаграммы «читаются» проще чем любой код.
                  • +2
                    Ну а про фломастеры и вкус я думаю все знают.
                    • +4
                      Вы, наверное, руководитель, а не рядовой разработчик? Да, UML-диаграммы делают Python более «ынтерпрайзным». Но при этом код, который получается после генерации, становится похожим на написанный на Java, на которой без IDEA (по отзывам несчастных) очень муторно писать.

                      У Вас кодогенерация демонстрируется на каком-то оторванном от жизни абстрактном примере. Какой-то Foo, CheckHelper, PrintHelper — что обозначают все эти названия? Давайте в следующей статье про Django какой-то более жизненный пример. Например, систему регистрации-авторизации пользователей. Стандартный компонент registration мне показался не лишенным недостатков, когда работал c Django.
                      • +1
                        Я руковожу отделом, в котором 3 программиста, так что отношу себя к разработчикам. Исходный код, после генерации, является промежуточным звеном между UML и python. Нет необходимости его читать и тем более править.
                      • 0
                        Ну так читайте UML-диаграммы, раз хотите. Вопрос генерации кода из них — это совсем другой вопрос, который ведет к другому способу разработки, имеющему (на мой взгляд) значительные недостатки.

                        Кстати, не совсем по делу, но картинки, чтоб посмотреть структуру моделей, можно сгенерить из этих самых моделей:

                        code.google.com/p/django-command-extensions/wiki/GraphModels
                        code.djangoproject.com/wiki/DjangoGraphviz
                        • 0
                          UML — очень полезная штука, но генерировать повторяющийся код — серьезная ошибка. UML следует рисовать отдельно (лучше всего на бумажке:) или получать путем анализа существующего кода. Хорошо, если вручную: лучше разберетесь в коде и заодно поймете, что в нем надо изменить. Если же вручную разбираться в коде мучительно — значит, код ужасен и, вероятно, сгенерирован кем-то из UML.
                      • +1
                        У меня вопрос к автору как человеку осведомленному в области UML.
                        Есть какие то достойные бесплатные аналоги Sybase Power Designer?
                        • +3
                          Я пользовался только PowerDesigner'ом, BPWin'ом и MS Visio все они платные. Достойные обзоры уже были на хабре тут и тут
                          • +1
                            бесплатных достойных нет :) из платных, но очень достойных могу посоветовать Enterprise Architect, к тому же он вполне подъемный: Desktop — ~4500р, Pro — ~6700р, Corp — ~8100р.
                            • 0
                              использовал в работе Enterprise Architect, года 2 назад он показался проще и удобней. тоже рекомендую. в нем есть возможность выбора процесса разработки и набор доступных диаграмм и инструментов адаптируется под него.
                          • 0
                            Вопрос ко всем поклонникам UML. Есть ли что-то приятное и бесплатное/имеющее кряк для Linux? BoUML и Umbrello, как мне кажется, имеют маловато возможностей по кодогенерации. В плагинах к NetBeans/Eclipse, она тоже отсутствует.
                            • +1
                              Есть TopCoder UML Tool. Написано на Java. Я лично не пробовал, но эта штука активно используется в разработке на topcoder.com.

                            • +3
                              интересно будет посмотреть про джанго. на самом деле, мне кажется, что кодогенерация для джанго несколько излишние предприятние.
                            • 0
                              В области встроенного ПО автогенеренный код применяется с большим успехом и очень давно. Дело все именно в удобстве документирования и разработке, основанной на примитивах (model-based development, например).

                              А если разработка ведется по какому-либо отраслевому стандарту. то время экономится еще и за счет квалификации программного обеспечения для разработки и, как следствие, удешевлению верификации и сертификации.
                              • +9
                                Может у меня что-то с глазами, но я не вижу никакой связи с Джанго в посте.
                                Или это такой способ привлечь внимание?
                                • +3
                                  Я тоже удивился, а ещё удивило # -*- coding: cp1251 -*- разве на питоне не все пишут в # -*- coding:utf-8 -*-?
                                  • 0
                                    cp1251 — следствие использования плохого редактора по виндой.
                                    Проходит со временем.
                                • +3
                                  Описанный пример — пример неграмотного и глупого решения задачи. Какой смысл плодить сгенерированный дублирующийся код? Все ради того, чтобы рисовать стрелочки в ГУИ?

                                  А уж такую задачу, как связь и создание объектов по требованию можно решить легко без автогененированной каши.
                                  • –2
                                    ну вы не правы, дорогой, вспомните долгие рассуждения о том, как правильно писать инклуды на спп, или как муторно искать нужный файл с классом в котором надо поправить 76 строчку, или подумайте какой-это геморрой делать апгрейд проекта в котором 150 файлов со странными названиями.
                                    • +2
                                      Долгие рассуждения фиксятся документом под названием code convention. Нет времени его придумывать — возьмите Google Code Convention или Lockheed-Martin.

                                      >>Геморрой делать апгрейд проекта
                                      А это, извините, специфика разработки — чтобы что-то поменять, надо что-то поменять. В случае с UML у вас даже юнит-тестов на сгенерированный не будет.

                                      >> 150 файлов со странными названиями
                                      Такое будет как раз после использования кодогенератора.

                                      Кроме того, сравните возможности этого notepad-кодогенератора и нормального редактора кода — с подсветкой, ассистом и браузером кода.
                                      • –2
                                        1. я о code-convension не знал, видимо в ближайшее время не узнаю,
                                        2. речь не о том, что бы сделать так, чтобы работало и сверять юнит-тестом, а быстро вспомнить что почем, и не рисовать картинки на столе
                                        3.прикольно а у вас проект все в одном файле лежат?)

                                        Не знаю, как вам, я тоже давно прирос к кодогенератору, и если вы не имеете проблем с синтаксисом языка и соглашениями о его оформлении, то проблем с кодогенератором у вас не будет. Я же стараюсь любой громоздкий проект перевести в него, потому как с картинками работать удобнее, чем с текстом.
                                        • +1
                                          2. Ну так чтобы вспомнить, что почем, необязательно иметь кодогенератор, достаточно wiki c UML-схемой. Если конечно, у вас не директива «сначала UML, потом код по нему»
                                          3. Нет, у меня все выстроено иерархически, по папкам и проектам, так что вопросы к проекту на предмет «что-где» не появляются )

                                          Кодогенератор нужно использовать там, где нужен кодогенератор.
                                          Иначе code-generation превращается в co-degeneraton, со связанными руками, наколенными хаками и все такое. Тот же RUP, несмотря на всю формальность, со стороны архитекторов предусматривает только генерацию протоколов/интерфейсов, а код пишут люди.
                                        • –1
                                          а зачем unit-тесты для кода, который из генератора вылезает?
                                          • +2
                                            А вы посмотрите на иллюстрации в статье внимательно. Там генерирует только «скелет», а «мясо» вписывается руками. Я считаю, что его _надо_ тестировать.
                                        • +1
                                          > вспомните долгие рассуждения о том, как правильно писать инклуды на спп

                                          Претензии к авторам C++ за отсутсвие модулей.

                                          > или как муторно искать нужный файл с классом в котором надо поправить 76 строчку

                                          Не знаю, у меня в php классы в строгом порядке по папкам, я всегда знаю где какой искать (и имена файлов соотвествуют классам).

                                          > или подумайте какой-это геморрой делать апгрейд проекта в котором 150 файлов со странными названиями

                                          Бросайте курить всякую дурь и называйте файлы нормально :)

                                          p.s. Вы про code convention не слышали, наверно и про inline documentation и системы типа javadoc/cppdoc не слышали? Теорию учите тогда и учитесь оформлять код правильно.
                                      • +4
                                        UML в Django — это в первую очередь создание ORM-моделей.

                                        Не увидел пути к этому в посте:( А очень-очень хотел, правда.
                                        • 0
                                          Да, я тоже этого ожидал.
                                          У самого была (давным давно, когда был юн и холост) идея сделать на PyQt подобную генерилку, но руки так и не дошли.
                                          • +1
                                            А не проще ли:
                                            а) придумать хорошие названия моделям,
                                            б) разбить модели по модулям
                                            и спокойно обозревать всё это добро без каких-либо доп. инструментов?

                                            Пункт «а», наверно, самый важный. Иногда название ну никак не придумывается. Это явный признак плохого дизайна. Когда названия ясны и точны, вопросов о структуре и связях не возникает и схемы практически не нужны.
                                            • 0
                                              Так вот об архитектуре и речь. UML позволяет создать архитектуру, «подвигать» её в разные стороны, не написав ни единой строки кода. Вообще говоря, UML-модель — это нечто еще обльшее, что еще шире охватывает архитектуру вашего приложения, чем простое проектирование структуры объектной модели.

                                              Мы здесь не пытаемся отказаться от UML. Задача в том, чтобы не писать одно и то же сто, а иногда и тысячу раз. Не знаю как вам, а мне достаточно трудно обозревать в коде проект состоящий из 6-8 app-ов, в каждом из которых не меннее 10-12 моделей.

                                              Задача автоматической генерации Django-моделей из диаграммы классов UML выглядит достаточно тривиальной. Интереснее было бы генерировать код для view из Sequence-диаграммы, автотесты из Use Case диаграмм и т.п.

                                              Согласитесь, что при наличии подробного ТЗ, формальной формой которого является UML-модель, создание проектов с использованием Django сводится к однообразному механическому кодированию. Так почему бы не отдать однообразную бездумную работу инструменту, которые для этого создан?
                                        • 0
                                          Мне для диплома надо написать кодогенератор UML -> САА; хорошо, что прочитал эту статью, спасибо.
                                          • –1
                                            Сильно рекомендую посмотреть на Active Record для Ruby
                                            • 0
                                              Лет 5-6 назад я участвовал в проекте, для которого мы написали ядро для кодогенерации кода python из PowerDesigner, и кстати тоже использовали wxWidgets и MSSQL (может это тот же проект? Тогда привет Марселю и Вите. :) )
                                              Но основная фишка того проекта — это генерация типизированных форм из диаграмм объектов. Это позволило 3 разработчикам за 1.5 года практически полностью автоматизировать одну из крупнейших оптовых контор в Казани, занимающейся алкоголем.
                                              Ну и других плюсов не мало. :)

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