• Самое опасное слово в разработке программного обеспечения
    +8

    Помимо "просто" меня жутко бесит слово "ВСЕ". Употребляется в контексте, когда нужно добавить новый функционал, но заказчик/менеджер не имеет представления о всей конкретике работы системы, либо тупо не хочет заморачиваться.
    — В какую форму добавить коментарий? — Во ВСЕ!
    — В каком сценарии вызывать этот интерфейс? — Во ВСЕХ!
    — Для пользователей каких ролей сделать проверку? — Для ВСЕХ!
    — Какие интерфейсы экспортировать для удаленного использования? — ВСЕ!

  • Объект в футляре или Optional в Java 8 и Java 9. Часть 1: «Как без него прожить?»
    –1

    Идея как раз в том, чтобы исключить искусственные методы типа isActive() и isPresent() и соответствующие проверки (они ни чем не лучше проверки на null). Возвращаемый "пустой" объект имеет полностью осмысленное поведение при вызове своих методов, и не требует специальных кейсов в логике программы. Например с пустой сторокой можно делать все те же операции, или например пустой список можно также итерировать в цикле без специальной проверки.


    я не понял зачем нужен EMPTY если не имплементируется equals()

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


    public class AnotherClass {
        public MyClass myClass = MyClass.EMPTY;
    }

    Это в случае если класс MyClass immutable. Тогда проверку на empty можно делать простым сравнением "==", но при желании можно добавить и equals()/hashCode(). Хотя как я уже сказал выше, поведение кода не должно отличаться в случае пустого или непустого объекта и не должно содержать искусственных проверок.


    Ну а список можно сделать immutable с помощью Collections.unmodifiableList()

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


    userService.getUsers().add(new User());

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

  • Объект в футляре или Optional в Java 8 и Java 9. Часть 1: «Как без него прожить?»
    –1

    Не использовать вообще нулевые значения.
    У большинства стандартных типов существует некое дефолтное значение, которым можно заменить null. Например для числовых типов это ноль, для String это пустая строка "", для списка — пустой список, etc.
    Поля класса сразу инициализируйте дефолтными значениями.


    Для собственных типов можно использовать можно искусственно определить нулевое значение и при необходимости сравнивать с ним.


    public class MyClass {
      public static final MyClass EMPTY = new MyClass();
    
      public final String name;
      // Optional field, "" by default
      public final String address;
    
      protected MyClass() {this("","");}
      public MyClass(@Nonnull String name) {
        this(name,"");
      }
      public MyClass(@Nonnull String name, @Nonnull String address) {
        this.name= name; this.address = address;
      }
    }

    Возвращается лист, возможно пустой
    Проблема в том, что лист mutable. Лучше возвращать Iterator или Stream.
  • Почему мне кажется, что студентов учат ООП неправильно
    0

    Извиняюсь, что поздно ответил.
    Смысл в том, при пожирании одновременно определенным образом изменяются состояния и собаки и сосиски. Однако первый вариант нарушает инкапсуляцию сосиски: собака должна знать как изменить свое собственное состояние (ок), но также и состояние сосиски. Во втором варианте соответственно нарушается инкапсуляция собаки.
    А третий вариант — это тупо процедурное программирование, закамуфлированное под объект, со всеми вытекающими (нарушение инкапсуляции, отсутствие полиморфизма).


    С упомянутым Вами удалением сосиски все еще хуже: после пожирания на сосиску остается указатель, поэтому впринципе одну и ту же сосиску можно скормить разным собакам, если не ввести искусственный контроль :)


    В более сложной модели собака и сосиска должны обменяться сообщениями типа собака-сосиске: "я тебя ем с такими параметрами", сосиска-собаке: "вот мои питательные вещества". Это будет более корректно. Иными словами собака и сосиска реализуют двунаправленный интерфейс "сожрать"-"быть сожранной" с двумя каналами. Но это уже больше похоже на модель акторов, нежели ООП.

  • Почему мне кажется, что студентов учат ООП неправильно
    0

    Не существует никаких классов и сущностей, есть только интерфейсы. Абстрактный водитель может управлять всем чем угодно, что реализует стандартный интерфейс "автомобиль" и имеет руль, педали и прочие приблуды. Более того, для управления нам не нужна никакая сущность типа "абстрактный или конкретный автомобиль": водитель может ездить на тренажере по виртуальной локации еще вместе с десятком таких же водителей. Здесь "сущность", которой управляем, уже выделить сложно. Точно также с другой стороны у нас нет никакой необходимости в сущности "абстрактный водитель" — стандартным такси может управлять механизм, подключенный к единой сети, которая управляет его действиями.


    И вот когда мы начинаем оперировать такой вещью как "состояние" и пытаемся разобраться как правильно будет разбить и сгруппировать состояние всей системы, появляются различные парадигмы программирования. ООП — одна из таких парадигм, и достаточно спорная, особенно что касается взаимодействия между сущностями. Подумайте на досуге под пивко, как будет правильней с точки зрения ООП:


    • собака.сожрать(сосиска)
    • сосиска.бытьСожранной(собака)
    • new ПожирательноеДействие(собака, сосиска).сделать()
  • Servlet 4.0: Делаем больше быстрее. Server Push
    0

    Прикрутили сбоку модную фичу для галочки.
    Никого не напрягает, что на coffie-cup.jpg уже ссылаются из .jsp и что чуть более интеллектуально развитый темплейтер мог бы сам запушать автоматически все необходимые ресурсы? Ну или на крайняк придумать специальную директиву для .jsp, чтобы там же рядышком прописывать все, что надо запушить. А модифицированные сервлеты уж никак не есть естественное место для справления своих потребностей в пуше.

  • Почему Agile не работает и что с этим делать
    0
    Во-первых, в разработке ПО есть такое понятие как гибкость.

    Да, в отличии от инженерного дела разработка ПО не ограничена жестко законами физики, поэтому позволяет девелоперам творить любую фигню — машина все проглотит. Тем не менее, базовые принципы построения проекта никто не отменял.


    Он просто позволяет делать качественный продукт в условиях неопределенности.

    А как вы себе представляете неопределенность? Продукт призван решать определенные задачи, для этого создаются определенные решения. Единственная область, где я вижу более-менее оправданное использование agile — это типичный веб-проект: страничка, сервер и база данных. Клиент пока не знает что конкретно ему нужно, но вы пока начните, сделайте форму логина, потом утвердим дизайн, определимся с функционалом, добавим пунктиков в меню, табличек в БД, etc… Архитектуры — ноль, зависимости слабые, объем работы скалируется и хорошо делится. Типичная дача.

  • Почему Agile не работает и что с этим делать
    0

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

  • Почему Agile не работает и что с этим делать
    0

    Совершенно верно. Agile — это когда вы строите для клиента дачу. Можно начать с возведения сортира, затем пилить баню, забор, сарай, потом приступить к дому, затем пристройку, потом домик для гостей — все по необходимости, и главное, чтобы народ был занят. А вот многоэтажку таким методом построить уже проблематично.

  • Блеск и нищета джавовых веб-фреймворков
    +2

    А дело в том, что Java изначально семантически очень плохо приспособлена для декларативных конструкций и DSL-ей. Фреймворки, построенные на аннотациях — это некий компромисс между декларацией и исполнением, причем очень фиговый по сравнению с тем же DSL. В бекенде еще как-то прокатывает, но во фронтенде, где приходится создавать иерархические конструкции (напр. DOM), в императивном стиле на Java это превращает код в линейную кашу. Поэтому на Java никогда не было и не будет нормальных html-темплейтеров, тем более type-safe как на скале или котлине. Хотя попытки есть: https://j2html.com/

  • Блеск и нищета джавовых веб-фреймворков
    +1

    GWT абсолютно ничего не имеет общего с Java-рантаймом. Это распространенное ошибочное мнение. У него есть определенная Runtime Library Emulation, чтобы можно было работать с коллекциями, строками, стримами, лямдами, etc как в Java. Но в рантайме GWT не таскает с собой вообще никакие библиотеки. Вместо этого он анализирует весь код приложения начиная от EntryPoint, включая только те функции из всей кодовой базы, которые используются въявную (а для 100% явности была выпилена reflection). Остальной шлак жестко шринкается. Дополнительными бонусом идет минимизация и обфускация. В итоге для функционального приложения код получается меньше, чем на нативном JS, т.к. последний грузит все используемые JS-библиотеки полностью со всем функционалом. Кстати, GWT поддерживает SourceMaps при запуске в DevMode, поэтому можно дебажить вживую в Chrome или Firefox, а в SourceMaps показывается только Java-код, который GWT оставил после шринкинга, т.е. то, что реально будет в рантайме.


    Насколько GWT-код может быть минимальным полностью зависит от того, что вы будете использовать. Откажитесь от стандартных GWT-виджетов и UiBinding, используйте библиотеку Elemental, и Overlay Types. Для манипуляции с DOM-ом для GWT есть аналог JQuery — GwtQuery.

  • Блеск и нищета джавовых веб-фреймворков
    +2

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


    • индикация описок, и ошибочных идентификаторов
    • подстрочник: подсказки при вызове методов
    • элементарный рефакторинг
    • простая навигация по коду (своему и библиотечному), позволяющая отследить всю цепочку вызовов
    • контрактный стиль программирования
    • различные тулзы для статического анализа кода
    • умные хинты и варнинги от IDE
    • кодогенерация и умные темплейты
  • Блеск и нищета джавовых веб-фреймворков
    0
    Да, многие из нас работают в банках, и там всё на GWT. Но, оглядываясь назад на этот долгий-долгий путь, давайте честно признаем: управлять JavaScript из Java — наиболее дурацкая и деструктивная идея, которая когда-либо приходила в голову.

    В GWT Java не управляет Javascript-ом. Java управляет DOM-ом, точно также как это делает Kotlin.js, Scala.js, TypeScript, Dart и вообще любой кросс-компилятор в JavaScript. Более того, это то, что должно было мейнстримом по причине ущербности JavaScript-а, но внезапно успело подрасти поколение JS-рунов, которым ущербность языка и динамическая типизация стало норм.
    Для сложных клиентских приложений использование GWT очень даже оправдано.
    GWT-проект очень нетривиально подготовить для воркбенча (вкратце пускайте вручную com.google.gwt.dev.DevMode.main(args)), но работает сносно и инкрементально компилится достаточно быстро.

  • Что я узнал после 1000 code review
    +1

    Не совсем понимаю чем вторая запись лучше и понятней первой. Если str объявлен как @Nullable, то при возможном NPE тулинг выдаст варнинг — и этого в большинстве случаев достаточно. Кроме того, тулинг достаточно умный, чтобы выводить @Nullable по коду.


    Кроме того, в данном случае, как я и говорил, имеет смысл вообще использовать @Nonnull String str = "" вместо null или Optional. И никаких проверок делать не надо.


    NPE исключен

    Да ладно?


    Optional<String> calculate() {
        return null;
    }
    Optional<String> str = calculate();
    ...
  • Что я узнал после 1000 code review
    +1

    Если у нас есть сложная операция или композиция, валидным результатом которой может быть "отсутствие результата", то Optional может подходить. Пример: Optional findPerson(query). Использовать же Optional для хранения или передачи состояния — плохая практика. То есть поля объекта Optional или Optional-параметр в сеттере — это сразу плохо (даже Idea вам об этом скажет). Поэтому единственный юзкейс — возврат значения, которого может не быть. Однако Optional в Java — достаточно лимитированная монада. По-сути единственное, что можно с ней сделать — это orElseXXX() (а много логики в map не запихнешь), никакой дальнейшей композиции с ней сделать нельзя (в Java 9 ей добавили свойства стрима и теперь можно делать flatMap()). Кроме того, в большинстве случаев логика требует нечто большее, чем orElse, поэтому все-равно приходится ставить if (maybe.isPresent()). Так что на мой взгляд, не фиг функционально выпендриваться на нефункциональном языке — в Java есть аннотация @Nullable.
    Насчет коллекций — формально да, но реально сложно найти пример, где бы необходимо было именно Nullable-коллекция. Пустая коллекция — это и есть отсутствие результата. Какой смысл при этом будет иметь возврат null (или Optional) не совсем ясно.

  • Что я узнал после 1000 code review
    +4
    Пустые объекты не являются подходящим инструментом для этой работы. Если ситуация исключительная, вы должны выбрасывать исключение

    Между прочим это один из кейсов негативного влияния checked exceptions. Если бы RemoteInvocationException не был бы задекларирован как checked, программист бы скорей всего не допустил ошибки. Вообще по эксепшнам можно отдельно статью писать. Смысл простой по возможности избегайте checked-exceptions. Всегда врапьте checked-exceptions по возможности в один из стандатрных форм RuntimeException: IllegalArgumentException, IllegalStateException, etc...


    Пользуйтесь наиболее специфическими типами данных

    Более того, в некоторых случаях имеет смысл использовать класс-враппер над типом, вместо самого типа. Например, вместо String phoneNumber лучше сделать враппер-класс PhoneNumber с единственным полем String value. Для перечислимых типов по возможности используйте enums.


    Используйте Optional вместо Null

    Сомнительная рекомендация. Optional к Java прикрутили сбоку совсем недавно с приходом элементов функционального программирования, и его использование не должно выходить за рамки функционального "однострочника". Кроме того большинство библиотек и спецификация Java Beans не предусматривает использование Optional вообще. Для null-checking уже давно имеются @Nullable аннотации, которые являются лучшей альтернативой, нежели Optional. Благо тулинг их понимает из коробки. Если же хотите писать в труЪ функциональном стиле с монадами Try и Option, используйте замечательную библиотеку http://www.vavr.io/


    Добавлю от себя еще некоторые правила:


    • По возможности используйте immutable-объекты. Их состояние детерминировано в любой момент.
    • Насчет пустых объектов: они всегда являются лучшей альтернативой, нежели nullable. Особенно важно для коллекций: возвращайте Collections.emptyList() вместо null. Для String использование по дефолту пустой строки "" вместо null избавить от кучи ненужных проверок.
    • Для collection-полей неплохой практикой будет возвращать в геттере Stream вместо Collection.
  • BPM в компании: пусть решают процессы
    0
    BPM-движок — это в первую очередь не просто конечный автомат, а все-таки движок, который может «проигрывать» схему, нарисованную бизнес-аналитиком в BPMN. И это действительно полезно, когда использовать BPM правильно, а не как «волшебную таблетку» для своего бизнеса.

    Этот движок занимает 70кб джарник, их полно в инете. Плюс средства разработки — BPMN-редактор, где человек с ограниченными интеллектуальными возможностями, гордо называющий себя бизнес-аналитиком, сможет почувствовать себя разработчиком, расставляя на диаграмме ящики и стрелки при помощи мышки, концептуально называя все это бизнес-процессом. А дальше требуется нехилая бригада чертей, которые заставят все это хоть как-то шевелиться — заполнить каждый ящик реальной логикой, используя предоставляемую провайдером "платформу", которая по-сути есть фоллбэк в какой-нибудь фреймворк (Spring, JEE, JBI, SCA, etc) или язык программирования, но только с сильно ограниченными возможностями.


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


    Однажды запустив процесс, начинается свистопляска с его поддержкой и версионированием. Причем, версии могут меняться как у самого процесса, так и у внешних сервисов и структур данных. До сих пор ни одна BPM так и не решила по-нормальному этот вопрос, потому что нормального решения просто нет. Нормальное решение — это при выкатывании новой версии апдейтнуть состояния всех запущенных процессов. Но поскольку у нас не простенькая state machine, а BPMN, выполняемая пропиетарным движком, то нифига не получится.

  • BPM в компании: пусть решают процессы
    +6

    Если бы космический корабль!
    Когда клиенту нужно наладить доставку продуктов из пункта А в пункт Б, где хватило бы мотоцикла с коляской или для особо продвинутых — электромобиля на солнечных батареях, тебе продают железную дорогу, позиционируя как наилучшее и самое перспективное решение на рынке грузоперевозок. Комплект включает в себя: рельсы, шпалы, паровоз (1шт.), лицензию на использование, толстую инструкцию по монтажу, экспресс-курсы для клиента на роль путейцев, машинистов, кочегаров, вагоновожатых и станционных диспетчеров.


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


    Весь монтаж и использование делается исключительно силами свежеобученных "специалистов" клиента под зорким присмотром провайдера, который следит за соблюдением концептуальности монтажа (best practices) и правильным использованием "средств разработки" — лопаты, лома и кувалды. Обязательная "поддержка" паровоза производится провайдером за периодическую плату, которая состоит в оперативном объяснении клиенту, в чем была его вина в случае взрыва котла или схода поезда с рельс: неправильная эксплуатация локомотива или некачественный монтаж путей.
    Любые претензии к провайдеру не принимаются во внимание. Низкая скорость доставки или паровоз не едет в горку — покупайте второй паровоз и используйте в сцепке! Поэтому большинство клиентов на особо сложных участках колеи использует своих лошадей для "подтаскивания" локомотива (а иногда и поездную бригаду), т.к. на второй паровоз денег запланировано не было. Доходит даже до случая, когда поезд с локомотивом на всем участке приводится в движение исключительно лошадьми, но это уже крайность.


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


    Звучит шизофренично, но это краткое иносказательное описание моего более-чем-десятилетнего опыта работы с BPM.

  • BPM в компании: пусть решают процессы
    +4
    Зачем BPM бизнесу? BPM — это концепция управления бизнесом через бизнес-процессы.

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


    У нас для вас две новости: хорошая и так себе. Хорошая: BPM уже существует. Так себе: мало кто знает, что с этим делать.

    Это я все периодически слышу более чем 10 лет. Уж извините за упоминания, "работал" (хотя тут больше подходит глагол, обозначающий действие сексуального характера) со стеком IBM Websphere, с Oracle SOA Suite, немного ковырял JBoss SOA platform и небольшие BPM вроде Activiti и Bonita — все клянутся, что это вазелин для вашего бизнеса и без него никак. В итоге практически нигде эти решения не работают по-нормальному по ряду причин концептуального, технического и политического характера. А возни и расходов с ними на порядок больше.


    Среди использующих Pega компаний — лондонский аэропорт Хитроу, MasterCard, City Bank, Morgan Chase и многие другие.

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


    В банках кейс, как правило, включает в себя все действия с момента обращения клиента (например, запрос на получение кредита, опротестование операции по карте) до полного решения данного вопроса (к примеру, выдача кредита)

    Это то, что продают на презентации продукта. Первый пример процесса в tutorials ко всем BPM — это Loan Broker. И как правило на этом все заканчивается.


    Работая в действительно нетривиальных и сложных проектах, разработчики могут использовать и прокачивать свои навыки: Java SE, Java EE,

    Согласно моему плачевному опыту, основную часть работы все-равно приходится делать именно в "этих самых навыках": Java SE, Java EE, и пр. И в определенный момент сама БПМ начинает уже мешать, а потом сильно мешать. И в итоге принимается решение переписать весь модуль на Java без участия БПМ.


    На самом деле, Pega сама по себе — будущее автоматизированных систем управления (АСУ) и корпоративных информационных систем (КИС).

    Это будущее уже на горизонте лет этак 15, еще когда BPM скромно называли Workflow. Но все никак не наступит. Так что определенная ниша у подобных решений будет всегда, но далеко не в каждом доме. А связывать свое будущее с программированием мышью, клепанием бесконечных формочек и меппингу данных — удовольствие на любителя.

  • Java EE 8: краткий и весьма оптимистичный обзор новых возможностей
    0

    С нулевыми зависимостями — это тоже миф. Обычно ВАР содержит еще тонны артефактов и велосипедов, не предоставляемых JEE API.
    Ну и традиционный троллинг: раньше чтобы протестировать простой бинчик, нужно было сбилдить весь проект, запаковать его в ВАР/ЕАР, запустить контейнер, задеплоить артефакт, и вызвать нужный метод через какой-нибудь remote api (EJB, JAX-WS, JAX-RS), посмотреть ошибку в логах сервера, попытаться понять с каким фрагментом кода она связана, закорректировать код и повторить операцию. В JEE8 есть какие-нибудь улушения на этот счет?

  • «В ЕЕ всегда есть альтернатива» — Дмитрий Александров (T-Systems) о Java EE / EE4J
    +3

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


    P.S. Как там с тестингом у микропрофайла? До сих пор юзается костыль Arquillian?

  • MockK — библиотека для mocking-а в Kotlin
    0

    Не знаю насколько релевантно: есть библиотека, которая позволяет пускать агента из уже с запущенного кода без нужды указывать -javaagent:
    https://github.com/electronicarts/ea-agent-loader
    Запуск агента производится через определенный OpenJDK-шный JMX — весь инструментарий для рантайм инжиниринга вналичии. Я так пускаю EclipseLink JPA с динамическим weaving-ом в рантайме.

  • Spark — Потрясающий веб-микрофреймворк для Java
    0

    В системах, где нужны привилегии суперпользователя, обычно имеется iptables:
    iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to a.b.c.d:8080

  • Необычный митап про Java в Питере 30 октября
    +1
    Как вы думаете, в современной автомобильной промышленности при каких обстоятельствах автоконцерн вкладывается в разработку своего собственного стеклоподъемника, а не возьмет готовый, хороший и стандартный агрегат?

    Тут две причины.
    Во-первых, автомобильный стеклопакет делает всегда одну и ту же вещь на всех марках автомобилей. Тогда как требования в IT настолько меняются от случая к случаю, что требуют сделать открытие окна сверху вниз, сбоку, наружу или внутрь, либо сразу во всех направлениях, или продолбить в окне персональную форточку для сигареты заказчика. Тут уже смотришь, что проще: мучиться, приспосабливая стандартный стеклопакет, либо плюнуть и сделать свой под конкретный случай.


    А во-вторых, сейчас мало фреймворков, которые предлагают только "стеклопакет". Обычно в комплекте идет своя электрошина, комплект акумуляторных батарей со специфическим вольтажем, блок управления с джентльменским набором кнопок, и собственный генератор. Изгововитель заявляет небывалую гибкость ввиде интеграции с любым типом ДВС. Вот и думай — когда тебе нужен только стеклопакет, стоит ли тащить еще все это добро в свое решение?

  • Spark — Потрясающий веб-микрофреймворк для Java
    0

    Я думал, Вы забросили этот проект. Ан-нет, уже даже достаточно юзабельная версия! На выходных попробую. Из пожеланий: добавить автоматический генератор врапперов к JS-библиотекам из TypeScript на DefinetlyTyped.

  • Spark — Потрясающий веб-микрофреймворк для Java
    +1

    Клиент-сайд состоит из двух частей: фреймворка и библиотеки виджетов. В качестве фреймворка довольно давно использую GWT + GQuery + RestyGWT. Доволен. Из печалек: медленная компиляция и неудобный дебаг в superdevmode. В качестве библиотеки виджетов можно использовать GWTBootstrap, GWT-Material, gwt-polymer-elements, любую CSS-based библиотеку, или даже интегрировать практически любой bullshit.js.


    Про упомянутый Vaadin: да, подтормаживает (постоянная синхронизация состояния виджетов с сервером), спорно годится для интернет-проектов, но для энтерпрайзных админок и дэшбоардов — самое то. При помощи GWT можно использовать весь widgetset Vaadin-a на клиентской стороне без использования серверной части, что значительно разгоняет UI. Кроме того, есть полностью js-ный Vaadin Elements. Из печалек: из пресловутый Vaading Grid тормозит гораздо больше на клиенте, чем на сервере.


    P.S. Хочу попробовать подергать Kotlin.js. Кстати, если уж о котлине заговорили, то вот фреймворк со схожим функционалом: https://github.com/Kotlin/ktor

  • «Если бы сейчас начали сначала, снова выбрали бы Scala»: Tinkoff.ru о Scala-разработке
    +1
    Напрашивающийся первый вопрос: почему в компании сделали неочевидный выбор в пользу Scala

    Недавний скандал с участием интернет-блоггеров повысил общественный интерес к персоне Олега Тинькова и его бизнеса. Нам он раскрывается как человек черезвычайно прагматичный, поэтому истинные мотивы выбора Скалы могут оказаться немного иными.


    С одной стороны фильтр вхождения в язык достаточно высок и сразу отсеивает большую часть любителей и непрофессионалов. То есть программист на скале — это "мозги" с уже достаточно высоким профессиональным уровнем, большим багажом знаний и способностью к самостоятельному обучению. С другой стороны действуют факторы, позволяющие осуществлять жесткий контроль и экономию средств на работниках, потому как:
    1) рынок трудоустройства на скале черезвычайно ограничен (куда вы еще денетесь с подводной лодки?)
    2) большинство людей со знанием скалы приходит без требуемого опыта (а где еще им его накопить?), что используется как аргумент при приеме на работу
    3) акцент в основном делается на молодых людей, которым еще предстоит "набраться опыта", для которых работа в компании позиционируется как "неплохой шанс" с заявкой на светлое будущее.
    Плюс одновременно можно не беспокоиться об утечке кадров, решений и экспириенса из компании. Получается тройной профит!


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

  • Периоды звездных суток в радиоактивном распаде
    0

    Масса причин, начиная от распределения темной материи в солнечной системе и заканчивая анизотропностью самого пространства. Фантазия безгранична!

  • «Паттерны» функционального программирования
    +4

    Потому что основа функционального программирования — это stateless-операции над аргументами функции. Когда мы добавляем внешний изменяемый state в качестве, например, базы данных, то теряется идемпотентность функций, и результат композиции становится непредсказуемым. Чтобы жестко зафиксировать последовательный порядок применений функций, требуется использовать специальную монаду IO, с которой программирование фактически становится императивным. Кроме того, результат вычисления функции — это уже не просто Response, а еще и измененный State. То есть красивая идеальная схема HttpResponse = WebApplication(HttpRequest) уже не работает, и проблема здесь будет не в getCustomerFromDatabase(), а в updateCustomerInDatabase().
    Поэтому для data-driven приложений функциональное программирование не лучший выбор.

  • Исправляем 7 распространенных ошибок обработки исключений в Java
    0
    Checked исключения — это вариант возвращаемого значения с приятным бонусом в виде неявного завершения блока кода, вместо проверок возвращаемого методом кода (результата) — ловишь исключение.

    И кто вам мешает делать то же самое с unckecked? Разница лишь в том, что вас не обязуют это делать непосредственно в вызывающем методе. Если хотите, unchecked эксепшны — это вариант возвращаемого значения с неявным завершением блока, добавляемый для всех методов по умолчанию. Но основное назначение эксепшнов — это именно раннее завершение блока, а вот как раз бонус — это возвращаемое значение. Кроме того, когда требуется именно возврат определенного осмысленного значения, лучше использовать монады типа Optional или Try — для эксепшнов осмысленное значение редко выходит за рамки типа эксепшна и сообщения со стектрейсом.


    А насчет заворачивания исключений многократно могу лишь сказать так: руки кривые и излишнее проектирование.

    То есть архитектурный леер должен выставлять наружу делати реализации? :) Для самостоятельного осмысления требуется расставить эксепшны в throws:


    interface ConfigReader {
      Properties readConfig() throws ???;
    }
    class SQLConfigReader implements ConfigReader {
      Properties readConfig() throws SQLException;
    }
    class FileConfigReader implements ConfigReader {
      Properties readConfig() throws IOException;
    }
    class URLConfigReader implements ConfigReader {
      Properties readConfig() throws MalFormedURLException, IOException;
    }

    Не каждый уровень бизнес-логики вообще требует какой-либо работы с исключениями.

    Справедливо. Однако Java Api просто пронизан checked-исключениями. То есть либо перехватывайте и обрабатывайте, либо перехватывайте и врапьте, либо извольте отписаться в throws. И если уж затронули тему Java Api, то почему MalformedURLException и ParseException checked, а NumberFormatException unchecked, хотя все они возникают при парсинге текста.


    Вот чего не хватает в Java, так это возможности сказать, что любые исключения в этом методе считать unchecked — как раз избавится от ручного управления списком throws.

    И это будет последним костылем перед тем, как полностью перейти к unchecked.


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

    class MyService {
      void init(ConfigReader configReader) {
        // configReader -- это интерфейс.
        // В какой конкретный класс смотреть компилятору,
        // чтобы определить, какие исключения тут могут быть выкинуты?
        configReader.readConfig();
      }
    }
  • Исправляем 7 распространенных ошибок обработки исключений в Java
    –1

    Throws приходится пробрасывать через весь стек методов. При движении снизу вверх количество эксепшнов в throws будет только расти. Ну и как правило верхним уровням абсолютно пофиг что за ошибка там возникла — у него как правило стоит один универсальный обработчик на все типы эксепшнов.


    Есть расхожий паттерн о том, что эксепшны низких уровней нужно заворачивать в собственные более внятные: например при чтении конфигурации SQLException или IOException завернуть в свой ConfigurationException. Это плохо, потому как затрудняет абстракциям верхнего уровня получить внятный доступ к причине (в каком из цепочки getCause() он лежит?). В случае же, когда этого не требуется и абстракции верхнего уровня абсолютно пофиг на тип эксепшна, нет никакого смысла в заворачивании.


    Checked должны быть эксепшны, связанные с бизнес-логикой: валидацией данных, некорректным состоянием, etc. Эксепшны, связанные с ресурсами должны быть только unchecked, и это ошибка дизайна Java API.

  • Исправляем 7 распространенных ошибок обработки исключений в Java
    0

    Ошибка одна — перехват исключений. В подавляющем большинстве случаев его в бизнес-коде вообще не должно быть. Практически всегда обработка исключений — это удел абстракций верхнего уровня, где как правило нет особой необходимости сильно различать тип эксепшна. К сожалению в Java checked exceptions обязуют перехватывать непосредственно в вызывающем методе, хотя практически всегда это не его ответственность. В частности в Java все исключения доступа к ресурсам checked: IOException, SQLException, JMSException, etc… Архитекторы посчитали, что вызывающий метод во что бы то ни стало просто обязан позаботиться о том, что если вдруг что-то пойдет не так. Реально же бизнес-код вообще не должен заботиться об ошибке доступа к ресурсам также как и не должен заботиться об InterruptedException или OutOfMemoryError — это должны компоненты верхнего уровня универсальным способом, например откатить транзакцию.

  • 7 правил хорошего тона при написании Unit-тестов
    0
    1. Третье правило настоящего джентльмена — следи за путями.

    Что за треш? Paths.get(".", "log", "service.log") позволит вам навсегда забыть о File.separator.

  • Почему я ненавижу Spring
    +2
    Большинство джунов не в состоянии не только написать такой, но и понять зачастую. Поэтому посты типа "я ненавижу..." следует читать с солидной долей скепсиса.

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

  • Обратная сторона Spring
    0

    На мой взгляд основная проблема спринга, превращающая его из фреймворка в книгу заклинаний, состоит в повсеместном использовании аннотаций. Аннотации в java были придуманы для определения метаданных в коде. Но строить на их основе некий расширяемый метаязык для определения контекста приложения — это вкорне неверная идея, аннотации для этого не приспособлены. Расставленные в коде аннотации сематнически никем не контролируются, кроме рантайма: @EnableWebMvc я могу вообще поставить на любой объект, не обязательно на @Configuration — никто меня не ограничит.
    Есть гораздо более удобные, правильные и открытые способы задания конфигурации контекста без аннотаций, например Guice.
    Спринг же пытается всю задачу замести под ковер, оставляя пользователю лишь набор заклинаний и рецептов для описания бизнес логики, которые нужно использовать в определенном порядке, иначе просто не взлетит. Это очень эффектно для демонстраций и презентаций, но в реальных проектах при попытке заглянуть под ковер и что-то там изменить всегда сопряжена с головной болью и геморроем.

  • Почему я ненавижу Spring
    +7
    1. огромное количество библиотек и реализаций. Попробуйте навелосипедить свой spring-security c каким-нибудь oauth собственнм сервером и клиентом.

    В большинстве случаев это не нужно. Как правило вы используете какую-то одну конкретную технологию и уже готовую библиотеку для нее. Spring же предлагает навороченный абстрактный леер, интеграцию сразу со всеми известными технологиями и толстую книгу рецептов как это все засандалить в ваше приложение. Причем зачастую многие проблемы уже решены на более низком уровне, например тот же Servlet уже содержит простые средства security.


    Альтернативу @Transactional с нетривиальнм двухфазным коммитом (например БД + Очередь в единой транзакции).

    Двухфазный коммит делает не Spring, а стороннияя библиотека-координатор, например Atomikos, Narayana, etc. Spring @Transactional делает лишь наивный автоматический прокси на коммит/роллбэк, который также легко сделать вручную при помощи java.lang.reflect.Proxy, AspectJ или ByteBuddy. В реальных проектах практически всегда требуется вручную контролировать сбои и взависимости от типа ошибки нужно помимо роллбека повторить транзакцию, реинициализировать ресурс, отрапортовать о сбое, собрать метрики… Вот вам и свой @Transactional. Кроме того есть мнение, что XA вообще не рекомендуется использовать...


    но опять же время на изучение и не меньшее время чтобы все это подружить между собой

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


    Представьте, что у вас ушел 1-2 ключевых разработчика, кто делал ваши велосипеды и потом найдите и пофиксите сложный баг.

    Ваши 1-2 разработчика писали когда-нибудь bean postprocessors? Скорей всего они намолотили кучу кривой прикладной магии ввиде специфических @Заклинаний. Разобраться почему не проксируется бин, кто его процессит и в какой последовательности и почему вдруг что-то перестало работать — никто не будет. Девелоперы как правило понавтыкают костылей, чтобы хоть как-то решить требуемую задачу.


    Куча проблем за вас решена

    И на ровном месте создана другая куча. Если все так просто — почему на SO Spring держится в топе? Как правило всегда есть более простое и элегантное решение каждой конкретной проблемы. Spring же пытается влезть без вазелина везде, где это только возможно, вцелом значительно усложняя архитектуру и упрощая лишь какие-то конкретные простые случаи использования. Кроме того, подобное упрощение имеет негативный эффект: куча кодеров, не понимая принципы работы, начинает копипейстить туториалы и SO, допуская архитектурные ошибки. И, столкнувшись с проблемами или с незнанием того, как что-то конкретное сделать на спринге, начинают грязно костылить.


    Сделать достаточно сложный проект на spring-boot для быстрого старта как прототип относительно несложно

    Сделать демку типа "хелло-ворлд" с кучей подключенных технологий. В реальном проекте требуется более полный контроль над кодом, где в итоге все плюсы ввиде средств автоматического бутстрапа превращаются в огромные минусы.

  • Рано закапывать Java
    +3

    Вобщем-то на Java ввиду особенностей языка как раз нельзя написать нормальный DSL. Лямбды немного улучшают ситуацию, но не сильно. В частности, проблемы возникают с описанием иерархической структуры и со ссылками на проперти (которые всегда будут не type-safe). Стандартрый способ — клепать билдеры, но с ними получается очень гормоздко. Поэтому практически всегда для описания структур используют сторонний язык типа XML.


    P.S. В Java 8 идентификатор _ объявлен как deprecated, а Java 9 вообще запрещает его использовать.

  • GitHub переходит на GraphQL
    0

    Те, кто юзают в бэкенде Java и Hibernate знают о такой вещи как JPA 2.1 Entity Graphs. Фактически это та же идея, что и GraphQL.

  • Как защищаться от атаки вируса-шифровальщика «WannaCry»
    +1

    У нас пострадали в основном крупные компании.
    http://www.elmundo.es/tecnologia/2017/05/12/59158a8ce5fdea194f8b4616.html


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

  • Выход Java 9 снова отложен
    +1
    Вы хотите сказать в том же IBM отдельно сидят люди, которые участвуют в JCP и отдельно те, кто пишет софт и причем первые не общаются со вторыми? Не проблема ли это IBM

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


    Поэтому еще год назад от них были призывы "если вы видите какие-то проблемы у вашей библиотеки/фреймворка при переходе на Jigsaw — напишите нам!".

    Это когда еще мало-мальски стабильной девятки не было? Есть очень много решений, базирующихся на classpath. SLF4J использует classpath для поиска бэкенда для логгинга и настроек. Чтобы это сработало в модульной среде, библиотека должна быть изменена концептуально. И все остальные библиотеки, использующие SLF4J, будут ждать, пока мейнтейнеры соизволят выпустить его модульную версию, а также модульную версию всех своих зависимостей. И так с каждыми библиотеками, фреймворками и тулзами для сборки, тестинга и, наконец, продуктами. Период перехода может затянуться лет на 5 или больше, и все это время придется поддерживать две версии. В итоге экосистема сплитанется на две — модульную и classpath-ную.


    А теперь главный вопрос: в чем реальный профит модульности?