Самые глупые вещи, которые я сделал будучи программистом

http://blog.cherouvim.com/the-stupidest-things-ive-done-in-my-programming-job/
  • Перевод
Оригинальное название статьи: «The * stupidest things I’ve done in my programming job», поэтому перевод названия статьи не очень точен, однако то, что автор имел ввиду под "*" мы опустим — мы ведь не знаем наверняка :)

Я больше не стыжусь своих грешков, так что — вперед:

1. ORM


Глупость

Создал собственную ORM (Object Relational Mapping) библиотеку

Следствие

Неразбериха в проекте после двух лет поддержки, в следствие хаков-обходов моей ORM библиотеки для запуска прямых SQL запросов

Что я должен был сделать

Использовать Hibernate, iBATIS, Cayenne или нечто подобное.


2. EAV


Глупость

Использование модели Entity-attribute-value

Следствие

Отсутствие масштабируемости (scalability) и полная невозможность запускать нужные запросы на уровне базы данных.

Что я должен был сделать

Использовать процедуру нормализации БД.

3. Database Access


Глупость

Последовательный доступ к базе данных с использованием одного общего соединения для всех пользователей.

Следствие

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

Что я должен был сделать

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

4. IDE


Глупость

Избегал IDE (Integrated development environment), отказывался изучать и использовать

Следствие

Невозможность быстро строить, тестировать и развертывать (deploy) приложения.

Что я должен был сделать

Изучать IDE: NetBeans, Eclipseт.д.

5. Транзакции


Глупость

Не использовал вообще.

Следствие

Поврежденные данные в приложениях, в том числе повреждение функциональности.

Что я должен был сделать

Использовать транзакции

6. Prepared Statements


Глупость

Использование Statement, конкатенация строк и наивные преобразования запросов в «безопасные».

Следствие

Возможны SQL инъекции.

Что я должен был сделать

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

7. Бизнес-логика


Глупость

Вся логика заключена в шаблоне вывода (JSP).

Следствие

Беспорядочный код, неудобный для сопровождения

Что я должен был сделать

Использовать шаблон MVC или Front Controller. Ещё лучше использовать MVC в рамках таких open-source продуктов как Struts, Spring MVC, других.
Поделиться публикацией
Похожие публикации
Ой, у вас баннер убежал!

Ну. И что?
Реклама
Комментарии 61
    +12
    продолжим?

    Глупость
    Использовали собственные реализации очередей и семафоров
    Следствие
    Потраченное время, сложный код, ошибки собственных реализаций
    Что я должен был сделать
    Убедить в необходимости миграции на Java 5, использовать соответствующие классы из Collection API и java.util.concurrency
      +8
      Глупость
      Интеграция новых фич, забыв о рефакторинге старого кода
      Следствие
      Сложный код, который не поддается никаким изменениям
      Что я должен был сделать
      Использовать TDD + рефакторинг на ранних стадиях проета
        +2
        Это целый класс клупостей — делать свой велосипед и не пользовать хорошо известную библиотеку.

        +4
        Глупость
        Храним библиотеки, в том числе открытые, в SVN
        Следствие
        Сложная процедура обновления конкретной библиотеки, особенно если она имеет зависимости. Большой трафик к серверу
        Что я должен был сделать
        Использовать maven
          +1
          Очень интересный топик — посоветовал всей команде хоть и на php пишем. :)
          Можно этот пункт раскрыть?

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

          А что делать когда библиотеку приходиться патчить? да лучше до этого не доводить, но иногда приходиться…

            +3
            Именно так. Библиотеки скачиваются из публичных репозиторев. Однако mvn аккуратно и очень педантично сохраняет всё скаченное локально. Поэтому можно относительно не бояться — два раза одну версии одной библиотеки в общем случае качать не придётся.

            Сами зависимости объявляются в xml-файле, а файл находится под контролем версий. Поэтому если вы использовали допустим версию 1.3, а вдруг решили обновиться — вы просто правите цифру в xml-файле — 1.4. Теперь билд будет использовать новую версию.
              0
              «два раза одну версии одной библиотеки в общем случае качать не придётся» — сколько проектов у вас не было б. копии сохраняются в win — «C:\Documents and Settings\user\.m2\»
                +3
                Я бы добавил еще возмодность использования промежуточных репозитрориев уровня команды (Apache Archiva, Artifactory). Тогда скачивать придется один раз на команду, да и свои артефакты там держать удобно.
                  0
                  хотя у меня на маке был момент с тем, что запуск мавена с коммандной строки и с IDEA приводил к созданию 2 репозиториев. Решилось путем настройки всего, что связано с мавеном, но на маке с мавеном стоить быть осторожным :)
                    0
                    а на компьютере девелопера данную библиотеку кто обновлять будет? или у всех стоит клиент от maven?
                      +1
                      все пользуются maven для сборки
                +4
                Поддерживаю!

                Кроме того maven может помочь избежать таких глупостей как:
                1. Отыскивание и разрешение зависимостей вручную.
                2. Написание и поддержка длинных ant скриптов для сборки, деплоя и тестирования проекта (вообзе имхо, так что фанаты ant'a не ругайтесь :) )
                3. Создание тега в source control для стабильных версий кода.
                4. Много еще чего.
                  0
                  Or use Ant+Ivy
                  +13
                  Глупость
                  Вести всю работу с кодом в trunk репозитория, не заботиться об управлении конфигурациями
                  Следствие
                  Невозможность в нужный момент собрать необходимый релиз; невозможно править и коммитить несколько багов одновременно
                  Ч я д б с
                  Получше освоить корректное управлении исходными кодами (например, здесь, применить на практике паттерны управления версиями www.scmpatterns.com
                    +11
                    у меня таких глупостей под 100 штук наберется, но главное делать своевременно выводы и двигаться вперед… главное — вперед. не боятся изучать новое и пробовать новые концепции.
                      –11
                      scalability переводится, как правило, как «расширяемость» или «масштабируемость».

                      Исповедь говнокодера, вставшего на путь истинный.

                        +2
                        Глупость
                        Использовать константы для вывода i18n надписей
                        Следствие
                        Фоллбэк затруднен, а кое где невозможен,
                        Фраза должна добавляться сразу во все локализации,
                        Не отследишь непереведенные фразы,
                        Усложняет жизнь переводчика знаниями о кавычках и т.п.,
                        Сложно найти код, который выводит нужную фразу
                        Что делать
                        Юзать gettext на худой конец
                          +2
                          Глупость: пишу собственную реализацию event-management модели на java.
                          Следствие: не знаю как её применить.
                          Что делать: не страдать фигнёй :(
                            0
                            что делать — ответа нет. вы пишете ответ на вопрос «что НЕ делать»
                          • НЛО прилетело и опубликовало эту надпись здесь
                            +8
                            без ошибок и набивания шишек не понять смысла умных вещей. Уж лучше самому изобрести велосипеды чтобы лучше понимать зачем нужные чужие и готовые — а не бездумно пользоваться результатами чужого труда.
                              +4
                              Честно говоря, IDE — глупость номер 0. Минус один. Вселенская глупость!

                              // добавьте Idea, пожалуйста. Штука очень мощная и безусловно окупается.
                                +4
                                Я сам фанат IDEA начиная с версии 3.0. Однако из перевода слов не выкинешь :)
                                +28
                                Глупо верил в существование «серебрянных пуль» компьютерной науки.

                                Повзрослел. Теперь отношусь терпимее к своему и чужому говнокоду
                                  –3
                                  А что это?
                                    0
                                    Ответ ищите в книге Фредерика Брукса «Мифический человеко-месяц или как создаются программные системы». Только помните, что каждый новый ответ порождает новые вопросы.

                                    lib.ru/CTOTOR/BRUKS/mithsoftware.txt
                                  –8
                                  Да и вообще нужно было Grails использовать вместо всей этой разрозненной ботвы.
                                  • НЛО прилетело и опубликовало эту надпись здесь
                                      0
                                      Скажите, а сколько времени ушло на написание этого «велосипеда» и его отладку, сколько еще уйдет на добавление новых фич при необходимости. Автор говорит о том, что лучше использовать готовое решение если оно уже давно написано и работает как надо. По моему нужно иметь очень веские основания, чтобы писать свою orm, когда есть монстры вроде hibernate.
                                      • НЛО прилетело и опубликовало эту надпись здесь
                                        0
                                        Мне интересно — есть ли какие ORM системы для php
                                          +1
                                          Как минимум Propel и Doctrine, ну и еще всякие мелкие можно гуглить…
                                          • НЛО прилетело и опубликовало эту надпись здесь
                                          +2
                                          Мда. А всего-то стоило заюзать что-то из пункта 1 и проблемы 3, 5, 6 сразу отпали бы.
                                            +1
                                            хм, я как дилетант, думал, что для DB connection pool надо просто юзать appllication servers, в которых это уже есть
                                              0
                                              Далеко не всегда использование полноценных серверов приложений оправдано. Надо смотреть по требованиям конкретной задачи/проекта.
                                              +9
                                              Одна из самых глупый вещей, которая не позволяет оглядываться назад и пересматривать себя со стороны — это отношение к критике.

                                              Глупость
                                              Не принимал критику кода/решений — взрывался, отрицал, начинал оправдываться. Очень резко относился к любому вмешательству в свой код.
                                              Следствие
                                              Заблуждения, конфликты с коллегами, «допотопность» — не использовал кругозор других.
                                              Что я должен был сделать
                                              Прислушаться к критике, самому на нее нарываться. Потому что люди, критикующие или сообщающие тебе об ошибке — чаще всего, делают тебе хорошую услугу. Обсуждая свой код, свои решения — мы учимся, находим правильные решения, ведь спор заставляет нас думать, аргументировать наши поступки. Понимание этого вкупе с терпимостью :-) и позволяет легко учиться на своих ошибках.
                                                +5
                                                А я всегда любил критику в адрес своего кода, при одном условии, что критик человек достаточно компетентный в этом вопросе.
                                                • НЛО прилетело и опубликовало эту надпись здесь
                                                  +2
                                                  Сделал 1-3 на C# :)
                                                  Как-то работает, конечно, но сейчас бы так уже делать не стал.

                                                    +3
                                                    Глупость
                                                    Изобрел велосипед.
                                                    Следствие
                                                    Все работает медленно, находятся новые баги.
                                                    Что я должен был сделать
                                                    Воспользоваться Java API, а не изобретать велосипед.
                                                      +1
                                                      ч я д б с
                                                      Воспользоваться готовыми решениями (библиотеками), которые уже используют Java API, а не изобретать велосипед
                                                        +1
                                                        Это я и хотел сказать, но ваше ч я д б с более точно отражает мою мысль. Спасибо
                                                          0
                                                          всегда пожалуйста :)
                                                      +2
                                                      а помоему все это жутко полезно, сталкиваться с проблемами, даже изобретая свой велосипед — это самый лучшии опыт.
                                                        +2
                                                        Ну по поводу пунктов про ORM, EAV и IDE я бы поспорил.
                                                        * ORM — нужно изобретать, в идеале, править имеющиеся. Так как то что есть далеки от идеала. На практике реально использовали практически полностью своё, первая версия конечно же больна всеми болезнями, что дают велосипедостроение и первооткрыватели, но идеи, особенно на вторую версию, очень даже здравые.
                                                        * EAV — отказываться от этой модели не просто глупо а преступление :) в некоторых случаях без нее просто не обойтись. Говорить что эта модель в чем то ограничивает как то глупо, я не согласен, изменение структуры данных без изменения структуры физического хранилища очень большой плюс. Проблемы с производительностью решаются, к примеру, 'кешем' в нормальных формах, для критичных для скорости данных.
                                                        * IDE — полностью отказываться конечно тяжело да и не нужно, практика показывает что в части задач разработки лучше использовать что 'то мышастое' (это шутка, имеется в виду готовые инфраструктуры сборки, отладки, тестирования, генерации установки и т.д.) чтобы не тратить на это время, за это же можно заплатить потерей производительности конечной программы (хотя выбор IDE и фреймворка должен быть обдуманным с оглядкой именно на производительность, а не только на возможности). но практика показывает что какие то задачи удобнее решать 'своими силами', в этом случае IDE, которое можно допилить до желаемого, предпочтительна.
                                                          0
                                                          Правка имеющихся ORM без внесения этих изменений в транк библиотеки — это ещё одна глупая вещь. Я не представляю, как вы будете писать «свой Hibernate». Это было бы очень и очень глупо. Написание своей ORM могут себе позволить только очень крупные компании, понимающие почему им не подходят конкретные библиотеки, даже после допилки.

                                                          Про IDE. Eclipse очень хорошо пилится и дополняется плагинами. Единственный его недостаток — скорость работы и требуемая память.
                                                            0
                                                            Кстати, не подскажите, какие подходы к кэшированию EAV и обеспечению когерентности популярны/распространены?
                                                              +1
                                                              Если из вопроса убрать слова 'популярны/распространены' (не обладаю достаточными данными чтобы отвечать именно на это), то…

                                                              * Кеширование EAV?
                                                              Самое первое решение, что приходит обычно в голову, это возврат к модели преставления данных, проблемы которой оно и решает, т.е. создание таблиц с полями — соответствующих элементам из EAV. Само собой только для тех атрибутов, доступ к данным которых — узкое место.
                                                              EAV: prop(id,name)={1: это,2: то,3: тому,4: того,...}, object(id,...), values(id,object_id,prop_id,data)
                                                              Кэш: cache(object_id,prop1,prop2,prop3)
                                                              Плюсы: облегчает задание сложных ограничений целостности (constraint на кэш), увеличивает скорость доступа к значениям пропертей (индексы на propX у кэша)
                                                              Минусы: неполная транзакционность (изменение prop, да еще внутри тригеров — кошмар), вроде нет БД предоставляющих транзакции на команды DDL, меняет подход к построению SQL запросов и ограничивает/усложняет удаление элементов из prop.

                                                              * Соответствие кеша данным?
                                                              Что тут можно предложить, только тригеры или использование прослойки между БД и приложением (фактически свои собственные тригеры).
                                                              Прослойка между приложением и БД вообще полезная вещь не только для подобных задач, если использовать информацию о модели данных, на этапе проектирования в (полу)автоматическом режиме, то создание подобных кешей можно вообще практически полностью автоматизировать.
                                                                0
                                                                Т.е. кэш заранее делается на определённый состав пропертей (и, соответственно, под определённый класс запросов)? Просто интересно, может для этого есть какие-нибудь невелосипедные библиотечки/наработки. Это в частности, интересно, т.к. некоторые игроки предлагают key-value базы данных и было бы неплохо производить какие-нибудь простенькие операции с ними на стороне клиентов в семантике SQL.

                                                                Я так понимаю, что оригинальный жалующийся автор (Ioannis Cherouvim) как раз и реализовал в своём самописном ORM какую-то извратную обёртку вокруг EAV. Из-за этого велосипеда (а также из-за замены продумывания схемы БД кажущимся ему «серебрянной пулей» EAVом) он и получил фэйл…
                                                                  0
                                                                  При создании оберток нужно не забывать что обертка делается для человека а не наоборот.
                                                                  Не следует запрещать самому себе все и вся, это вредно — именно это обычно порождает проблемы.

                                                                  P.S. Производительность практически всегда приносится в жертву удобству, и наоборот. Если видите что система получается слишком сложной (взаимозависимости технологий друг от друга большое), лучше остановиться и прекратить решать как еще извратиться чтобы получить результат (анекдот про программиста и чайник помните?). Лучше написать своё.
                                                                    0
                                                                    Кэш делается после анализа узких мест (которые можно и заранее предугадать кстати), само собой запросы должны будут переписаны под использование этого кэша (у нас это было легко сделать, даже с учетом дрянной реализации и временных наслоений кэш заменил собой вьюху, которую oracle не очень хотел оптимально разворачивать в запросах, хотя у нас и специалиста как такового не было).
                                                              +1
                                                              Собственные интерфейсы мониторинга и управления вместо JMX.
                                                                +2
                                                                Сервера приложений там, где сгодился бы сервлет-контейнер,
                                                                контейнер — там, где прекрасно себя чувствовал бы Jetty.
                                                                EJB(2, 3) вместо Spring.
                                                                Бинарный ремоутинг там, где сгодились бы HTTP-запросы.
                                                                SOAP вместо REST.
                                                                GWT вместо фронтенда на jQuery (или подобном) к REST-бекенду.
                                                                Чисто джавские MVC-фреймворки вместо Grails.
                                                                Толстые клиенты на RCP и Swing вместо Flex/AIR.
                                                                Подключаемые библиотеки для работы с картинками вместо внешнего ImageMagick.
                                                                Работа с файлами и окружением из кода вместо шелл-скриптов.
                                                                  0
                                                                  это плохо, или это так надо?))
                                                                    0
                                                                    Думаю, что так было бы не плохо. Но не всегда вы можете этими требованиями управлять. Недавно был проект. Простенькая система учета материалов. На java/tomcat пишется в течение дня, но требование было написать это дело на lotus notes.
                                                                • НЛО прилетело и опубликовало эту надпись здесь
                                                                    +1
                                                                    +1 к фанатам IDEA. Стоящая вещь, экономящая время и нервы, а заодно в фоне обучающая новым методам рефакторинга :-)
                                                                      0
                                                                      Для чего в Hibernate нужно было реализовывать пул соединений через c3p0? Разве сам Hibernate этого не поддерживает?
                                                                      И еще вопрос, Prepared Statements:

                                                                      String sql = «from Logon where sid = :sid»;
                                                                      Query q = session.createQuery(sql).setString(«sid», logonValues.getSid());

                                                                      Это ведь именно prepared statement. Я это к тому, что если использовать Hibernate, то глупость №3 и №6 отпадают сами собой?
                                                                        0
                                                                        половина глупостей слишком странные

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

                                                                        Самое читаемое