Є ідея гри чи геймінг-сервісу? Реєструйся на онлайн-хакатон 7.08! Призовий фонд — $3000
×Закрыть
  • Переход с Maven на Gradle

    Я все ж схильний надавати перевагу conventions over configuration, навіть якщо це йде всупереч компактності. :) Maven 3.3.1, кажуть, дозволяє писати pom.xml взагалі майже довільно: github.com/takari/polyglot-maven (в Overview є приклад на Ruby, хоча я так і не мав змоги з таким підходом попрацювати). У Gradle, принаймні як це заявлено на офіційному сайті, все ж є (?) суттєвіші переваги аніж просто компактність: gradle.org/maven_vs_gradle Знову ж таки, не мав змоги перевірити — приходиться вірити на слово. :)

    Поддержали: Alexander Levitskiy, Sergey Podobry
  • Переход с Maven на Gradle

    В Ant взагалі абсолютна свобода, проте його build.xml-и з часом на повну кашу перетворюються, незалежно від рівня тих, хто їх пише.

    Поддержали: Alexander Levitskiy, Sergey Podobry
  • Mercurial vs. Git в коммерческой разработке

    Мушу додати все ж коментар і визнати деяку некомпетентність стосовно вічності гілок в hg. Як мені сьогодні підказали, «вічно» також можна трактувати по-різному. Так, зокрема, у моєму випадку «вічно» слід розглядати як те, що гілка навічно залишається історії і залишає за собою ексклюзивне право на своє ім’я. Проте, існує можливість «затінити» існуючу гілку (щоправда, перевіряв лише на закритій), додавши просто ключ «-f» у виклик команди «hg branch». Таким чином, нова гілка матиме таке ж ім’я, як і попередня. «hg up» оновлюватиме до останньої гілки із таким іменем.

  • Нужна критика Java пет-проекта

    Загально
    1. Назви пекеджів мають бути в нижньому регістрі
    2. for ( int i = 0; i < collection.size(); i++ ) -> for ( T value : collection )
    3. Якщо вже дійсно закривати ресурси, то у finally-блоках.
    4. import static може мати позитивний вплив на читабельність.

    Сервлети
    1. Команди потрібно розділити і виокремити рівні контролера і сервісів, перший з яких мав би відповідати за взаємодію із зовнішнім світом (не обо’вязково сервлети+HTTP) і просто в лоб перетворювати запити і відповіді на/з сервера, а інший — власне, будувати логіку, і звертатися до DAO-шару у разі чого.
    2. CommandFactory якась не дуже-то й фекторі. Більше щось типу як «command-локатор».
    3. Команди можна було б розділити на щонайменше read- і на write-операції, що могло би мати позитивний наслідок для MainController, який незалежно від HTTP-запиту делегує виконання на той самий код.
    4. Перевірка вхідних параметрів із запитів — там жесть. Щонайменше стрічки в константи повиносити + можливо, написати вручну маппери, які би запит перетворювали у «істівне» з точки зору сервісів.
    5. Перевірка вхідних параметрів, можливо, нехай би краще викидала IllegalArgumentException, а вже би контроллер сам знав, як про це сповістити користувачу.

    Можливо, варто дивитися в бік Spring MVC.

    DAO, JDBC
    1. DaoFoo -> FooDao; DaoBar -> BarDao.
    2. Всі DAO-класи могли би мати спільного предка, окрім як java.lang.Object, для пристойності.
    3. Жорстка зав’язка на синглтон DaoFactory загалом. Я би їх взагалі уникав і у клієнтський код просто би передавав посилання на фекторі, а чи вона синлтон чи ні — питання другорядне (з точки зору клієнтського коду, звісно).
    4. Connection, ***Statement, ResultSet не закриваються.
    5. Можна було б мати connection pool.
    6. resultSet.getString("foo«) можна було б виносити в змінну і лише тоді порівнювати n-ну кількість разів
    7. Перебір одного Iterable і переливання елементів з нього за умовою в інший Collection, по суті, є базовим алгоритмом filter, який реалізовано як в Stream API, так і в Google Guava (там навіть ще простіше + немає вимоги щодо Java 8)
    8. Часто сутності (entity) для сервісів виду «прочитав з бази — віддав назовні» можна робити іммутабельними, передаючи аргументи через єдиний конструктор. (Хоча тут є спірні моменти з кількістю параметрів у таких конструкторів і з шаблоном Builder)
    9. Витягувати запити з ресурсів, я думаю, все ж не дуже варто. («//», до речі, не є коментарем у properties).
    10. DAO-рівень також мав би мати мінімум логіки (перераховування бонусів мало би бути десь на сервісному рівні). + Туди ж і локальні змінні, які ведуть себе як константи
    11. Запити, такі як ADD_BONUSES_TO_DB, можна було б за допомогою квері-білдерів можна було б перетворювати в batch-INSERT-запити, якими одним махом можна відіслати все в базу.
    12. Спірне по суті, але я би старався уникати методів, які повертають null (можливо, throw?). Або принаймі явно оголошувати такі методи як @Nullable (JSR-305)
    13. Якщо потрібно перевірити наявність якогось об’єкта за ключами, не варто передавати в такий метод весь об’єкт. Наприклад, isExist(Employee): 1) не зрозуміло, що робиться із таким об’єктом (він мутабельний); 2) не зрозуміло, які його поля впливають на поведінку isExist(); 3) для виклику того метода потрібно взагалі спочатку інстанціювати Employee. Можливо, exists(login, password) краще? До речі, read(Employee) також дивний, оскільки приймає Employee, за потрібних умов його змінює, і його ж повертає. До речі, користувача варто було б однозначно ідентифікувати лише за логіном.
    14. getDs() -> getDataSource()
    15. ADD_BONUSES_TO_DB -> ADD_BONUSES (й так зрозуміло, що мається на увазі БД); TUNE_EMPLOYEE -> GET_EMPLOYEE?
    16. catch (NamingException e) { /*logger.error( e); */ } -> загорнути в RuntimeException і викинути

    Можливо, варто дивитися в бік Spring JDBC Template.

  • Нужна критика Java пет-проекта

    Може мати суттєвий ефект, зокрема linkedList.get(i) не є O(1). Ітератори самі по собі вже можуть бути оптимізовані для оптимальної ітерації. + for(each) все ж позитивно впливає на читабельність.

    Поддержал: Victor Bolshakov
  • Mercurial vs. Git в коммерческой разработке

    До речі, та, забув, але це не «first-class citizen», як і rebase, який з нуля в hg відсутній.

  • Mercurial vs. Git в коммерческой разработке

    Я справді дуже люблю hg, і для своїх особистих проектів надаю йому перевагу, а не git, проте з часом я маю все ж деякі розчарування стосовно нього. З ходу можу назвати наступне:

    • Відсутність staging area. В git її наповнювати можна в імперативній формі, і згодом видалити із неї файли, випадково туди занесені. Писати hg commit із складним фільтром для комміта важко, і виправляти такий комміт незручно або важко (як і через hg commit —amend, так і через hg strip —keep).
    • Імена гілок у hg вічні. Якщо планується якась експериментальна гілка, яку планується назвати «experimental», дуже бажано подумати ще раз, чи вартує їй давати саме таке ім’я, оскільки навіть з hg commit —close-branch створити нову гілку із таким іменем більше не можна буде. Ніколи. Навіть через два роки. Смішно, але тут навіть svn ліпше виглядає.
    • Закладки (bookmarks), які концептуально трохи ближчі до git-ових гілок, в hg випиляти інколи також складно (якщо можливо).
    • Субрепозиторії в hg мені особисто здаються «дикішими» за субмодулі в git, оскільки hg при коміті в батьківському репозиторії оновляє .hgsubstate, якщо, знову ж таки, в hg commit не вказати правильний фільтр.
    • .hgignore лише, по ходу, в кореневій директорії. Якщо субдиректорії мігрують з місця на місце з часом, це також означає, що шляхи в одному .hgignore також потрібно поправити вручну.
  • GitHub vs. Bitbucket

  • Для RSS є повноцінна заміна? Чому зараз його ігнорують багато сайтів?

    Я про те що, Feedly, InoReader, як і почивший Google Reader, пропонують доступ, грубо кажучи, на безперебійній основі для клієнтів різного роду (веб, Android, iOS і, можливо, десктоп чи CLI), не вимагаючи постійного аптайму цих клієнтів. Натомість ці сервіси періодично агрегують ваші RSS-стрічки, навіть коли ваші клієнти відключені, що дає змогу спокійно зайти через тривалий час і переглянути все, що надійшло у ці стрічки за вашої відсутності (в розумних межах, звісно). У випадку з клієнтами типу Thunderbird потрібний постійний аптайм. Інакше частина апдейтів просто пройде повз, бо в RSS-фідах прийнято видавати лише останні n апдейтів, а не всю історію.

  • Для RSS є повноцінна заміна? Чому зараз його ігнорують багато сайтів?

    Ви користуєтесь офлайн-агрегаторами?

  • Для RSS є повноцінна заміна? Чому зараз його ігнорують багато сайтів?

    InoReader взагалі крутий, щонайменше коли я востаннє його для себе тестив. Перейшов би на нього із задоволенням, як би Press був із ним сумісний.

  • Для RSS є повноцінна заміна? Чому зараз його ігнорують багато сайтів?

    Так от власне, що це швидше набридає і змушує блокувати контакти в фідах для пониження інформаційного шуму.

    Поддержали: Denys Rafael, Василь Зима
  • Java дайджест #18: ожидание Java 9, G1 — сборщик мусора по умолчанию, почему убили log4j 1

    Дякую. «Третя рівна половина» була проти лямбд взагалі, напевно: декілька разів зустрічав думку, що лямбди мають негативний вплив «на надійність софту» і «на реалізацію крупних проектів».

  • Java дайджест #18: ожидание Java 9, G1 — сборщик мусора по умолчанию, почему убили log4j 1

    Бо прості і зручні фічі в Java з’являються раз на 15 років. Благо, try-with-resources маєм. До того приходилось писати всякого роду сурогати CloseableProcessor<t> чи використовувати Closer. А так, із списку хіба collection initializers було б непогано мати і, можливо, string interpolation, якщо я правильно розумію «string templating».

  • Java дайджест #18: ожидание Java 9, G1 — сборщик мусора по умолчанию, почему убили log4j 1

    Можете коротко розказати, про що йшлось в тих обговореннях?

  • Java дайджест #18: ожидание Java 9, G1 — сборщик мусора по умолчанию, почему убили log4j 1

    Ми, по ходу, говоримо дещо про різні речі. Я лише кажу, що статичні імпорти унікально іменованих методів справді зручні у використанні, хоча і мають свої недоліки. Залишимо це справою звички.

  • Java дайджест #18: ожидание Java 9, G1 — сборщик мусора по умолчанию, почему убили log4j 1

    Так Sets же із Guava покриває лише основні реалізації і спроектований лише для того, щоби найбільш використовувані сети можна було наповнювати зручним способом (а не використовувати той же double brace initializer), і змусити Java 6- компілятор вивести типи подібно до diamond-operator в Java 7. Якщо CoolConcurrentSet заслужить такої поваги — можливо, й потрапить туди. Хоча навіщо, якщо міг би існувати static-import-friendly CoolConcurrentSet.coolConcurrentSet(...).

  • Java дайджест #18: ожидание Java 9, G1 — сборщик мусора по умолчанию, почему убили log4j 1

    На жаль, не можу демонструвати реальний приклад, і випадок з Google GSON у мене вже давно був. Проте, наскільки я пам’ятаю, тоді я завтикав щось із тайп-адаптерами чи тайп-токенами, і зав’язався на конкретний клас ArrayList. Не подумавши/забувши/не знаючи наслідків, об’єкт вирішив ініціалізувати через double brace initializer. Відповідно, прямий маппінг для об’єкта, породженого таким чином класу, не працював. Щось таке.

  • Java дайджест #18: ожидание Java 9, G1 — сборщик мусора по умолчанию, почему убили log4j 1

    Я не казав, що double brace initializer — моветон, але справді вважаю, що він таким є, оскільки використовується для імітації деякої поведінки, яка доступна, наприклад, в C# (Collection initializers), або може бути досягнута тими ж фекторі-методами чи іншим зручним API (включно з builder-патерном). Крім того, механізм double brace initializer не працює із класами, які оголошені final-класами, оскільки сам вимагає породження анонімного класу лише для сурогатної ініціалізації об’єкта, у якого просто немає зручного API, яке може навіть бути ефективнішим, ніж послідовні операції над об’єктом. Крім того, у деяких випадках, створення таких класів інколи провокує помилки, які важко відслідкувати (наприклад, при серіалізації сам стикався з таким у Google GSON).

    Поддержал: Viktor Musienko
  • Java дайджест #18: ожидание Java 9, G1 — сборщик мусора по умолчанию, почему убили log4j 1

    Я все ж би не розглядав статичний імпорт просто як синтаксичне спрощення для класів типу Math. LinkedHashSet.of із запропонованого JEP 269 має свій аналог в Google Guava під виглядом newLinkedHashSet(), і чудово імпортується без клешів поряд, скажімо, із newTreeSet(). Щоправда, наскільки мені відомо, деякі код-конвеншени забороняють використання статичних імпортів, і тоді дублювання імені класу в назві відповідного фекторі-метода справді виглядає жахливо (+ синтаксичне підсвічування статично імпортованих методів читається не так зручно, як підсвічування окремо назви класу і назви його метода).

    Поддержал: Viktor Musienko
← Сtrl 12 Ctrl →