Хочу описать свои наблюдения и впечатления о самом популярном языке серверного программирования для Enterprise под названием Java. Наблюдения и впечатления на сравнении и контрасте с “похожей” платформой .NET, с которой я очень хорошо знаком. Уверен, что ~год назад, когда будущее нового дотнета в очередной раз показалось мне чересчур туманным и мысль сменить технологический стек окончательно материализовалась в голове, данная статья оказалась бы очень полезной. Я постараюсь не вдаваться в мелкие технические/стилистические различия языков программирования, которые легко нагуглить, а предложу скорее взгляд сверху — на экосистему в целом. Итак, Java глазами матёрого дотнетчика с десятилетним стажем. Прошу под кат.

Disclaimer


Когда-то давно у меня уже возникали похожие мысли написать про интересные отличия Microsoft Sql Server / Oracle, в стиле “ух ты, нету типа bool”, “длинные транзакции это норма, серьезно?”, “как это нет авто-коммита в настройках по умолчанию” и т.д. Но внутренний перфекционист всё думал, что я еще “недостаточно долго и хорошо всё изучил”, “где-нибудь ошибусь”, “поспешишь людей насмешишь” и т.д. — всё откладывал на “попозже”, а потом все впечатления буквально смылись и писать стало нечего. Так что в этот раз я решил слишком долго не ждать, иначе писать снова может стать не о чем. Поэтому отдельная просьба указывать мне на неточности, если они присутствуют. А я в свою очередь постараюсь не вдаваться в банальности “как же неудобно писать без var” (уже дождались на днях Java 10), “extension methods отсутствуют” и прочие “type erasure” и "multiline-strings".
Итак, экосистема.

1. IDE и терминология


В .NET выбор очевиден — Visual Studio. Работа в студии идет с проектами (projects), которые сгруппированы в солюшн (последний то .sln, то .json, то снова .sln, не сильно важно). Всё достаточно просто.

В мире Java в качестве IDE внимания на данный момент заслуживают двое парней — это Intellij Idea и Eclipse. На “постсоветском пространстве” первая победила. У зарубежных авторов эклипс живее всех живых. Казалось бы, какая разница чем пользуешься, хоть блокнотом, но в этом месте сразу же возникает проблема в терминологии.

В Eclipse самый верхний уровень — workspace, который состоит из projects.
В Idea самый верхний уровень — project, который состоит из modules.

В какой терминологии общаться разработчикам, использующим разные IDE, неясно. Часто принято общаться в терминологии “сборщиков”. Так, в случае например maven, дистрибутив собирается из модулей (modules), которые сгруппированы в pom-нике.

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

Отдельно хочу отметить бины (Beans). В .Net никому не придет в голову вводить новые термины для обычных классов, зарегистрированных в контейнере. На многих проектах контейнеры вообще не используются, даже в 2018 году (да, на это больно смотреть, но я это наблюдал и ни раз). В мире Java наоборот — культ контейнера и часто принято общаться в терминах бинов.

2. Сборка проекта


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

В мире .Net как средство управления пакетами/зависимостями используется nuget, для сборки — msbuild.

В Java всё склеено в один инструмент (впрочем, здесь снова есть выбор — Maven или Gradle). К каждому существует куча плагинов. В кровавом интерпрайзе доминирует первый.

Есть очень удобные wrapper-ы над сборщиками, позволяющие просто взять и начать сборку (кто сталкивался с поиском нужных версий msbuild-а на разных машинах, меня поймёт).

Дотнет сейчас тоже пытается двигаться в эту же сторону (привет, Cake).

3. Прикладные фреймворки


Здесь абсолютное доминирование Java-платформы. Есть два основных монстра: EJB и Spring с огромнейшей экосистемой и практиками “вокруг”. Доминирует второй. Со временем он тоже стал большим и сложным, поэтому даже придумали фреймворк для фреймворка — Spring Boot. Который, хочу отдать должное, действительно сильно облегчает жизнь.

В .Net ничего этого нет. Зато есть изобретение велосипедов “в каждом проекте по-своему”. Вплоть до выбора нужного DI/IoC-контейнера на вкус разработчика (если разработчик вообще в курсе про существование контейнеров) и решение как управлять транзакциями (если разработчик опять же знает, что такое транзакции и кто-то догадался отключить автокоммит на Sql Server-е). Разве что ASP.NET MVC немного похож на Spring MVC (который лишь малая часть Spring Framework).

4. Сервер приложений


И был IIS един и монолитен. И поняли Микрософт, что System.Web это плохо. И придумали OWIN. Впрочем, адекватные альтернативы IIS под Windows от этого не появились (да я знаю про Kestrel для .Net Core).

В Java выбор огромный, есть Servlet API, или новенький Reactive Streams(привет .Net Async Controllers) и множество реализаций, из которых Tomcat одна из самых популярных “коробочных”.

5. Community


Java Community Process и этим всё сказано. Формальный процесс, в котором заинтересованные лица могут участвовать в обсуждении и формировании новых версий платформы.

Только спустя 15 лет в Микрософт поняли, что это хорошо и пора перестать диктовать миру “как правильно жить” (помните ныне расформированный Microsoft Patterns and Practices group?) и придумал аналог — .NET Foundation.

6. Работа с БД


Это до сих пор не до конца понятный для меня момент, почему люди продолжают использовать JPQL в 2018 году. Единственное объяснение, которое я нашел, состоит в том, что типизированная Criteria — ужасна и многословна.

Это одно из немногих мест, где дотнетчикам повезло больше, т.к. 99% запросов к БД в .NET пишутся на типизированном Compile-time LINQ.

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

7. XML hell


До сих пор популярно заблуждение, что java — это тонны xml когда. Но на текущем этапе развития экосистемы это совсем не так. Скорее даже наоборот! Я могу написать web-приложение на Java без единой строчки xml (привет Spring Boot), и не могу это сделать на .Net (привет web.config, который “по сути” тот же web.xml, только еще и перемешанный с конфигом).

Выводы


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

P.S.: На КПДВ — старое, но еще смешное видео.

Комментарии (194)


  1. Szer
    30.03.2018 09:40
    +1

    и не могу это сделать на .Net (привет web.config, который “по сути” тот же web.xml, только еще и перемешанный с конфигом).

    Я вот пишу облачные микросервисы в Azure (serverless и webapp) и чот мне ни разу не потребовалось включать web.config в проект. Всё можно из кода настроить. Пишу под netcoreapp2.0
    Максимум для удобства быстрой настройки логирования или параметров приложения вообще (connection strings) подключается app.config (который JSON)


    1. Enrey Автор
      30.03.2018 10:30

      Спасибо за комментарий. Сфокусированность микрософта на своем личном облаке это одна из вещей, которая меня очень настораживает в. net core и почему я не очень верю в его будущее (по крайней мере в российских реалиях). Весь кровавый интерпрайз попытались оставить в старом заброшенном .net 4.6+ и всё переписать заново в core где сегодня csproj (xml), завтра json (который project) а потом опять xml (решили все-таки не выкидывать msbuild), зато в entity framework core банально уже n лет нет lazy loading (т. е. оно не Enterprise ready). Для облаков и микросервисов в них .net core возможно действительно вполне себе ок.


      1. raptor
        30.03.2018 13:03

        В версии 2.1 уже есть.


        1. Free_ze
          30.03.2018 13:11

          нет lazy loading (т. е. оно не Enterprise ready)
          ибо
          This release is still in preview.


        1. Enrey Автор
          30.03.2018 22:34

          Выше уже ответили что еще не зарелизилось.
          А как насчет many-to-many отношений?


          1. Free_ze
            31.03.2018 00:56

            А как насчет many-to-many отношений?

            Так ли велика эта проблема?


            1. Enrey Автор
              31.03.2018 14:12

              Заставляет плодить новые сущности там где они не нужны.


              1. Free_ze
                31.03.2018 14:26
                -1

                Почему же не нужны? Связная сущность отражает структуру базы данных. К костылям или какому-то неочевидному ужасу в коде не приводит. А уж что лучше: явность или неявность — это дискуссионный вопрос.


      1. yarosroman
        30.03.2018 15:51

        Естественно, они этим зарабатывают. Но .Net Core и Azure никак не связаны. Core реально кроссплатформенно (не зря они сделали Linux Subsystem в Win10). А еще поддержка Docker из коробки. Да с EF Core есть проблемы, но учитывая, что он написан с нуля, он взрослеет с каждым релизом. Ну и с выпуском .Net Core платформа переродилась. О ней говорят и пишут больше.


        1. Free_ze
          30.03.2018 15:53

          Core реально кроссплатформенно (не зря они сделали Linux Subsystem в Win10).

          Как связаны .NET Core и WSL?


          1. yarosroman
            30.03.2018 16:06

            Возможность тестировать и писать .net core приложения сразу в Linux. Сразу после анонса WSL появилось много статей как настроить .net core и VS Code в WSL


            1. Free_ze
              30.03.2018 16:26

              Возможность тестировать и писать .net core приложения сразу в Linux.
              Вы же про нативный докер и прочие специфичные инструменты, которые нормально работают только в Linux-окружении? Иначе разрабатывать кроссплатформенное приложение, используя WSL в качестве референса целевой платформы — это выглядит немного странно, как по мне.


              1. yarosroman
                30.03.2018 16:32

                Целевая платформа всё-таки это Linux. Я считаю возможность разработки в WSL одной из причин появления последней.


      1. yarosroman
        30.03.2018 15:57

        Да и выбор типа проекта был на стадии RC, с релиза 1.0 тип проекта не менялся.


      1. Bonart
        31.03.2018 01:10

        LazyLoading скорее вреден чем бесполезен и очень хорошо там, где его нет.


    1. IvanNochnoy
      01.04.2018 13:03

      Более того, в ASP.NET Core web.config вообще отсутствует (он генерится только при публикации)


      Существуют следующие поставщики конфигурации:


      • Форматы файлов (INI, JSON и XML).
      • аргументы командной строки.
      • Переменные среды.
      • Объекты .NET в памяти.
      • Незашифрованное хранилище Secret Manager (Диспетчер секретов).
      • Зашифрованное пользовательское хранилище, например Azure Key Vault.
      • Пользовательские поставщики (установленные или созданные).


  1. zodchiy
    30.03.2018 10:26

    Сразу скажу, что отношусь к java и java-сообществу, как собратам .net.

    И был IIS един и монолитен… да я знаю про Kestrel для .Net Core

    Над Kestrel можно и Nginx или IIS в качестве прокси.

    Я могу написать web-приложение на Java без единой строчки xml и не могу это сделать на .Net

    netcore?
    Вот весь xml, который был автосгенерён. Больше трогать его не надо.
    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <system.webServer>
        <handlers>
          <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
        </handlers>
        <aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false" />
      </system.webServer>
    </configuration>


    Есть два основных монстра: EJB и Spring с огромнейшей экосистемой и практиками “вокруг”. В .Net ничего этого нет. Вплоть до выбора нужного DI/IoC-контейнера на вкус разработчика

    Очень сомнительный минус, и очень сомнительный плюс.


    1. Enrey Автор
      30.03.2018 22:36

      Вся ирония в том, что некоторое время назад все.нетчики подкалывали джавистов про «программирование на xml». А сейчас этот самый xml остался, как необходимость, как раз в .Net.


      1. Bonart
        31.03.2018 01:12

        Я программирую в .net и не имею необходимости использовать xml.
        Что я делаю не так?


    1. IvanNochnoy
      01.04.2018 14:05

      Впрочем, адекватные альтернативы IIS под Windows от этого не появились (да я знаю про Kestrel для .Net Core)

      Зато появилась альтернатива Java под Linux.
      Размещение в Linux с использованием Nginx
      Размещение в Linux с использованием Apache


  1. olegchir
    30.03.2018 10:39

    Кстати, в Visual Studio файлы проектов уже можно писать с нуля руками, как это делается с Maven/Gradle, или там всё ещё чёртов ад, править который без гуя рука не поднимется?


    1. Szer
      30.03.2018 10:49

      Кстати, в Visual Studio файлы проектов уже можно писать с нуля руками

      Уж пару лет как. Не уверен за самую раннюю версию msbuild, которая может понимать сокращённый *.csproj, но чтобы написать webapp какой-нибудь достаточно пару строчек.


      1. Enrey Автор
        30.03.2018 22:37

        И новые PackageReference руками добавляете?


        1. Szer
          31.03.2018 00:52

          И новые PackageReference руками добавляете?

          Ну я вас умоляю, мы ж не в каменном веке. Package Manager'ы же есть.


          1. Enrey Автор
            31.03.2018 13:55

            Причем здесь каменный век, в Java тоже есть пакетные менеджеры и появились они гораздо раньше чем возник тот же nuget. Но вот принято референсы прям в pom.xml руками прописывать. Вопрос привычки и удобства. Поначалу выглядит странновато, но по факту на самом деле оказывается удобней чем отдельный CLI.


            1. Szer
              31.03.2018 14:10

              В .Net есть варианты (перечислю самые, на мой взгляд, популярные):


              • Отличный GUI в Rider/Visual Studio (и частично через Command Palette в VS Code)
              • dotnet CLI (dotnet add package Newtonsoft.Json)
              • Ручками в csproj (нет подсказок по именам/версиям)
              • Nuget Package Manager (CLI / package.config, который ужасен)
              • Paket (CLI / paket.dependencies, который прекрасен + есть lock файл с транзитивными зависимостями)


              1. IvanNochnoy
                01.04.2018 14:15

                MSBuild project file tools
                An extension for VS Code that provides intellisense for MSBuild project files, including auto-complete for PackageReference elements.


            1. IvanNochnoy
              01.04.2018 09:12

              Еще есть расширение для VS Code vscode-nuget-package-manager с автоподсказками


        1. Bonart
          31.03.2018 01:13
          +1

          Еще ни разу «матерый дотнетчик с десятилетним стажем» не был так близок к провалу.


          1. Enrey Автор
            31.03.2018 13:47

            Вы слишком токсичны. Но я плюсанул, радуйтесь.


        1. more_cry
          31.03.2018 13:47

          Не поверите, но через CLI, ведь nuget-manager включен в cli tools у dotnetcore:

          dotnet add package Newtonsoft.Json

          Так же есть выбор добавить через GUI от разных IDE: VSC, Rider, VS.


  1. antonarhipov
    30.03.2018 11:13

    Есть два основных монстра: EJB и Spring с огромнейшей экосистемой и практиками “вокруг”.


    EJB — это не фреймворк. Может быть автор хотел сказать Java EE (Jakarta EE). EJB — это всего лишь одна из спек Java EE


    1. Enrey Автор
      30.03.2018 11:40

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

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

      Но концептуально вы правы, наиболее корректно использовать JEE Server (именно эту бирку «лепят» (или лепили?) себе всякие jboss-ы). Или уже правильно Jakarta Server? :)


      1. DSolodukhin
        30.03.2018 11:59

        JEE Server означает, что у данного продукта есть сертификация реализации Java EE. Например, тот же Wildfly имеет сертификацию по Java EE 7, но не имеет по Java EE 8.
        С Jakarta пока не понятно, в каком виде будет сертификация и будет ли вообще.


        1. iZENfire
          31.03.2018 16:01

          Эталонная реализация Java EE 8 — GlassFish 5.0.


  1. maxzh83
    30.03.2018 11:35

    Всем, кто переходит с VisualStudio, советую только IDEA. Когда переходил (очень давно), думал что умнее студии ничего нет, но IDEA приятно удивила и продолжает удивлять до сих пор. И ReSharper от тех же JetBrains, которые делает студию умнее и удобнее, тому подтверждение.


  1. Free_ze
    30.03.2018 11:47
    +2

    В .NET выбор очевиден — Visual Studio.
    Как же Rider?


    1. Makc_K
      30.03.2018 14:29

      Отсутствует бесплатная версия, аналогичная VS Community


      1. Free_ze
        30.03.2018 14:44

        Это имеет мало значения, если большинство компаний и так покупает платную студию, да еще и решарпер. Idea с поддержкой всякого EE тоже стоит денег, если сравнивать. Тем более, что это единственное адекватное решение для .NET-разработки из *nix.
        Для Rider есть достаточно милая инди-лицензия, позволяющая разрабатывать на ней хоть лично для себя, хоть чужой лютый интерпрайз (проблемы совместимости я обнаружил только для некоторых T4-шаблонов, но это специфика).


      1. Bonart
        31.03.2018 01:33

        Это только до тех пор, пока не покупается решарпер.


    1. Enrey Автор
      30.03.2018 22:44

      Скорее всего схвачу минусов (на хабре культ Jetbrains), но это хайп. Да еще и платный.
      Я года 3-4 работал с VS Community и ни одной мысли о Pro не возникало — хватало всего что есть. А в Idea Community со спрингом нормально работать невозможно — сделано всё чтобы люди платили деньги.


      1. Free_ze
        31.03.2018 00:42

        Я года 3-4 работал с VS Community и ни одной мысли о Pro не возникало — хватало всего что есть.
        Вы/организация точно не нарушали Community-лицензию при этом? Ведь при желании можно и райдер «покрякать» и считать бесплатным.
        А решарпер (который всего на $10 дешевле райдера) вы тоже принципиально не используете?

        сделано всё чтобы люди платили деньги.
        Вы так говорите, будто это что-то плохое. Коммерческая фирма делает качественные инструменты и просит за это деньги! То ли дело MS, которая выпускает эсклюзивную Visual Studio для своей платной операционной системы!


        1. Enrey Автор
          31.03.2018 14:01
          -1

          Не нарушал я ничего, речь идет о домашнем компьютере и pet-проектах. Visual Studio Community хватает «на всё что угодно» (в отличие от ужасающей Express которая была ранее давно). А вот в IDEA Community жадинки отрезали использование спринга с бутом, что отвратительно и неприятно.


          1. Free_ze
            31.03.2018 14:31

            Не нарушал я ничего, речь идет о домашнем компьютере и pet-проектах.
            Там может каждый делать то, что ему вздумается. Я все же про прямое назнчение инструментов — интерпрайз. MS молодцы, конечно, но у них такие меры — не от лучшей жизни.
            Вопрос про решарпер все так же актуален.

            А вот в IDEA Community жадинки отрезали использование спринга с бутом
            Вам maven там тоже отрезали?)


          1. Bonart
            31.03.2018 16:06

            Что же это за контейнер такой, которым без специальной поддержки от IDE пользоваться отвратительно и неприятно?


          1. iZENfire
            31.03.2018 16:08

            Почему-то все забыли про NetBeans IDE. А в ней достаточно инструментария для создания Java9 и Java EE 7- приложений, которые можно тут же в среде тестировать в GlassFish 5.x и WildFly 12, собирать метрики и протоколы обмена (http-monitor), а maven является родным форматом организации проектов на Java. Интегрированы Git и Mercurial-плагины (используют внешние git и hg) для прозрачного сохранения изменений в коде — можно буквально щелчком мыши откатиться на определённый коммит в истории изменений.


          1. solver
            31.03.2018 18:30

            Что именно там отрезали от сприг бута?
            Почему тогда у меня проекты на спринг буте прекрасно работают в IDEA Community?


        1. vlanko
          31.03.2018 22:50

          Почитал лицензию. А что трактуется под «одновременным использованием»?


        1. IvanNochnoy
          01.04.2018 15:01

          То ли дело MS, которая выпускает эсклюзивную Visual Studio для своей платной операционной системы!

          Это утверждение ложно. В VS можно делать приложения для Android, Linux, iOS, Windows. Что касается "платной операционной системы", то JetBrains Rider для индивидуалов без решарпера стоит 139$ в год пруфлинк + Linux = 7 942 рубля, Windows 10 Home стоит 5 500 руб пруфлинк + Visual Studio Community = 5 500 руб


          Напомню, что разница между VS про и коммюнити только в отсутствии CodeLens в последней и лицензией для инди либо опенсоурс разработок.


          Итого по гамбурскому счету разница в пользу МС — 2 500 руб.


          Цифры не лгут.


          1. Free_ze
            01.04.2018 15:13

            Это утверждение ложно
            Внезапно. Под Linux тоже версия данной IDE есть?

            JetBrains Rider для индивидуалов без решарпера стоит 139$ в год пруфлинк + Linux = 7 942 рубля, Windows 10 Home стоит 5 500 руб пруфлинк + Visual Studio Community = 5 500 руб
            … и еще решарпер сверху за $129 (=


            1. IvanNochnoy
              01.04.2018 15:50

              Линукс не нужен. Шучу. МС с удовольствием сделали бы версию под Линукс, но пока не могут — слишком долго портировать такого монстра. С другой стороны, судя по темпам развития, энтузиазму контрибюторов и по опросу StackOverflow VS Code, уже обогнал всех и вышел на первое место, так что для Линукcа он может стать основным продуктом из семейства Visual Studio. Аминь.


              1. Free_ze
                01.04.2018 16:24

                МС с удовольствием сделали бы версию под Линукс, но пока не могут — слишком долго портировать такого монстра.

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

                он может стать основным продуктом из семейства Visual Studio

                Но он не станет Visual Studio (= Начало конца уже положено в его технологических основах.


              1. PsyHaSTe
                01.04.2018 19:15

                VS Code к VS имеет такое же отношение, как слово «котлета» к «коту». Не позволяйте бренду смысл затмевать, а то так еще можно случайно сказануть, что есть студия на мак.


          1. solver
            02.04.2018 11:09

            Цифры действительно не лгут. А вот люди их применяющие их, вполне могут…


  1. talbot
    30.03.2018 12:21

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


    В защиту jOOQ'а скажу, что во всю используем в продакшене энтерпрайза: гораздо очевиднее, чем JPQL/Criteria Builder, а в сочетании с правильной готовкой миграций даёт управляемую работу с БД. Почему-то JPQL/Criteria Builder считают, что разработчики не могут в SQL, поэтому предлагают навернуть абстракций там, где можно обойтись понятным и проверяем (во время компиляции) кодом.


    1. StanislavL
      30.03.2018 13:58

      Есть вариант с iBatis/MyBatis для любителей SQL. И Spring Data для сильно нелюбящих. Довольно много в последнем запросов можно просто сделать названием методов.


      1. talbot
        30.03.2018 15:59

        И Spring Data для сильно нелюбящих. Довольно много в последнем запросов можно просто сделать названием методов.

        Можно, но в какой-то момент начинаешь очень сильно предпочитать явное неявному.


  1. Naglec
    30.03.2018 12:54

    На многих проектах контейнеры вообще не используются, даже в 2018 году (да, на это больно смотреть, но я это наблюдал и ни раз).


    Контейнеры головного мозга


    1. Enrey Автор
      30.03.2018 22:28

      По моему опыту отсутствие контейнеров в .net — это говнокод в 90% случаев. Статистика. :)


      1. Bonart
        31.03.2018 01:17

        Говнокод — это не отсутствие контейнеров, а неосиливание DI.
        Карго-культ контейнера от этого не спасает.


  1. alz72
    30.03.2018 13:25

    Я бы рекомендовал поближе присмотреться к .Net Core, лично мне кажется C# куда как продуктивнее Java. Да и тенденции в мире также смотрят в сторону .Net ...


    1. maxzh83
      30.03.2018 13:46

      Да и тенденции в мире также смотрят в сторону .Net ...

      Это какие например?


    1. bromzh
      30.03.2018 15:23
      +1

      C# куда как продуктивнее Java.

      А что под этим подразумевается, можно поподробнее?


      1. Bonart
        31.03.2018 01:20

        Нормальные генерики (существующие и в рантайме), непримитивные типы-значения, много меньший объем синтаксического словоблудия, LINQ.


        1. Enrey Автор
          31.03.2018 14:08

          Ни одно из слов к продуктивности не имеет отношения.


          1. lair
            31.03.2018 14:29
            +2

            … к продуктивности программиста? Я не соглашусь, дженерики сильно на это влияют, expression trees — тоже.


            1. Enrey Автор
              01.04.2018 09:29

              Можете мне привести пример частого использования expression trees в кровавом энтерпрайзе? Мне действительно интересно.
              Последний раз я их ковырял когда правил форк от ORM и больше «с ходу» не припомню необходимости.

              Про дженерики тоже холиварный вопрос, в джаве они есть, причем с неплохой ковариантностью-контрвариантностью из коробки, ala
              List<? extends A> myList1
              List<? super B> myList2
              Ну да, type erasure. Сейчас минусаторы набегут, но в большинстве повседневных задачах он не мешает.

              Мы же про продуктивность? Почему не вспоминаем про тот же Lombok
              @NonNull
              @AllArgsConstructor
              @ToString
              @EqualsAndHashCode
              Getter/@Setter

              Вот это про продуктивность. И никакого бойлерплейта.
              В дотнете такое возможно огромными костылями ala Postsharp (который почти загнулся из-за платности / заметно возрастающего времени компиляции), ну или Fody (который тоже не оч.популярен). Появилось ли что-то похожее в .Core?


              1. asm0dey
                01.04.2018 10:03

                Не, это не про продуктивность. Про продуктивность в Java — Kotlin :) И его я тоже больше 2х лет использую в продакшне в энтерпрайзе. Там все эти костыли не нужны.


              1. Free_ze
                01.04.2018 11:08

                Можете мне привести пример частого использования expression trees в кровавом энтерпрайзе?
                Составление фильтров.


              1. lair
                01.04.2018 11:47
                +1

                Можете мне привести пример частого использования expression trees в кровавом энтерпрайзе?

                LINQ, AutoMapper, FluentAssertions. Мы вот у себя только что маленький внутренний движок критериев на expression tree сделали.


                Почему не вспоминаем про тот же Lombok

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


                1. Enrey Автор
                  01.04.2018 15:25
                  -1

                  Разве что LINQ принимается :)
                  Да и-то в качестве «запросов к БД» или куда-либо ещё.
                  Что автомаппер что FluentAssertions, что Linq2Objects на простых лямдах достаточно нормально отжимаются.


                  1. lair
                    01.04.2018 15:27

                    Разве что LINQ принимается

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


                    Что автомаппер что FluentAssertions, что Linq2Objects на простых лямдах достаточно нормально отжимаются.

                    И как вы из простой лямбды получите описание провалившегося assertion?


              1. lair
                01.04.2018 11:52
                +1

                Почему не вспоминаем про тот же Lombok
                Getter/@Setter

                … так в C# это не нужно уже черт знает сколько, auto properties же.


                @NonNull

                С nullability планируют расправляться намного более системно.


                1. Enrey Автор
                  01.04.2018 15:23

                  Ну не черт сколько, возможность на авто-пропертях делать readonly setter появилась достаточно недавненько.

                  Плюс если вспомнить любимого Рихтера, то он ненавидит проперти со времен первого издания своей книги про CLR и говорит что стоит явно писать методы, которые не несут «многозначности то-ли переменная то ли метод» :D
                  Но это я уже подтроливаю немножко, да. Еще Рихтер везде sealed рекомендовал, помнится.


                  1. lair
                    01.04.2018 15:26

                    Ну не черт сколько, возможность на авто-пропертях делать readonly setter появилась достаточно недавненько.

                    Ну так никто все сразу и не обещал.


                    Плюс если вспомнить любимого Рихтера, то он ненавидит проперти со времен первого издания своей книги про CLR

                    Это вопрос вкуса.


              1. IvanNochnoy
                01.04.2018 21:33

                Появилось ли что-то похожее в .Core?

                /// Example of a simple immutable record 
                type FinalGameScore = 
                    /// Game property
                    Game: string
                    /// FinalScore property
                    FinalScore: int
                
                


                Появилось… 13 лет назад… F# называется… Здесь вам и ToString и NotNull и Equals и HashCode и Serializable уже реализовано. Только, судя по популярности F#, это нафик не нужно никому… Энтерпрайз же, там люди серьёзные. Решарпером генерим.

                Касаемо мейнстрима — общают Records завести в С#. Status: InProgress.
                А пока вот аналогичный код на C#
                /// <summary>
                ///  Example of a simple immutable record 
                /// </summary>
                [Serializable]
                public sealed class FinalGameScore :
                    IEquatable<FinalGameScore>,
                    IStructuralEquatable,
                    IComparable<FinalGameScore>,
                    IComparable,
                    IStructuralComparable
                {
                    internal string _Game;
                    internal int _FinalScore;
                    
                    /// <summary>
                    /// Game property
                    /// </summary>
                    public string Game get => _Game;
                
                    /// <summary>
                    /// FinalScore property
                    /// </summary>
                    public int FinalScore get  =>_FinalScore;
                     
                    /// <summary>
                    /// Constructor 
                    /// </summary>
                    public FinalGameScore(string game, int finalScore)
                    {
                        this._Game = game;
                        this._FinalScore = finalScore;
                    }
                
                    /// <summary>
                    ///  Needed for custom equality
                    /// </summary>
                    public int GetHashCode(IEqualityComparer comp)
                    {
                        if (this != null)
                        {
                            int num = 0;
                            int offset = -1640531527;
                            num = offset + (this._FinalScore + ((num << 6) + (num >> 2)));
                            string _game = this._Game;
                            return offset + (((_game == null) ? 0 : _game.GetHashCode()) + ((num << 6) + (num >> 2)));
                        }
                        return 0;
                    }
                
                    /// <summary>
                    ///  Needed for custom equality
                    /// </summary>
                    public sealed override int GetHashCode()
                    {
                        return this.GetHashCode(LanguagePrimitives.GenericEqualityComparer);
                    }
                
                    /// <summary>
                    ///  Implement custom equality
                    /// </summary>
                    public bool Equals(object obj, IEqualityComparer comp)
                    {
                        if (this == null)
                        {
                            return obj == null;
                        }
                        FinalGameScore finalGameScore = obj as FinalGameScore;
                        if (finalGameScore != null)
                        {
                            FinalGameScore finalGameScore2 = finalGameScore;
                            return string.Equals(this._Game, finalGameScore2._Game)
                                && this._FinalScore == finalGameScore2._FinalScore;
                        }
                        return false;
                    }
                
                    /// <summary>
                    ///  Implement custom equality
                    /// </summary>
                    public bool Equals(FinalGameScore obj)
                    {
                        if (this != null)
                        {
                            return obj != null
                                && string.Equals(this._Game, obj._Game)
                                && this._FinalScore == obj._FinalScore;
                        }
                        return obj == null;
                    }
                
                    /// <summary>
                    ///  Implement custom equality
                    /// </summary>
                    public sealed override bool Equals(object obj)
                    {
                        FinalGameScore finalGameScore = obj as FinalGameScore;
                        return finalGameScore != null && this.Equals(finalGameScore);
                    }
                
                    /// <summary>
                    ///  Implement custom comparison
                    /// </summary>
                    public int CompareTo(FinalGameScore obj)
                    {
                        if (this != null)
                        {
                            if (obj == null)
                            {
                                return 1;
                            }
                
                            int num = string.CompareOrdinal(this._Game, obj._Game);
                            if (num < 0)
                            {
                                return num;
                            }
                            if (num > 0)
                            {
                                return num;
                            }
                
                            int _finalScore = this._FinalScore;
                            int _finalScore2 = obj._FinalScore;
                            if (_finalScore < _finalScore2)
                            {
                                return -1;
                            }
                
                            return (_finalScore > _finalScore2) ? 1 : 0;
                        }
                        else
                        {
                            if (obj != null)
                            {
                                return -1;
                            }
                            return 0;
                        }
                    }
                
                    /// <summary>
                    ///  Implement custom comparison
                    /// </summary>
                    public int CompareTo(object obj)
                    {
                        return this.CompareTo((FinalGameScore)obj);
                    }
                
                    /// <summary>
                    ///  Implement custom comparison
                    /// </summary>
                    public int CompareTo(object obj, IComparer comp)
                    {
                        FinalGameScore finalGameScore = (FinalGameScore)obj;
                        FinalGameScore finalGameScore2 = finalGameScore;
                        if (this != null)
                        {
                            if ((FinalGameScore)obj == null)
                            {
                                return 1;
                            }
                            int num = string.CompareOrdinal(this._Game, finalGameScore2._Game);
                            if (num < 0)
                            {
                                return num;
                            }
                            if (num > 0)
                            {
                                return num;
                            }
                            int _finalScore = this._FinalScore;
                            int _finalScore2 = finalGameScore2._FinalScore;
                            if (_finalScore < _finalScore2)
                            {
                                return -1;
                            }
                            return (_finalScore > _finalScore2) ? 1 : 0;
                        }
                        else
                        {
                            if ((FinalGameScore)obj != null)
                            {
                                return -1;
                            }
                            return 0;
                        }
                    }
                
                }
                


                1. Enrey Автор
                  01.04.2018 21:47

                  Хоспадя, причем здесь F#


                  1. IvanNochnoy
                    01.04.2018 22:06
                    +1

                    Появилось ли что-то похожее в .Core?

                    Вы задали вопрос про .NET Core, а не про С#, так ведь?


                  1. Bonart
                    01.04.2018 22:07

                    Что характерно, вопросов, причем тут котлин, не возникало.


                  1. Szer
                    01.04.2018 22:45

                    Хоспадя, причем здесь F#

                    Я сам из тех, которые на F# лепят.
                    Он очень даже при том.


                    Получаете кучу бонусов в языке, синтаксисе, системе типов, но теряете немного в IDE (Visual Studio днищенски поддерживает F#, VS Code — норм, Rider EAP 2018.1 уже тоже норм), в тулах (нет ничего подобного R#, но учитывая что язык гораздо менее бойлерплейтный и защищает от ошибок намного сильнее, надобность уже не та. Так же нет нормальных декомпиляторов, если dotPeek'ом тыкаться, получаем бесплатную обфускацию)


                    А главное dll те же, dotnet xxx.dll всё так же работает, поэтому хоть в Azure, хоть в AWS Lambda заливается абсолютно одинаково.
                    Ну и если чо, компилятор и темплейты проектов F# в .NetCore SDK уже встроены.


                    Поэтому встречный вопрос:
                    А почему не F#?


              1. PsyHaSTe
                01.04.2018 21:47

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


              1. Bonart
                01.04.2018 22:04
                +1

                Почему не вспоминаем про тот же Lombok

                Потому что инструменты с вплетением байт-кода есть и для дотнета: от Fody до PostSharp.
                Для NotNull в дотнете хватает системы типов (благодаря тем самым, не имеющим отношения к вашей личной продуктивности, генерикам и структурам): я, например, просто могу писать NotNull<T> и это будет та же самая ссылка на класс без оверхеда, но с гарантией, что null там нет.


                с неплохой ковариантностью-контрвариантностью из коробки

                Согласно Джону Скиту, это единственное преимущество языка Java над C#.


                в большинстве повседневных задачах он не мешает

                Ну да, конечно. Если я в параметре конструктора укажу IEnumerable<TypeName>, то дотнетные контейнеры автоматически подставят мне все зарегистрированные реализации для TypeName.
                В яве это не сработает по построению. Именно поэтому явовские контейнеры на фоне дотнетных смотрятся убого.
                Если потребуется оптимизация по аллокации памяти в куче, в яве придется делать специальные алгоритмы с использованием только примитивных типов.


                Getter/@Setter

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


                1. fRoStBiT
                  02.04.2018 06:35

                  Вообще-то сработает, как минимум в Spring с этим проблем нет и это используется.
                  А работает это потому, что несмотря на type erasure, информация о типах вполне себе доступна в runtime, через reflection.


    1. Enrey Автор
      30.03.2018 22:49

      .Net Core это попытка выкинуть платформу, разрабатываемую 15 последних лет и переписать/переосмыслить всё заново. Насколько эта идея может быть успешна в нынешних реалиях, покажет только время.
      Но то что большинство текущих проектов на .NET (не Core) внезапно стало Legacy — это факт.


      1. alz72
        31.03.2018 00:36

        .NET (не Core) достаточно легко переходит в .Net Core, в обратную тоже может, но уже труднее — хотя с каждой новой версией это все проще...


  1. perfectdaemon
    30.03.2018 13:28

    Ох, какая холиварная пятничная статья :)

    В .Net ничего этого нет. Зато есть изобретение велосипедов “в каждом проекте по-своему”. Вплоть до выбора нужного DI/IoC-контейнера на вкус разработчика (если разработчик вообще в курсе про существование контейнеров) и решение как управлять транзакциями (если разработчик опять же знает, что такое транзакции и кто-то догадался отключить автокоммит на Sql Server-е). Разве что ASP.NET MVC немного похож на Spring MVC (который лишь малая часть Spring Framework).

    .Net Core принес встроенный DI, который покрывает 95% нужд. И что вообще плохого в выборе DI/IoC-контейнера самостоятельно из существующих? Лучше иметь одну прибитую гвоздями реализацию?

    Про транзакции немного не понял, их управление строится через конфигурацию ORM, как и в мире Java. Или речь о распределенных?

    Опять-таки .Net Core предлагает многое, из того, что есть в Spring Framework (если, конечно, описание его состава на википедии не врет). Не все, но многое. Остальные вещи можно найти, установить и «подружить».

    И был IIS един и монолитен. И поняли Микрософт, что System.Web это плохо. И придумали OWIN.

    OWIN дал возможность более гибко и прозрачно конфигурировать пайплайн http-запроса через middleware.

    В общем, на вкус и цвет — фломастеры разные.


    1. Enrey Автор
      30.03.2018 22:57

      Наконец-то принес, спустя 15 лет. Минусов «выбора» масса — в одном проекте Unity, в другом — Autofac, в третьем StructureMap, а в четвертом NInject — и все они различаются в API и при этом одинаковые на 95%. Здесь огромный плюс джавовских JSR виден, надеюсь, всем.

      Транзакции — скорее про аннотацию @Transactional.

      OWIN еще и Embended Server дает. Еще немного, и Микрософт придумают свой H2 (или уже придумали?).


      1. Free_ze
        31.03.2018 00:50

        в одном проекте Unity, в другом — Autofac, в третьем StructureMap, а в четвертом NInject — и все они различаются в API и при этом одинаковые на 95%. Здесь огромный плюс джавовских JSR виден, надеюсь, всем.

        В том же ASP.NET MVC адаптируются в IDependencyResolver.


        1. Szer
          31.03.2018 00:56

          В том же ASP.NET MVC адаптируются в IDependencyResolver.

          Опускаясь на уровень этого интерфейса все эти контейнеры полностью теряют уникальные фичи (Ninject — auto discovery, SimpleNinject — проверку на собираемость и т.д.) что делает наличие такого большого кол-ва реализации контейнеров бессмысленным.


          1. Free_ze
            31.03.2018 01:00

            А джавовые стандарты этой проблемы лишены?


          1. lair
            31.03.2018 12:03
            +1

            Не теряют. Этот интерфейс — он для потребителя, вам ничто не мешает использовать уникальные фичи в composition root. Более того, скажем, у Autofac есть всякие милые штуки типа Func<T> и Lazy<T>, которые и на стороне потребителя видны.


      1. Bonart
        31.03.2018 01:27

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


        1. Enrey Автор
          31.03.2018 14:20

          Composition Root оно называется и подобным образом на русский язык не переводится.
          Точка сборки — это к Кастанеде Карлосу ;)

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


  1. StanislavL
    30.03.2018 14:01

    Для сборок еще кое где встречается старый добрый ant.


    1. Enrey Автор
      30.03.2018 22:57

      К счастью не застал :)


  1. JavaFox
    30.03.2018 14:28

    Вставлю и я свои 5 копеек. Всю жизнь был .NET developer, иногда хотелось поработать с Java, узнать как там и у них и перейдя в новую фирму стал больше Java Developer чем .NET. Что сразу бросилось в глаза:
    1) IntelliJ лучше чем Visual Studio. Хотя VS+ReSharper стирает все преимущества IntelliJ, но всё же ReSharper добавляет свои проблемы (не знаю исправили баг или нет, но RS очень не любит WPF и в нашем проекте, плагин для VS, у нас почти все xaml.cs файлы были красные из-за того, что он не видел зависимости или что-то в этом роде), IntelliJ свои баги, тоже есть, но всё же для меня IntelliJ было приятным открытием
    2) Очень неудобная настройка билдов (maven). Кроме того, что это огромные файлы xml, так в той же intellij нет(либо я не нашёл) GUI для управлением этим файлом и чтения зависимостей. Gradle почти тоже самое, правда все же файлы не такие огромные
    3) Как же плохо без дефолтных фреймворков. Что я имею ввиду — огромное количество разных orm, библиотек логирования и т.д. Кому-то это плюс но в корпо это ужас ибо работаешь с разными программистами, с разных стран, у всех свои стандарты и пожелания. В итоге в проекте у нас 3 библиотеки для логов, ибо каждый вбил что хотел в свое время, используется MyBatis который конечно быстрый, но неудобный и вообще Spring Boot сейчас уничтожает все апгрейды у нас в проекте, потому что у нас Spring 3, сделали апдейт до 4, а дальше уже тяжело, ибо нужны новые версии зависимых других библиотек, а они все почти уже имеют настройки под Spring Boot. Ясно, что можно и под обычный настроить Spring, но если нет документации, то на это уходит много времени. Как пример — сейчас нам надо сделать Gateway и мы такие обрадовались, ведь в Spring Cloud появился как раз Gateway. Только фигушки нам ибо зависимости идут на Spring Boot и нет ещё статей на тему как поставить это на обычный Spring. К тому же очень мало статей на тему hello world в spring security на обычный spring. Найти конечно можно, но всё равно большинство под Spring Boot. В итоге сейчас думаем, что надо переноситься на Spring Boot 2, но у нас там столько зависимостей и не факт что все они имеют апдейт до SB2 и Spring 5. Вообщем ад и в .net даже близко такого не было никогда. В .net уже очень давно есть WCF и IIS, которые бы решили нашу проблему
    4) Закончу на положительной ноте для Java — open source. В той же IntelliJ можно найти имплементацию любого метода и даже в дебаг кинуть. В .net core была подобная возможность, дебажить исходники, но потом почему то убрали и сделали фигню, которая работает только в call stack, а вот если просто нажму open implementation на системном методе, то мне покажет только методанные. Вообщем огромный плюс Java

    Если я в чем-то не прав то пожалуйста напишите об этом, буду рад любой информации


    1. Veikedo
      30.03.2018 15:03

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


      1. Free_ze
        30.03.2018 15:28

    1. DieSlogan
      31.03.2018 00:38

      В своё время со spring security здорово помог разобраться цикл статей отсюда. Они актуальны и для 4-го спринга: http://krams915.blogspot.com/search/label/Security?m=1


  1. maxzh83
    30.03.2018 14:54

    Очень неудобная настройка билдов (maven)

    В idea есть maven plugin, который позволяет удобно выполнять частые операции с maven, поддерживает профили и т.д. Файлы xml maven хоть и часто большие, но однообразные и простые по структуре. Это отличается от xml в мире .net, где из-за сложности пришлось сделать графическую утилиту. Как правило в pom копируется зависимость и забывается, idea же при редактировании подсказывает синтаксис и проверяет ошибки.
    Как же плохо без дефолтных фреймворков

    Вам в помощь Spring Initializr (https://start.spring.io/). Выбрали нужный функционал, который нужен в проекте, нажали Generate и уаля у вас на выходе проект, который сразу запускается и содержит все что нужно.


    1. Bonart
      31.03.2018 01:29

      Это отличается от xml в мире .net, где из-за сложности пришлось сделать графическую утилиту.

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


      1. maxzh83
        31.03.2018 10:41

        Да, устаревшие и я рад что сейчас на .net тоже это поменялось. Но я отвечал на комментарий, в котором упоминалась GUI для конфигов, видимо автор комментария переезжал с устаревшей версии


        1. Bonart
          31.03.2018 15:32

          GUI при этом никуда не делся и прекрасно работает.
          Я пользуюсь и тем и другим — смотря что удобнее по ситуации.
          Так что у дотнета преимущество в обоих случаях.


          1. maxzh83
            01.04.2018 07:53

            Так что у дотнета преимущество в обоих случаях.

            Не у дотнета, а у одной конкретной IDE (VS) над другой конкретной IDE (Idea) в конкретном вопросе (GUI для редактирования конфигов). Да и то преимущество спорное, на любителя.


            1. Bonart
              01.04.2018 20:46

              Именно что у дотнета.


              1. Новый формат cproj — это все тот же msbuild (а не ide), замены которому де-факто нет.
              2. "Конкретная IDE" является лучшей и господствуещей на рынке разработки для платформы.
              3. Инструменты для явы почему-то никто от самой явы не отделяет — логично и с дотнетовскими поступать так же.


  1. eugenebb
    30.03.2018 16:09

    T4 для .net, очень увеличивает производительность труда и убирает рутину.


  1. konsoletyper
    30.03.2018 22:20

    Да, я знаю про jOOQ, но ни разу не видел его использование хоть в чем-то, напоминающем продакшен.

    Есть Querydsl, использовал в продакшене и не могу нарадоваться. Ещё есть Jinq, но с ним я только игрался и идея использовать его в продакшене мне кажется сомнительной. Причина — использует сериализуемые лябмды, что накладывает множество ограничений (лучше анализировал байт-код лябмд с помощью какого-нибудь инструментатора/класслоадера).


    Возможно потому что это полу-платный новодел без JSR, возможно по другой причине.

    JSR не панацея. На спринг есть JSR? А, скажем, для логгирования используют log4j/logback/slf4j вместо стандартного (JSR) java.util.logging.


  1. kemix
    30.03.2018 22:26

    Работал с asp еще до того как был .net, потом с monorail, потом с asp.net mvc и asp.net core, тоже недавно перешел проект, где один из сервисов на Java и spring boot, остальные C# asp.net core.


    Впечатления в радикально отличаются от впечатлений автора:


    VisualStudio vs Idea


    • VS (даже с R#) гораздо стабильнее и быстрее чем idea, по крайней мере на моих маленьких проектах
    • в VS не нужна кнопка invalidate caches and restart, за много лет использовал сброс кеша R# один или два раза, в idea при переключении веток и редактировании зависимостей gradle регулярно ее использую

    при переходе С# => Java очень напрягает:


    • отсутствие var, async/await, linq, extension methods и class properties
    • местами очень недружелюбный api библиотек
    • type erasure, не предполагал что так быстро с ним столкнусь
    • checked exceptions, не ощутил пока особой пользы

    при переходе asp.net => spring boot:


    • аннотации везде и для всего, причем не везде даже с compile time checking
    • неявный DI, аннотации для регистрации
    • отсутствие nuget install-package и UI к нему

    не могу согласиться с:


    Впрочем, адекватные альтернативы IIS под Windows от этого не появились (да я знаю про Kestrel для .Net Core).

    selfhosted asp.net webapi можно было писать и до .net core, хочешь запускай как консольное приложение, хочешь как win service с TopShelf например, отличный вариант для новых приложений который не зависят от возможностей IIS


    Только спустя 15 лет в Микрософт поняли, что это хорошо и пора перестать диктовать миру “как правильно жить”

    у меня сложилось впечатление что это в spring boot мне диктуют как правильно жить, как иcпользовать DI, как называть разные lifescope и тд


    Я могу написать web-приложение на Java без единой строчки xml (привет Spring Boot), и не могу это сделать на .Net (привет web.config, который “по сути” тот же web.xml, только еще и перемешанный с конфигом).

    пара очень простых и легко читаемых файлов в проекте напрягают гораздо меньше чем gradle config, хотя он и не xml


    1. maxzh83
      31.03.2018 11:11
      -1

      у меня сложилось впечатление что это в spring boot мне диктуют как правильно жить, как иcпользовать DI, как называть разные lifescope и тд

      Так никто же не заставляет использовать Spring Boot, тем более на него нет JSR. Можете использовать любой другой фреймворк, коих довольно много. И это отличается от ситуации с .net, который до недавнего времени был закрытым и фактически был прибит гвоздями к Windows (энтузиасты из Mono не в счет). И хорошо, что сейчас все по другому, но почему бы не сделать этого раньше?


  1. trailmax
    30.03.2018 22:26

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


    1. maxzh83
      31.03.2018 10:48

      Сложно не согласиться, но вокруг меня ситуация прямо противоположная. И у автора статьи, похоже, такая же.


      1. trailmax
        02.04.2018 01:41

        Рынок диктует условия. Я в универе яву учил… А потом пошел вакансии смотреть и резко пришлось платформу сменить. Так что мы все тут в одной корзине.


  1. build_your_web
    31.03.2018 00:35

    В статье нет самого главного, чем JVM сильно проигрывает .Net — это Type Erasure.

    Подобное в JVM без костылей не сделать:

    class Foo: IProcessor<A>, IProcessor<B> {
       void Exec(A arg){
       ...
       }
    
       void Exec(B arg){
       ...
       }
    }
    
    т.к. во время компиляции void Exec(A arg) и void Exec(B arg) превратятся в void Exec(Object arg) и мы получаем конфликт между двумя методами с одинаковой сигнатурой. Можно создать явно интерфейсы IProcessorA и IProcessorB в которых будет указана сигнатура, не имеющая generic type аргументов, но этот workaround мешает компоновке библиотек, т.к. появляется зависимость на конкретный интерфейс для конкретного аргумента generic типа (IProcessorA — A). А это значит, что все, кто захотят поддерживать интерфейс IProcessor, должны заранее договориться использовать общую сборку в которой лежит IProcessorA. А теперь представим, что есть N независимых разработчиков, не знающих друг о друге, объявивших в своих библиотеках свой IProcessorA…
    Есть решение через полиморфизм, но это в свою очередь осложняет жизнь тем, что в каком-то месте вам нужно указать все поддерживаемые типы-наследники. Что также является антипатерном. В общем, из одной ловушки в другую.
    Подробнее тут.

    Можно привыкнуть к новой IDE, освоить новый язык, потратить многие месяцы на изучение нового технологического стека, но один лишь факт того, что в языке нет полноценной реализации такой базовой штуки как Generic Types, означает, что постоянно будет ощущение неполноценности разрабатываемого кода, по сравнению с аналогичной реализацией на .Net.

    Пробовал программировать на Kotlin (на мой взгляд, у языка прекрасный синтаксис), но описанная выше проблема сводит его преимущества перед C# на нет.


    1. Bonart
      31.03.2018 01:39

      постоянно будет ощущение неполноценности разрабатываемого кода

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


      1. Viacheslav01
        31.03.2018 02:16

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


        1. Free_ze
          31.03.2018 11:06

          Обратная совместимость на уровне байт-кода — иначе старые JVM не смогут в новые дженерики, а они дорожат запуском нового кода в рарихетных рантаймах.


          1. kemix
            31.03.2018 21:29

            а может добавить ключ компиляции и дать возможность мне самому решать нужна ли мне эта обратная совместимость или нет?


            1. Free_ze
              01.04.2018 11:35

              Тогда все сразу забьют на поддержку старых версий)


            1. PsyHaSTe
              01.04.2018 19:18

              Когда это решение принималось, то это было самым простым решением. Сейчас же менять это уже поздно, и ОЧЕНЬ дорого.


  1. MRomaV
    31.03.2018 01:32

    В .NET выбор очевиден — Visual Studio.

    Как же VS Code для .net core? Rider?


  1. Viacheslav01
    31.03.2018 02:12

    «5. Community», а может оно и лучше? Я без слез на прогресс платформы явы на фоне дотнета без слез смотреть не могу.


  1. vladimirkolyada
    31.03.2018 20:59

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


  1. vlanko
    31.03.2018 21:57

    Прочитал про LINQ. Интересно, хоть и дико для джависта видеть SQL в переменных.


    1. Makc_K
      01.04.2018 01:07

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


      1. Bonart
        01.04.2018 01:12

        Почему теряет в читабельности?


        1. Makc_K
          01.04.2018 11:37
          +2

          Кому-то SQL-подобный синтаксис проще читать, он более «самодокументируемый».


          1. PsyHaSTe
            01.04.2018 19:20

            Любой код самодокументируемый, потому что иначе оно бы не работало.

            Главное преимущество лямбд — типизируемость. Кто-то использует дапперы и фигачат всё на SQL, только вот гарантировать правильные типы, увы, становится невозможно.


            1. lair
              01.04.2018 20:09

              Любой код самодокументируемый

              Очевидно, нет.


              потому что иначе оно бы не работало.

              Для того, чтобы код работал, читаемость не обязательна.


              1. PsyHaSTe
                01.04.2018 20:58

                Ок, не так выразился. LINQ-код не более и не менее понятен, чем аналогичный SQL почти всегда.


                1. Makc_K
                  01.04.2018 22:48

                  Может я, конечно, ошибаюсь. Но мне кажется, мы недопоняли друг друга и говорим о разных вещах. Я говорил о том, что есть 2 формата записи LINQ (примеры чисто академические):
                  1) SQL-образный

                  var selectedUsers = from user in users
                                      from lang in user.Languages
                                      where user.Age < 28
                                      where lang == "английский"
                                      select user;

                  2) С использованием лямбд
                  var selectedUsers = users.SelectMany(u => u.Languages,
                                              (u, l) => new { User = u, Lang = l })
                                            .Where(u => u.Lang == "английский" && u.User.Age < 28)
                                            .Select(u=>u.User);


                  Причём запросы могут формироваться, как LINQ for Objects, так и LINQ for Entities. Первое — для коллекций, второе — для ORM, что в итоге преобразуется в банальный SQL запрос для СУБД.


                  1. PsyHaSTe
                    01.04.2018 23:02

                    И то и то LINQ, просто у него 2 формы записи: query linq и method chain linq. Первый вариант иногда читаемее, а иногда нет. Например типичный запрос выглядит так:


                    var foo = mytable.Where(x => x.Foo == 1).Select(x =>x.Bar).FirstOrDefault()

                    В виде query получается немного нелепо.


                    А я изначально подумал что вы в прямом смысле про SQL в шарпе:


                    var foo = mytable.Query<Thing>("select * from Thing where Name = @Name", new {Name = "abcde" });

                    Насколько это читаемее — вопрос


  1. dmitry_dvm
    31.03.2018 22:36

    Джава очень уж многословна по сравнению с шарпом. В нее автопроперти-то завезли наконец?


    1. maxzh83
      01.04.2018 10:44

      Недавно завезли var, что должно уменьшить многословность. Автопроперти делаются с помощью аннотации над классом (с Lombok). Но многих это несильно волнует, т.к геттеры и сеттеры генерятся легко в любой IDE.


      1. Makc_K
        01.04.2018 11:40
        +1

        геттеры и сеттеры генерятся легко в любой IDE

        Претензия не в том, что геттеры/сеттеры сложно генерировать, а в том, что по сравнению с .Net наблюдается увеличение объёма кода. Вместо одной сущности — автосвойства, три — переменная + геттер + сеттер.


        1. maxzh83
          01.04.2018 13:53

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


          1. Bonart
            01.04.2018 22:21

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


            1. maxzh83
              01.04.2018 23:08

              В мире джавы мало кого смущает и генерация сеттеров IDE и Lombok, в котором магии не больше чем в Spring. Но, как уже писал выше, никто не мешает использовать Котлин, которые в обе стороны совместим с Джавой, и в котором есть все что нужно. Но, возможно, сейчас и тут напишут про проблему с дженериками.


              1. Bonart
                02.04.2018 00:20

                В дотнете Fody тоже никого не смущает.
                Но никто не делает вид, что вплетение кода заменяет имеющиеся языковые средства задаром.
                А котлин мне очень нравится.


                Но, возможно, сейчас и тут напишут про проблему с дженериками.

                Такова жизнь. В JVM JIT и сборщик мусора лучше дотнетных. Но нет генериков и непримитивных типов-значений.


  1. asm0dey
    01.04.2018 00:34

    Больше 2х лет использую JOOQ в банковском (и похожем) энтерпрайзе.


  1. IvanNochnoy
    01.04.2018 13:27

    Java Community Process и этим всё сказано. Формальный процесс, в котором заинтересованные лица могут участвовать в обсуждении и формировании новых версий платформы.

    По статистике GitHub https://octoverse.github.com/ проект VSCode вообще на первом месте по количеству контрибуторов. В остальных тоже жизнь кипит как в аду. В проекте TypeScript Хейлсберг крутится, как на сковородке.


    Только спустя 15 лет в Микрософт поняли, что это хорошо и пора перестать диктовать миру “как правильно жить” (помните ныне расформированный Microsoft Patterns and Practices group?) и придумал аналог — .NET Foundation.

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


    1. Enrey Автор
      01.04.2018 15:41
      -1

      Причем здесь VSCode? VSCode это переосмысление Atom-а и Sublime, которое действительно выстрелило. VS код действительно очень крут и опенсорсен.

      PnP в конечном итоге извергло из себя Unity (не движок для игр, а контейнер), которое преподносилось в ~2010 как супер ноу-хау в т.ч. в живых семинарах в Мск. Это было как минимум забавно — ничего нового, но пафоса горы.


  1. IvanNochnoy
    01.04.2018 13:45

    Здесь абсолютное доминирование Java-платформы. Есть два основных монстра: EJB и Spring с огромнейшей экосистемой и практиками “вокруг”… В .Net ничего этого нет.

    Только спустя 15 лет в Микрософт поняли, что это хорошо и пора перестать диктовать миру “как правильно жить” (помните ныне расформированный Microsoft Patterns and Practices group?)

    Похоже на двоемыслие.


    1. Enrey Автор
      01.04.2018 15:33
      -2

      В каком месте-то?)
      1. В .NET нет нормальной платформы для разработки ентерпрайз приложений.
      2. 15 лет микрософт «в одно рыло» делал изменения в языке и .NET Framework.

      И-то и то верно, вы с этим спорите что ли?


      1. lair
        01.04.2018 18:45

        В .NET нет нормальной платформы для разработки ентерпрайз приложений.

        Define "нормальная платформа".


        1. Enrey Автор
          01.04.2018 21:11

          a la Spring.


          1. PsyHaSTe
            01.04.2018 21:21

            Ну то есть оригинальное высказывание было «В .NET нет Spring». Ну, возможно. Только не все вообще в курсе, что это.


            1. Enrey Автор
              01.04.2018 21:45

              Ну его действительно нет. Были давным-давно попытки a la Spring.NET, но оно разбилось об отсутствие Community.
              Конструктивней в данном треде, увы, вряд ли получится, здесь какая-то атмосфера нездоровая — сплошные переходы на личности с двоемыслиями, define и т.д. Неинтересно.


              1. PsyHaSTe
                01.04.2018 21:48

                Может просто стоит обосновывать такие громкие утверждения? В стиле «В дотнете нет Spring поэтому ынтырпрайз на нем не написать».


                1. Enrey Автор
                  01.04.2018 22:10

                  Если вам действительно интересно, зайдите на сайт спринга там есть features projects.spring.io/spring-framework оно всё вместе работает «из коробки». В .NET я не знаю фреймворка такого уровня зрелости (только десяток более мелких ежей-ужей которые постоянно приходится скрещивать).

                  А если посмотреть на спринг.клауд, projects.spring.io/spring-cloud то его фичи это вообще космос, вообще не знаю ничего похожего для .NET.


                  1. Bonart
                    01.04.2018 22:25

                    Один фреймворк для всего?
                    Спасибо, не надо.
                    Вдобавок у комментатора с опытом здесь же https://habrahabr.ru/post/352404/#comment_10732666
                    мнение про Spring слегка отличается от вашего.


                    1. solver
                      02.04.2018 12:25

                      Справедливости ради, Spring это не «Один фреймворк для всего».
                      Это множество библиотек и фреймворков, решающих различные проблемы построения приложения и разрабатываемых в схожем стиле для облегчения интеграции между собой. От базовых типа DI, до продвинутых типа Cloud.


                  1. IvanNochnoy
                    02.04.2018 00:28
                    +1

                    Мне интересно. Зашел по ссылке.


                    Вот рецепт приготовления Spring в .NET


                    md Spring
                    cd .\Spring
                    dotnet new sln
                    md Spring
                    cd .\Spring
                    dotnet new razor --auth Individual --use-local-db
                    dotnet add package System.Reactive
                    dotnet add package AutoMapper
                    dotnet add package JetBrains.Annotations
                    dotnet add package Microsoft.AspNetCore.SignalR --version 1.0.0-preview1-final
                    cd ..
                    md Spring.Tests
                    cd .\Spring.Tests
                    dotnet new xunit
                    dotnet add package Microsoft.AspNetCore.All
                    dotnet add package Microsoft.AspNetCore.Cors
                    dotnet add package Microsoft.AspNetCore.Identity.EntityFrameworkCore
                    dotnet add package Moq
                    dotnet add package Autofixture
                    dotnet add package JetBrains.Annotations
                    dotnet add package Microsoft.AspNetCore.TestHost
                    dotnet add package CommonServiceLocator
                    dotnet add package Microsoft.EntityFrameworkCore
                    dotnet add package Microsoft.EntityFrameworkCore.InMemory
                    dotnet add package Microsoft.NET.Test.Sdk
                    dotnet add package Newtonsoft.Json
                    dotnet add package Selenium.Support
                    dotnet add package Selenium.WebDriver
                    cd ..
                    dotnet sln add .\Spring\Spring.csproj
                    dotnet sln add .\Spring.Tests\Spring.Tests.csproj
                    cd .\Spring
                    dotnet run

                    После выполнения получаем следующие аналогичные Spring возможности (отмечены крестиком)


                    Features
                    Core technologies:
                    [x] dependency injection,
                    [x] events,
                    [x] resources,
                    [x] i18n,
                    [x] validation,
                    [x] data binding,
                    [x] type conversion,
                    [x] SpEL,
                    [ ] AOP.
                    Testing:
                    [x] mock objects,
                    [x] TestContext framework,
                    [x] Spring MVC Test,
                    [x] WebTestClient.
                    Data Access:
                    [x] transactions,
                    [x] DAO support,
                    [ ] JDBC,
                    [x] ORM,
                    [x] Marshalling XML.


                    [X] Spring MVC and
                    [x] Spring WebFlux web frameworks


                    Integration:
                    [x] remoting,
                    [ ] JMS,
                    [ ] JCA,
                    [ ] JMX,
                    [x] email,
                    [x] tasks,
                    [ ] scheduling,
                    [x] cache.
                    Languages:
                    [ ] Kotlin,
                    [ ] Groovy,
                    [x] dynamic languages.


                    JMS я так понимаю, аналог MSMQ? JMX = Windows Management Instrumentation (WMI) + Performance Counters +.NET Profiling API. JCA не знаю, что такое. JDBC (аналог ODBC) не нужен.


                    АОП — не честно. Так как требует вмешательства в процесс сборки. В .NET есть аналоги, но не прижились они.


                    Kotlin => F#, Groovy => ???


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


                    1. Bonart
                      02.04.2018 01:22

                      В .NET есть аналоги, но не прижились они.

                      Как не прижились?
                      Fody жив-здоров, чего и вам желает.
                      PostSharp на этом вообще деньги зарабатывает.
                      Ну и масса библиотек над Castle.DynamicProxy


                    1. Enrey Автор
                      02.04.2018 07:04

                      Всё верно. А затем, как я и писал выше, начинается скрещивание ежа с ужом. Возьмем например такой базис в любом ентерпрайз приложении как управление транзакциями — где, к примеру, вы в дотнете будете стартовать транзакцию к бд и в какой момент завершать / откатывать? Вариантов много ведь, и ни один не выглядит до конца правильным.

                      А к примеру в том же спринге в разделе про Data — с этого всё начинается docs.spring.io/spring/docs/current/spring-framework-reference/data-access.html

                      Я сам прошёл путь от оголтелого отрицания «платформ» до понятия их необходимости в корпоративной среде. Позволяет не ходить по одним и тем же граблям разными путями в разных проектах.


                      1. IvanNochnoy
                        02.04.2018 11:46

                        System.Transactions есть в .NET. В корку тоже завозят в версии 2.1


                        Вариантов много, и ни один не выглядит до конца правильным, это факт. Я так понимаю, что Spring, это некая Тора в мире Java, где даны ответы на все вопросы? Это хорошо, потому что устраняет фрагментацию.


                        У меня такое мнение по этому вопросу: Вы говорите: я знаю Spring и счастлив. Ок, но есть нюанс. Вы обратили внимание на то, что Spring, Hibernate и т. п. не являются продуктами Sun/Oracle? Это сторонняя разработка. В то время как в .NET — ASP.NET МVС, Web API, EF, WPF — это продукты МС? Дело в том, что с точки зрения МС весь .NET фреймворк целиком является эдаким большим Spring. И если сказать: я знаю .NET, то тоже будет счастье.


                        Очевидно, Spring заточен под энтерпрайз, .NET — не только. Поэтому и разброс больше, и гайки затянуты не так туго.


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


                        В любом случае, в энтерпрайзе очень много рабочей силы. И на одном предприятии обязательно будет специалист по кнопочкам, по скриптикам, по базочкам и по сообщеньицам. Не из коробки, но каждый будет знать свою часть работы. Им не нужно знать Spring/.NET целиком. И когда новичок придет, то он будет заниматься тем, что знает — своим делом, в своем отдельном боксе.


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


                    1. asm0dey
                      02.04.2018 09:01

                      АОП не обязан (и по умолчанию не является) частью процесса сборки. JCA — Java Crypto API. Наверняка в дотнете есть аналогичный механизм— общее API для всего шифрования. JMX даёт не только телеметрию, но и возможность отправлять/получать данные как RPC примерно. JMS тянет за собой ещё и поддержку XA-транзакций на все JTA-compatible источники данных (ну то есть как минимум JDBC и сам JMS).


                  1. IvanNochnoy
                    02.04.2018 01:53

                    Что ж, Spring Cloud действительно выглядит внушительно. Аналогов в .NET я не знаю. Со своей стороны МС делает ставку на Kubernetes.


              1. Bonart
                01.04.2018 22:08

                Вы на редкость самокритичны.


          1. lair
            02.04.2018 00:03

            Это не определение. Если вы хотите сказать, что ничто кроме Spring — не нормальная "платформа для ентерпрайз приложений", то… ну ок, чо. Пойду писать свои ентерпрайз приложения без платформы.


            1. Enrey Автор
              02.04.2018 08:17

              Servicestack.net еще адекватная платформа для NET которую я знаю. Там можно на странице Features нажать на коробочку и получить их список. Но к сожалению платная, поэтому жутко непопулярная как у разработчиков так и работодателей. Странно что ее так никто и не упомянул, я всё ждал, ждал.


              1. lair
                02.04.2018 10:04

                Странно что ее так никто и не упомянул, я всё ждал, ждал.

                Может быть, потому, что критерии адекватности и ентерпрайзности у всех разные?


      1. Bonart
        01.04.2018 20:41

        1. Ни мне, ни моим работодателям, использующим дотнет для разработки самого что ни на есть кровавого энтерпрайза, эта мысль почему-то в голову не приходила. Что мы делали не так?
        2. Как будто что-то плохое: в яве очень много сделано в стиле «лебедь щуку раком», когда на каждый чих есть 100500 разных несовместимым между собой библиотек со своими уникальными недостатками.


  1. IvanNochnoy
    01.04.2018 19:33
    +2

    Я это к тому, что практики Spring Вас не напрягают а практики МС возмущают.


    1. Я не спорю, я не делаю приложений Enterprise уровня, поэтому не знаю, почему в .NET нет "нормальной платформы" для этого. Если проблема в том, что в .NET слишком много реализаций IoC контейнеров, то тогда, да, конечно. С другой стороны, не всем нужен Ынтерпрайз.


    2. Вы так говорите, как будто в этом что-то плохое. А по факту...

    Вы никогда не задумывались над тем, откуда в Java дженерики, аннотациии, автобоксинг/анбоксиг, короткая версия for, строки в свитчах, поддержка динамических языков, try-with-resources, выведение типов, лямбда выражения, методы расширения, перечислимые типы, методы с переменным числом аргументов? Почему Java Server faces так были похожи на ASP.NET Forms? Почему существуют хаки, типа EA Async, Lombok, jook?


    По странному совпадению, как только эти фишки появляются в .NET, они затем оказываются в Java. Это выглядит подозрительно.


    Нравится Reactive Streams? Я так понимаю, что это ReactiveX (RxJava), у которых устранен "фатальный недостаток"? Да, это те самые Reactive Extensions, которые используются сейчас и в Ангуляре и в Java и в Android. Cамое интересное здесь, что ReactiveX, стал опен-соурс проектом, после того, как был открыт и передан общественности… Майкрософт в 2012 году пруф.


    Я уже не говорю о том, что сейчас все на ушах от GraphQL, а вот когда Майкрософт в 2007 году сделали открытый протокол OData, это нафиг никому не было нужно (REST наше всё!). До тех пор, пока Facebook не исправил в нем "фатальный недостаток".


    А F#? Выпущен в 2005 году, стал опен сорс в 2010 (8 лет назад). Сколько ещё лет пройдёт, прежде чем Oracle заметят Scala?


    Как видно, опен сорсом МС занимается уже "многие лета".


    Вы живете какими-то воспоминаниями.


    1. Enrey Автор
      01.04.2018 21:07
      -1

      Я много о чем и когда задумывался :))
      И на OData доводилось писать когда не было никаких GraphQL. И только версия OData 4.0 уже хоть как-то подходила для продакшн, хотя и приходилось всё равно вставлять кучу костылей.

      Вы как-то в одни ворота играете… :)
      Давайте вспомним, например, (N)Hibernate. В каком году микрософт задумалась об ОРМ? А DI/IOC-контейнер в каком году появился? А библиотеки модульного тестирования ala N(J)Unit откуда портировались?

      Я согласен, что синтаксис и возможности языка C# приятней (микрософт переосмыслил ошибки Java, это известный факт). Но что касается экосистемы вокруг — здесь Java действительно впереди, как бы я не любил C#.
      И .NET Core это попытка MS запрыгнуть в уходящий поезд (возможно что-то и получится).
      Кстати, Java тоже решила ускориться и перешла на полугодичный цикл релизов.
      Так что дальше будет еще интересней. А то что языки черпают друг у друга новые возможности — это же хорошо.


      1. Enrey Автор
        02.04.2018 06:15

        Никто уже не помнит WCF Dataservices? Это и была одна из причин провала OData-ы — прибитая гвоздями кривейшая концепция и инфраструктура.
        К версии 4 оно всё-такие мигрировало на более адекватный и гибкий Web Api.
        Потом, впрочем, и Web Api канул в лету (оно и к лучшему).


        1. lair
          02.04.2018 10:06

          Никто уже не помнит WCF Dataservices? Это и была одна из причин провала OData-ы — прибитая гвоздями кривейшая концепция и инфраструктура.

          Вы под провалом OData понимаете то, что у нас до сих пор ощутимый поток интеграций через этот интерфейс?


          Потом, впрочем, и Web Api канул в лету (оно и к лучшему).

          Ыыы, а на чем я пишу сейчас?


          1. Enrey Автор
            02.04.2018 10:31

            Под провалом odata я понимаю что практически никто за пределом .net песочницы о ней не слышал, хотя технологии ~10 лет (да и в песочнице она нечасто всплывает)


            Пишете на WebApi? А как же .Core которому здесь сотню комментариев подряд все оды поют?


            1. Szer
              02.04.2018 10:35

              Пишете на WebApi? А как же .Core которому здесь сотню комментариев подряд все оды поют?

              Так это оно и есть.


              1. Enrey Автор
                02.04.2018 10:39

                Оно ж с MVC слилось в экстазе когда ms осознал что две параллельные реализации контроллеров и инфраструктуры вокруг них не есть хорошо. М?


                1. Szer
                  02.04.2018 10:47

                  Оно ж с MVC слилось в экстазе когда ms осознал что две параллельные реализации контроллеров и инфраструктуры вокруг них не есть хорошо. М?

                  ну да слилось, это плохо? Старые MVC неймспейсы убрали (System.Web.Mvc стал Microsoft.AspNetCore.Mvc), унифицировали работу с контроллерами, но в целом это тот же самый старый добрый WebApi.


                  Живее всех живых короче.


                1. IvanNochnoy
                  02.04.2018 10:52

                  Вы действительно думаете, что в МС дурачки сидят? Две параллельные реализации были сделаны потому, что Web API стали переводить на рельсы OWIN раньше, чем MVC. Сначала избавились от зависимости от System.Web в API, а затем уже и в MVC.


                  1. Enrey Автор
                    02.04.2018 11:19

                    Я думаю что МС не думает о ПЖЦ своих технологий, поэтому они часто «почкуются» и умирают.

                    Всё что можно было делать в Web Api, можно было делать и в MVC через JsonResult метода контроллера. Разве что без OWIN и Embeded Server и чуть более «многословно».

                    Так что Web Api попросту умер, когда в новом «более лучшем» MVC пришлось/удалось отказаться от System.Web за счет кросс-платформенности. Мавр сделал свое дело, мавр может уходить.


                    1. lair
                      02.04.2018 11:20

                      Всё что можно было делать в Web Api, можно было делать и в MVC через JsonResult метода контроллера.

                      Серьезно? Content negotiation — тоже? Из коробки?


                      1. Enrey Автор
                        02.04.2018 11:29
                        -1

                        Вам шашечки или ехать? Вот во всех комментариях найдут какую-то «мелочь» и цепляются к ней… Content negotiation только во 2м вебапи появилось, если мне склероз не изменяет и уж точно не было киллер-фичей.


                        1. lair
                          02.04.2018 11:39

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


            1. IvanNochnoy
              02.04.2018 10:58

              Да OData опередили свое время. Тогда все ещё на JQuery сидели. Славное было времечко.


              1. Enrey Автор
                02.04.2018 11:25

                Да уж :) Помню как евангелисты микрософта на конференции TechEd 2011 преподносили OData как революцию. Но «что-то пошло не так» ©

                Вот даже видюшку нашёл, харизматичный мужичок был www.techdays.ru/videos/3883.html


            1. lair
              02.04.2018 11:19

              Под провалом odata я понимаю что практически никто за пределом .net песочницы о ней не слышал, хотя технологии ~10 лет (да и в песочнице она нечасто всплывает)

              Берем, значит, любимый аналитический инструмент офисного работника — я про Excel — и видим там Get Data for OData feed.


              Пишете на WebApi? А как же .Core которому здесь сотню комментариев подряд все оды поют?

              У нас проект на .net framework. Когда поедем на Core — там все равно схожий движок, так что конкретно в этом месте я ожидаю тривиальную миграцию. Это вам не с WCF переписывать.


  1. PsyHaSTe
    01.04.2018 19:52

    1. Солюшен всегда был солюшен. Проекты пытались переделать на project.json, но не заехало + я работал с кором начиная с beta4 (в продакшне) — так вот изначальной кор это ад. У JSON нет никакой схемы, ничего не понятно, документации кот наплакал, периодически все перестает работать, где искать ответы — хз. По сравнению с этим расширение существующего XML выглядит как верх читаемости и удобства. JSON ради JSON'а это очень круто, но я на практике видел оба варианта. Не считая того, что я буквально вчера писал свой кастомный таргет для csproj, который через 30 минут после моей идеи о нем был реализован. Потому что не стали городить свой велосипед и просто убрали бойлерплейт, привнеся пользу причем и обычным проектам, ибо новый формат обратно совместим с полным фреймворком.
    2. Первый раз слышу, чтобы пытались собрать чем-то другим. Первый вопрос — зачем? Ведь в итоге все равно все выльется в msbuild, никто в здравом уме не будет писать свою обертку над csc. Сюда можно как раз вспомнить то, что я написал в предыдущем пункте, я когда писал свой таргет смотрел на стандартные, там СТОЛЬКО логики, что дублировать её можно, конечно, но смысл? Это очень дорогой эффорт, профит от которого неясен — msbuild вполне хорош, если не считать транзитивных зависимостей.
      Насчет разных версий msbuild'а было бы интересно послушать, потому что у меня например никогда проблем не было, включая сборку какого-нибудь солюшена под 2010 студию последним компилятором.
      Ну а что касается cake — я очень подозрительно отношусь к словосочетаниям "скрипты", "make" и "сборочная система". Ибо навевает печальные воспоминания как я пробовал opencv собрать правильно. Хотя кроссплатформа выглядит заманчиво, не спорю, но разрабатывать на шарпе я бы все равно иначе как на винде не стал бы — все-таки студия пока вне конкуренции. Через пару-тройку лет мб можно будет посмотреть на райдер, но пока в нем много чего не хватает.
    3. Не вижу, чем свобода выбора плоха. Если у вас разработчики не умеют договариваться, то тогда наверное да, диктатура со стороны языка вам на пользу. В моей практике наоборот, возможность выбрать тонко инструмент под задачу позволяет писать намного более приятный код. Нужен простенький DI? Не вопрос, берем Microsoft.Extensions. Нужно что-то посложнее? Окей, берем Autofac. Нужно, чтобы ASP.Net использовал Autofac вместо встроенного DI? Для этого тоже есть пакет. Ну и про "велосипеды на каждом углу" хотелось бы подробнее. Что именно люди переизобретают? В вашем десятилетнем стаже наверняка найдется пара-тройка примеров.
    4. Как я выше сказал, множество вариантов это всегда хорошо. С другой стороны, у вас ведь разработчики, которые не могут договориться, как же вы можете ставить это как плюс? А вдруг один возьмет servlet api, а другой — tomcat?
    5. Тут все верно, коммьюнити недавно появилось в процессах. Правда, как мне кажется язык и без того развивался быстрее и эффективнее, а с появлением коммьюнити это впечатление только усиливается.
    6. Тоже нечего добавить
    7. А вот тут поподробнее. Я, конечно, извиняюсь, но XML конфиги я уже года 2 точно не видел. Для настроек есть appsettings.json, который удобно подсасывается. Покажите, где тут хоть строчка с XML

    Хотел вкратце ответить — но как-то не срослось, решил подробнее остановиться на каждом из пунктов, очнулся уже в конце простыни.


    Мое мнение, что на новых языках писать всегда удобнее, чем на старых. Поэтому джава удобнее плюсов, шарп — джавы, а раст — шарпа. С другой стороны, количество библиотек — обратная зависимость. В итоге для меня лично сейчас компромиссная точка — шарп, у которого библиотек меньше чем у любого из этих языков, за исключением конечно раста, но появившийся позже плюсов и джавы и сумевший проделать работу над ошибками. По сути шарп можно считать Java++ с потерей обратной совместимости. Но с ростом количества библиотек у этого самого раста я планирую перейти на него как на основной язык в течение нескольких лет. И не потому, что я люблю системное программирование или производительность, а потому что я на него смотрю высокоуровнево, и для меня отсутствие null в языке это одна-единственная возможность, ради которой можно многое простить. Не считая того, что раст развивается даже быстрее шарпа, причем скорость развития даже сравнивать страшно, 6-недельные циклы против годового, и через эти самые пару-тройку лет там появятся и более крутые вещи — я например очень хотел бы увидеть HKT. В шарпе есть пропозал, но когда его примут — неизвестно. Ну а в джаве я не ожидаю их вообще никогда.


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


    1. Szer
      01.04.2018 20:24

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

      Тут мне кое-кто шепнул, что на дотнете есть F#.


  1. maxzh83
    01.04.2018 20:21
    +1

    У джавы наверняка есть свои плюсы

    Java сильна точно не языком. В первую очередь обратной совместимостью и аккуратным подходом к нововведениям. И это очень ценят в бизнесе, но как следствие — медленное развитие и постоянное отставание по фичам. Кроме этого, у джавы мощная инфраструктура и наличие открытых библиотек на все случаи жизни.
    Если не нравится Java именно как язык, то можно посмотреть в сторону Котлина. Получите современный язык, который стремительно развивается + из коробки все наследие Java.


    1. PsyHaSTe
      01.04.2018 21:01

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


      1. Enrey Автор
        01.04.2018 21:21
        -1

        Опять слышу про дженерики… Чем оно лично вам «критическое»-то? Может всё-таки не в дженериках дело? :) Object он и есть Object никаких супер-оптимизаций «серебряная пуля» — не бывает.

        Кстати, подумалось, что свеженький Kotlin-то бегает на JRE, а не на CLR…


        1. maxzh83
          01.04.2018 21:45

          Кстати, подумалось, что свеженький Kotlin-то бегает на JRE, а не на CLR…

          Ну это логично. Его разрабатывает JetBrains, которые свои инструменты исторически пишут на Java. Но Java как язык их не очень устраивает своей архаичностью, а Scala своей загонностью (как альтернатива), решили сделать свой, с фирменным тулингом.
          По поводу CLR, по моему, Андрей Бреслав говорил что CLR не выбрали потому, что смысла нет. C# по возможностям близок Котлину, т.е. Котлин если и лучше в чем-то, то не настолько чтобы люди захотели на него пересаживаться. Поэтому выбрали JVM и JavaScript как платформы для старта.


        1. PsyHaSTe
          01.04.2018 22:12

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


      1. maxzh83
        01.04.2018 21:34

        Вот тоже не понимаю, почему столько внимания в комментариях уделено проблеме с дженериками, причем обычно от людей, которые пишут на C#. Писал и на шарпе и на джаве, за все время сталкивался несколько раз. Т.е. не могу сказать, что как перешел на Джаву так сразу type erasure стало мешать жить. Ну неудобно, да. Но вот чтобы критично… Вот, например, многословность Джавы лично меня напрягает куда больше.


        1. Bonart
          01.04.2018 22:13
          -1

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


          1. maxzh83
            01.04.2018 22:55

            DI от явовских генериков страдает очень сильно.

            Искренне хочется расшифровки или пример «сильного страдания»


            1. Bonart
              01.04.2018 23:47

              Искренне хочется расшифровки или пример «сильного страдания»

              Практически все функции по ссылке явовские контейнеры не потянут без дополнительных костылей, так как параметры-типы у генериков Lazy, Func, Owned, IList и т.д. после компиляции даже не превратятся в тыкву, а просто исчезнут. На практике я использовал большую часть списка хотя бы однажды, а самые ходовые варианты (Func) — ежедневно


              http://autofaccn.readthedocs.io/en/latest/resolve/relationships.html#supported-relationship-types


              1. kjdfvskdfh
                02.04.2018 06:04

                ideone.com/eaT4pl

                Почему-то первыми ругать жаву за стирание типов набегают те кто понятия не имеет что именно стирается.


                1. asm0dey
                  02.04.2018 09:05

                  А что сломалось-то?


    1. Enrey Автор
      02.04.2018 06:08

      Плюсую. Модули Java 9 — колоссальнейшая многолетняя работа по модуляризации и перепиливанию всей платформы.
      Микрософт за это время успел выкинуть старый .NET.


  1. retran
    02.04.2018 11:40

    Так же перешел на java после десятка лет на .net.

    1. Про дженерики выше много написано.

    2. Как связаны Reactive Streams с серверами приложений? В .net Reactive Streams тоже есть (и, кажется, уже везде есть) и сам исходный паттерн Observable встроен в сам язык с самых первых версий.

    3. После знакомства с maven и gradle я начал очень сильно ценить и любить msbuild.

    4. Доминирования прикладных фреймворков не наблюдаю. Наблюдаю бардак в базовых АПИ (даты, коллекции, etc) и монстроидальные монолитные EE и Spring.

    5. В java есть osgi и новый jigsaw. В .net есть MEF, но я ни разу не видел, чтобы кто-то им пользовался.

    6. Наблюдаю использование большого количества бойлерплейтных паттернов типа Builder, вместо которых в C# удобный синтаксический сахар.

    7. В java очень любят и активно используют annotation processors для генерации кода. После .net ощущается очень свежо и интересно. Dagger удивил, например (а что, так можно было?)


    1. maxzh83
      02.04.2018 12:08

      Так же перешел на java после десятка лет на .net.

      А какова причина перехода, если не секрет?