Смена основного стека с .NET на Java



    Хочу описать свои наблюдения и впечатления о самом популярном языке серверного программирования для 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.: На КПДВ — старое, но еще смешное видео.
    Поделиться публикацией
    Ой, у вас баннер убежал!

    Ну. И что?
    Реклама
    Комментарии 196
      +5
      и не могу это сделать на .Net (привет web.config, который “по сути” тот же web.xml, только еще и перемешанный с конфигом).

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

        –2

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

          +1
          В версии 2.1 уже есть.
            0
            нет lazy loading (т. е. оно не Enterprise ready)
            ибо
            This release is still in preview.
              0
              Выше уже ответили что еще не зарелизилось.
              А как насчет many-to-many отношений?
                0
                А как насчет many-to-many отношений?

                Так ли велика эта проблема?
                  0
                  Заставляет плодить новые сущности там где они не нужны.
                    0
                    Почему же не нужны? Связная сущность отражает структуру базы данных. К костылям или какому-то неочевидному ужасу в коде не приводит. А уж что лучше: явность или неявность — это дискуссионный вопрос.
              +1
              Естественно, они этим зарабатывают. Но .Net Core и Azure никак не связаны. Core реально кроссплатформенно (не зря они сделали Linux Subsystem в Win10). А еще поддержка Docker из коробки. Да с EF Core есть проблемы, но учитывая, что он написан с нуля, он взрослеет с каждым релизом. Ну и с выпуском .Net Core платформа переродилась. О ней говорят и пишут больше.
                0
                Core реально кроссплатформенно (не зря они сделали Linux Subsystem в Win10).

                Как связаны .NET Core и WSL?
                  0
                  Возможность тестировать и писать .net core приложения сразу в Linux. Сразу после анонса WSL появилось много статей как настроить .net core и VS Code в WSL
                    0
                    Возможность тестировать и писать .net core приложения сразу в Linux.
                    Вы же про нативный докер и прочие специфичные инструменты, которые нормально работают только в Linux-окружении? Иначе разрабатывать кроссплатформенное приложение, используя WSL в качестве референса целевой платформы — это выглядит немного странно, как по мне.
                      0
                      Целевая платформа всё-таки это Linux. Я считаю возможность разработки в WSL одной из причин появления последней.
                0
                Да и выбор типа проекта был на стадии RC, с релиза 1.0 тип проекта не менялся.
                  –1
                  LazyLoading скорее вреден чем бесполезен и очень хорошо там, где его нет.
                  0

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


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


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

                  Очень сомнительный минус, и очень сомнительный плюс.
                    0
                    Вся ирония в том, что некоторое время назад все.нетчики подкалывали джавистов про «программирование на xml». А сейчас этот самый xml остался, как необходимость, как раз в .Net.
                      +3
                      Я программирую в .net и не имею необходимости использовать xml.
                      Что я делаю не так?
                      0
                      Впрочем, адекватные альтернативы IIS под Windows от этого не появились (да я знаю про Kestrel для .Net Core)

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

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

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

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

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

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

                                В .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 файл с транзитивными зависимостями)
                                0
                                Еще есть расширение для VS Code vscode-nuget-package-manager с автоподсказками
                              +2
                              Еще ни разу «матерый дотнетчик с десятилетним стажем» не был так близок к провалу.
                                0
                                Вы слишком токсичны. Но я плюсанул, радуйтесь.
                                0
                                Не поверите, но через CLI, ведь nuget-manager включен в cli tools у dotnetcore:
                                dotnet add package Newtonsoft.Json

                                Так же есть выбор добавить через GUI от разных IDE: VSC, Rider, VS.
                            0
                            Есть два основных монстра: EJB и Spring с огромнейшей экосистемой и практиками “вокруг”.


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

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

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

                              Но концептуально вы правы, наиболее корректно использовать JEE Server (именно эту бирку «лепят» (или лепили?) себе всякие jboss-ы). Или уже правильно Jakarta Server? :)
                                +1
                                JEE Server означает, что у данного продукта есть сертификация реализации Java EE. Например, тот же Wildfly имеет сертификацию по Java EE 7, но не имеет по Java EE 8.
                                С Jakarta пока не понятно, в каком виде будет сертификация и будет ли вообще.
                                  0
                                  Эталонная реализация Java EE 8 — GlassFish 5.0.
                              +1
                              Всем, кто переходит с VisualStudio, советую только IDEA. Когда переходил (очень давно), думал что умнее студии ничего нет, но IDEA приятно удивила и продолжает удивлять до сих пор. И ReSharper от тех же JetBrains, которые делает студию умнее и удобнее, тому подтверждение.
                                +4
                                В .NET выбор очевиден — Visual Studio.
                                Как же Rider?
                                  +2
                                  Отсутствует бесплатная версия, аналогичная VS Community
                                    0
                                    Это имеет мало значения, если большинство компаний и так покупает платную студию, да еще и решарпер. Idea с поддержкой всякого EE тоже стоит денег, если сравнивать. Тем более, что это единственное адекватное решение для .NET-разработки из *nix.
                                    Для Rider есть достаточно милая инди-лицензия, позволяющая разрабатывать на ней хоть лично для себя, хоть чужой лютый интерпрайз (проблемы совместимости я обнаружил только для некоторых T4-шаблонов, но это специфика).
                                      0

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

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

                                        сделано всё чтобы люди платили деньги.
                                        Вы так говорите, будто это что-то плохое. Коммерческая фирма делает качественные инструменты и просит за это деньги! То ли дело MS, которая выпускает эсклюзивную Visual Studio для своей платной операционной системы!
                                          –1
                                          Не нарушал я ничего, речь идет о домашнем компьютере и pet-проектах. Visual Studio Community хватает «на всё что угодно» (в отличие от ужасающей Express которая была ранее давно). А вот в IDEA Community жадинки отрезали использование спринга с бутом, что отвратительно и неприятно.
                                            0
                                            Не нарушал я ничего, речь идет о домашнем компьютере и pet-проектах.
                                            Там может каждый делать то, что ему вздумается. Я все же про прямое назнчение инструментов — интерпрайз. MS молодцы, конечно, но у них такие меры — не от лучшей жизни.
                                            Вопрос про решарпер все так же актуален.

                                            А вот в IDEA Community жадинки отрезали использование спринга с бутом
                                            Вам maven там тоже отрезали?)
                                              0
                                              Что же это за контейнер такой, которым без специальной поддержки от IDE пользоваться отвратительно и неприятно?
                                                +1
                                                Почему-то все забыли про NetBeans IDE. А в ней достаточно инструментария для создания Java9 и Java EE 7- приложений, которые можно тут же в среде тестировать в GlassFish 5.x и WildFly 12, собирать метрики и протоколы обмена (http-monitor), а maven является родным форматом организации проектов на Java. Интегрированы Git и Mercurial-плагины (используют внешние git и hg) для прозрачного сохранения изменений в коде — можно буквально щелчком мыши откатиться на определённый коммит в истории изменений.
                                                  0
                                                  Что именно там отрезали от сприг бута?
                                                  Почему тогда у меня проекты на спринг буте прекрасно работают в IDEA Community?
                                                  0
                                                  Почитал лицензию. А что трактуется под «одновременным использованием»?
                                                    +2
                                                    То ли дело 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 руб.


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

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

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

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

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

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

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

                                                          Но он не станет Visual Studio (= Начало конца уже положено в его технологических основах.
                                                            0
                                                            VS Code к VS имеет такое же отношение, как слово «котлета» к «коту». Не позволяйте бренду смысл затмевать, а то так еще можно случайно сказануть, что есть студия на мак.
                                                          0
                                                          Цифры действительно не лгут. А вот люди их применяющие их, вполне могут…
                                                    0
                                                    Да, я знаю про jOOQ, но ни разу не видел его использование хоть в чем-то, напоминающем продакшен. Возможно потому что это полу-платный новодел без JSR, возможно по другой причине.


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

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


                                                      Контейнеры головного мозга
                                                        0
                                                        По моему опыту отсутствие контейнеров в .net — это говнокод в 90% случаев. Статистика. :)
                                                          0
                                                          Говнокод — это не отсутствие контейнеров, а неосиливание DI.
                                                          Карго-культ контейнера от этого не спасает.
                                                        0

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

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

                                                          Это какие например?
                                                            +2
                                                            C# куда как продуктивнее Java.

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

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

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

                                                                    0
                                                                    Можете мне привести пример частого использования 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?
                                                                      0
                                                                      Не, это не про продуктивность. Про продуктивность в Java — Kotlin :) И его я тоже больше 2х лет использую в продакшне в энтерпрайзе. Там все эти костыли не нужны.
                                                                        +1
                                                                        Можете мне привести пример частого использования expression trees в кровавом энтерпрайзе?
                                                                        Составление фильтров.
                                                                          +3
                                                                          Можете мне привести пример частого использования expression trees в кровавом энтерпрайзе?

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


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

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

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

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


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

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

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

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


                                                                            @NonNull

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

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

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

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


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

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

                                                                              0
                                                                              Появилось ли что-то похожее в .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;
                                                                                      }
                                                                                  }
                                                                              
                                                                              }
                                                                              

                                                                                0
                                                                                Хоспадя, причем здесь F#
                                                                                  +1
                                                                                  Появилось ли что-то похожее в .Core?

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

                                                                                    0

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

                                                                                      +1
                                                                                      Хоспадя, причем здесь 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#?

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

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


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

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


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

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


                                                                                      Getter/@Setter

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

                                                                                        0
                                                                                        Вообще-то сработает, как минимум в Spring с этим проблем нет и это используется.
                                                                                        А работает это потому, что несмотря на type erasure, информация о типах вполне себе доступна в runtime, через reflection.
                                                                              –1
                                                                              .Net Core это попытка выкинуть платформу, разрабатываемую 15 последних лет и переписать/переосмыслить всё заново. Насколько эта идея может быть успешна в нынешних реалиях, покажет только время.
                                                                              Но то что большинство текущих проектов на .NET (не Core) внезапно стало Legacy — это факт.
                                                                                0

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

                                                                              +2
                                                                              Ох, какая холиварная пятничная статья :)
                                                                              В .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
                                                                                Наконец-то принес, спустя 15 лет. Минусов «выбора» масса — в одном проекте Unity, в другом — Autofac, в третьем StructureMap, а в четвертом NInject — и все они различаются в API и при этом одинаковые на 95%. Здесь огромный плюс джавовских JSR виден, надеюсь, всем.

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

                                                                                OWIN еще и Embended Server дает. Еще немного, и Микрософт придумают свой H2 (или уже придумали?).
                                                                                  0
                                                                                  в одном проекте Unity, в другом — Autofac, в третьем StructureMap, а в четвертом NInject — и все они различаются в API и при этом одинаковые на 95%. Здесь огромный плюс джавовских JSR виден, надеюсь, всем.

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

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

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

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

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

                                                                                        Явовские контейнеры можно конфигурировать кучей способов (сходу назову штук 5), при этом бут добавляет удобную авто-конфигурацию «из коробки». Не будьте столь категоричны, это неконструктивно и неприятно читать.
                                                                                    0
                                                                                    Для сборок еще кое где встречается старый добрый ant.
                                                                                      0
                                                                                      К счастью не застал :)
                                                                                      0
                                                                                      Вставлю и я свои 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

                                                                                      Если я в чем-то не прав то пожалуйста напишите об этом, буду рад любой информации
                                                                                      0
                                                                                      Очень неудобная настройка билдов (maven)

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

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

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

                                                                                          0
                                                                                          Да, устаревшие и я рад что сейчас на .net тоже это поменялось. Но я отвечал на комментарий, в котором упоминалась GUI для конфигов, видимо автор комментария переезжал с устаревшей версии
                                                                                            0
                                                                                            GUI при этом никуда не делся и прекрасно работает.
                                                                                            Я пользуюсь и тем и другим — смотря что удобнее по ситуации.
                                                                                            Так что у дотнета преимущество в обоих случаях.
                                                                                              0
                                                                                              Так что у дотнета преимущество в обоих случаях.

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

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


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

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


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

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

                                                                                            +6

                                                                                            Работал с 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
                                                                                              у меня сложилось впечатление что это в spring boot мне диктуют как правильно жить, как иcпользовать DI, как называть разные lifescope и тд

                                                                                              Так никто же не заставляет использовать Spring Boot, тем более на него нет JSR. Можете использовать любой другой фреймворк, коих довольно много. И это отличается от ситуации с .net, который до недавнего времени был закрытым и фактически был прибит гвоздями к Windows (энтузиасты из Mono не в счет). И хорошо, что сейчас все по другому, но почему бы не сделать этого раньше?
                                                                                              +2
                                                                                              На самом деле весь спор решается наличием вакансий на ту или иную платформу в вашем регионе. Вокруг меня количество работы на Java стремится к нулю, зато .Net цветет и пахнет.
                                                                                                +1
                                                                                                Сложно не согласиться, но вокруг меня ситуация прямо противоположная. И у автора статьи, похоже, такая же.
                                                                                                  0
                                                                                                  Рынок диктует условия. Я в универе яву учил… А потом пошел вакансии смотреть и резко пришлось платформу сменить. Так что мы все тут в одной корзине.
                                                                                                +1
                                                                                                В статье нет самого главного, чем 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# на нет.
                                                                                                  0
                                                                                                  постоянно будет ощущение неполноценности разрабатываемого кода

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

                                                                                                    0
                                                                                                    Да уж дженерики в яве сделаны отвратительно, я не могу понять почему выбрано такое странное решение.
                                                                                                      0
                                                                                                      Обратная совместимость на уровне байт-кода — иначе старые JVM не смогут в новые дженерики, а они дорожат запуском нового кода в рарихетных рантаймах.
                                                                                                        0
                                                                                                        а может добавить ключ компиляции и дать возможность мне самому решать нужна ли мне эта обратная совместимость или нет?
                                                                                                          0
                                                                                                          Тогда все сразу забьют на поддержку старых версий)
                                                                                                            0
                                                                                                            Когда это решение принималось, то это было самым простым решением. Сейчас же менять это уже поздно, и ОЧЕНЬ дорого.
                                                                                                    +1
                                                                                                    В .NET выбор очевиден — Visual Studio.

                                                                                                    Как же VS Code для .net core? Rider?
                                                                                                      0
                                                                                                      «5. Community», а может оно и лучше? Я без слез на прогресс платформы явы на фоне дотнета без слез смотреть не могу.
                                                                                                        0
                                                                                                        В высоко нагруженных проектах с mssql и радостным linq, когда начинаешь разбираться в миллионе планов, безумном их трафике и удивительной их параметризации, понимаешь, что это далеко не преимущество и так делать не нужно. Что значит отключать автокоммит инструкции и главное зачем?
                                                                                                          0
                                                                                                          Прочитал про LINQ. Интересно, хоть и дико для джависта видеть SQL в переменных.
                                                                                                            0
                                                                                                            Там есть другой вариант — использование лямбд, с которыми (если привыкнуть) код запросов становится совсем коротким, хоть и теряет в читабельности.
                                                                                                              0
                                                                                                              Почему теряет в читабельности?
                                                                                                                +2
                                                                                                                Кому-то SQL-подобный синтаксис проще читать, он более «самодокументируемый».
                                                                                                                  0
                                                                                                                  Любой код самодокументируемый, потому что иначе оно бы не работало.

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

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


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

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

                                                                                                                      0
                                                                                                                      Ок, не так выразился. LINQ-код не более и не менее понятен, чем аналогичный SQL почти всегда.
                                                                                                                        0
                                                                                                                        Может я, конечно, ошибаюсь. Но мне кажется, мы недопоняли друг друга и говорим о разных вещах. Я говорил о том, что есть 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 запрос для СУБД.
                                                                                                                          0

                                                                                                                          И то и то 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

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

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

                                                                                                                Претензия не в том, что геттеры/сеттеры сложно генерировать, а в том, что по сравнению с .Net наблюдается увеличение объёма кода. Вместо одной сущности — автосвойства, три — переменная + геттер + сеттер.
                                                                                                                  0
                                                                                                                  Как я и писал выше, для уменьшения кода применяется Lombok. К классу добавляется аннотация и после этого у всех полей появляются сеттеры и геттеры (при этом в коде класса их явно нет). Если и это напрягает, никто не мешает использовать Котлин )
                                                                                                                    0
                                                                                                                    Вплетение байт-кода вместо нормальных языковых средств — магия и костыль.
                                                                                                                    Гоферы с тем же успехом ссылаются на прости господи кодогенерацию.
                                                                                                                      0
                                                                                                                      В мире джавы мало кого смущает и генерация сеттеров IDE и Lombok, в котором магии не больше чем в Spring. Но, как уже писал выше, никто не мешает использовать Котлин, которые в обе стороны совместим с Джавой, и в котором есть все что нужно. Но, возможно, сейчас и тут напишут про проблему с дженериками.
                                                                                                                        0

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


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

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

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

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


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

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

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

                                                                                                                  PnP в конечном итоге извергло из себя Unity (не движок для игр, а контейнер), которое преподносилось в ~2010 как супер ноу-хау в т.ч. в живых семинарах в Мск. Это было как минимум забавно — ничего нового, но пафоса горы.
                                                                                                                  0
                                                                                                                  Здесь абсолютное доминирование Java-платформы. Есть два основных монстра: EJB и Spring с огромнейшей экосистемой и практиками “вокруг”… В .Net ничего этого нет.

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

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

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

                                                                                                                    И-то и то верно, вы с этим спорите что ли?
                                                                                                                      0
                                                                                                                      В .NET нет нормальной платформы для разработки ентерпрайз приложений.

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

                                                                                                                        0
                                                                                                                        a la Spring.
                                                                                                                          0
                                                                                                                          Ну то есть оригинальное высказывание было «В .NET нет Spring». Ну, возможно. Только не все вообще в курсе, что это.
                                                                                                                            0
                                                                                                                            Ну его действительно нет. Были давным-давно попытки a la Spring.NET, но оно разбилось об отсутствие Community.
                                                                                                                            Конструктивней в данном треде, увы, вряд ли получится, здесь какая-то атмосфера нездоровая — сплошные переходы на личности с двоемыслиями, define и т.д. Неинтересно.
                                                                                                                              0
                                                                                                                              Может просто стоит обосновывать такие громкие утверждения? В стиле «В дотнете нет Spring поэтому ынтырпрайз на нем не написать».
                                                                                                                                0
                                                                                                                                Если вам действительно интересно, зайдите на сайт спринга там есть features projects.spring.io/spring-framework оно всё вместе работает «из коробки». В .NET я не знаю фреймворка такого уровня зрелости (только десяток более мелких ежей-ужей которые постоянно приходится скрещивать).

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

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

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

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


                                                                                                                                    Вот рецепт приготовления 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 => ???


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

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

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

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

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

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

                                                                                                                                          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 целиком. И когда новичок придет, то он будет заниматься тем, что знает — своим делом, в своем отдельном боксе.


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

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

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

                                                                                                                                        0

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

                                                                                                                                      0

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

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

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

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

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

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

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

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


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

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

                                                                                                                                          0

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


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

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

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

                                                                                                                                              0

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

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

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


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

                                                                                                                                                  0
                                                                                                                                                  Вы действительно думаете, что в МС дурачки сидят? Две параллельные реализации были сделаны потому, что Web API стали переводить на рельсы OWIN раньше, чем MVC. Сначала избавились от зависимости от System.Web в API, а затем уже и в MVC.
                                                                                                                                                    0
                                                                                                                                                    Я думаю что МС не думает о ПЖЦ своих технологий, поэтому они часто «почкуются» и умирают.

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

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

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

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

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

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

                                                                                                                                                  Вот даже видюшку нашёл, харизматичный мужичок был www.techdays.ru/videos/3883.html
                                                                                                                                                  0
                                                                                                                                                  Под провалом odata я понимаю что практически никто за пределом .net песочницы о ней не слышал, хотя технологии ~10 лет (да и в песочнице она нечасто всплывает)

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


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

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

                                                                                                                                          0
                                                                                                                                          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. В шарпе есть пропозал, но когда его примут — неизвестно. Ну а в джаве я не ожидаю их вообще никогда.


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

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

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

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

                                                                                                                                            Java сильна точно не языком. В первую очередь обратной совместимостью и аккуратным подходом к нововведениям. И это очень ценят в бизнесе, но как следствие — медленное развитие и постоянное отставание по фичам. Кроме этого, у джавы мощная инфраструктура и наличие открытых библиотек на все случаи жизни.
                                                                                                                                            Если не нравится Java именно как язык, то можно посмотреть в сторону Котлина. Получите современный язык, который стремительно развивается + из коробки все наследие Java.
                                                                                                                                              +1
                                                                                                                                              Выше уже писали, те же дженерики — это критический недостаток не то что джавы, а рантайма. Как следствие хотя Котлин и выглядит клевым, под капотом происходит все то же самое, и нет-нет, да вылезает за пределы аккуратных абстракций. Хотя он шажище вперед, никто не спорит.
                                                                                                                                                –2
                                                                                                                                                Опять слышу про дженерики… Чем оно лично вам «критическое»-то? Может всё-таки не в дженериках дело? :) Object он и есть Object никаких супер-оптимизаций «серебряная пуля» — не бывает.

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

                                                                                                                                                  Ну это логично. Его разрабатывает JetBrains, которые свои инструменты исторически пишут на Java. Но Java как язык их не очень устраивает своей архаичностью, а Scala своей загонностью (как альтернатива), решили сделать свой, с фирменным тулингом.
                                                                                                                                                  По поводу CLR, по моему, Андрей Бреслав говорил что CLR не выбрали потому, что смысла нет. C# по возможностям близок Котлину, т.е. Котлин если и лучше в чем-то, то не настолько чтобы люди захотели на него пересаживаться. Поэтому выбрали JVM и JavaScript как платформы для старта.
                                                                                                                                                    0
                                                                                                                                                    огда наш гипотетический Блаб-программист смотрит вниз на континуум мощности языков, он знает, что смотрит вниз. Менее мощные, чем Блаб, языки явно менее мощны, так как в них нет некой особенности, к которой привык программист. Но когда он смотрит в другом направлении, вверх, он не осознает, что смотрит вверх. То, что он видит, — это просто «странные» языки. Возможно, он считает их одинаковыми с Блабом по мощности, но со всяческими сложными штучками. Блаба для нашего программиста вполне достаточно, так как он думает на Блабе.
                                                                                                                                                    0
                                                                                                                                                    Вот тоже не понимаю, почему столько внимания в комментариях уделено проблеме с дженериками, причем обычно от людей, которые пишут на C#. Писал и на шарпе и на джаве, за все время сталкивался несколько раз. Т.е. не могу сказать, что как перешел на Джаву так сразу type erasure стало мешать жить. Ну неудобно, да. Но вот чтобы критично… Вот, например, многословность Джавы лично меня напрягает куда больше.
                                                                                                                                                      –1

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

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

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

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


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

                                                                                                                                                            0
                                                                                                                                                            ideone.com/eaT4pl

                                                                                                                                                            Почему-то первыми ругать жаву за стирание типов набегают те кто понятия не имеет что именно стирается.
                                                                                                                                                              0
                                                                                                                                                              А что сломалось-то?
                                                                                                                                                    –2
                                                                                                                                                    Плюсую. Модули Java 9 — колоссальнейшая многолетняя работа по модуляризации и перепиливанию всей платформы.
                                                                                                                                                    Микрософт за это время успел выкинуть старый .NET.
                                                                                                                                                    0
                                                                                                                                                    Так же перешел на 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 удивил, например (а что, так можно было?)
                                                                                                                                                      0
                                                                                                                                                      Так же перешел на java после десятка лет на .net.

                                                                                                                                                      А какова причина перехода, если не секрет?
                                                                                                                                                        0
                                                                                                                                                        Дорос до проектов и компаний в которых фундаменталка, кругозор и знание предметной области важнее знания конкретных языков и фреймворков. В конце очередного собеседования узнал, что писать надо будет под JVM. Согласился. Уже больше года полет нормальный :)
                                                                                                                                                      0
                                                                                                                                                      писал на джаве и скажу что с.нет работать проще, кода можно писать меньше, магии правда больше, но обычно.нет библиотеки более продуманные и в исходники почти не надо лезть, в джаве это приходилось делать постоянно, для разнообразия пробовал сделать свой проект на разных языках используя фреймворки которыми не пользовался ранее и самым простым оказался node.js потом с# и джава оказалась самой неудобной и дольше всего писал и опять пришлось лезть в исходники, одно в джаве хорошо remote debug который настраивался намного проще чем в.нет

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