За пределами уютного стека .Net

Не знаю, может мне это все кажется, но в стеке .Net у нас – тех кто занимается .Net’ом с самого начала – начался какой-то процесс насыщения. Мне кажется это сродни ситуации когда сидишь на рейте OVER$100 и несмотря на то что ты пашешь 50 часов в неделю, тебя уже все устраивает и не к чему стремиться. В этом посте – мои умозаключения на тему того, что же нам всем бедным делать с нашим crise de foie.

Все действительно так хорошо?

Дотнет нужно рассматривать в разрезе и сравнении. По сути дела, дотнет – это языки, библиотеки и среда разработки. Можно пробовать классифицировать это по-другому, но мне нравится именно так. И что же мы, собственно, имеем?

Начнем с языков – а точнее с языка. Я уже писал на тему того, что мало языков нынче предоставляют реальную альтернативу C#. Другие языки полезны с точки зрения академических познаний, но посмотрев, например, на то как пишутся плагины для ReSharper на F#, я не могу сказать что для меня этот язык стал чем-то более чем хорошей зарядкой для мозгов.

Теперь насчет библиотек. Тут тоже все прекрасно – может у нас не такой развитый open source как в Java-стеке, но специфика нашего стека в том, что у нас есть Microsoft. Поэтому никого не должно удивлять что даже когда на рынок выходит Asp.Net MVC, этот фреймворк с запозданием в несколько лет (!!!) может показать себя лучше, чем OSS-альтернативы.

Ну и наконец IDE. С высоты птичьего полета может показаться, что Visual Studio дает нам абсолютно все что может оказаться полезным, а также дает нам через VSSDK дописать что-то чего мы не получаем ootb. Лично я провел большинство моего разрботческого времени под студией, и с ностальгией вспоминаю времена MFC, ClassWizard’ов и иже с ним.

Языки – есть ли смысл?

Знать один язык и писать на нем – это очень хорошо. Проблема с языками в том, что когда нужно выражать более сложные, запутанные идеи, мы как пользователи ООП-языков вынуждены оперировать приевшимися парадигмами – наследованием, полиморфностью, инкапсуляцией. И это уже совсем не модно, т.к. типичная мало-мальски сложная задачка – это не академичный пример по использованию классов, а “один большой суп”.

Я считаю, что единственная возможность варить этот “большой суп” – это передвинуть уровень абстракции хотя бы на один уровень вверх. Причем повысить его не путем создания какого-то шаблонно-типового решения вроде языка XAML, а повысить его в контексте своего, индивидуального проекта. Тут толком не важно что использовать: АОП, внутренние DSLи, кодогенерацию – все приемлимо.

Еще одна идея, с которой я периодически балуюсь – это идея loose coupling. Ну, сама концепция стара как мир, конечно, но только в контексте всяких там интерфейсов, IoC-контейнеров, и так далее. Все равно, зависимость от интерфейса – это тоже зависимость. Я говорю скорее про нечто в стиле ROC (ресурсно-ориентированного программирования) и про идею отделения архитектуры от реализации.

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

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

Про библиотечные решения

Давайте начистоту – что у нас сейчас в дотнете действительно fun? Нет, ну серьезно. Мне лично в голову пришло весьма небольшое количество вещей – например TPL или Reactive Extensions. Помимо этого, есть еще масса просто полезных библиотек, но сказать чтобы было что-то такое “вау” я не могу.

Проблема на самом деле не столько в отсутствии библиотек, сколько в их достаточно слабой совместимости. Возвращаясь к идее про ROC, мораль в том, что единый language-agnostic контейнер может координировать взаимодействие языков (а следовательно – технологий). Точнее наверное не совсем так – это контейнер может координировать взаимодействие всего что угодно, то есть всего, что является ресурсом – будь то сервис или XSLT-трансформация или HTML-файл.

Это очень хорошо в теории. На практике же, даже такие инфраструктуры, сколь полезными бы они не являлись, все равно ограничивают свой стек, например завязывая его под Java или .Net. Понятное дело что можно использовать REST или еще какой-то механизм для взаимодействия, но это уже серьезный недостаток – ведь тогда мы снова теряем заветную идею разделения архитектуры и реализаций, о которой все так мечтают.

Среда обитания… то есть разработки

Думаю глупо спорить, что какой-нибудь Notepad вряд ли сравнится с полноценной IDE вне зависимости от языка программирования (только если это не Brainfuck). Но несмотря на это, типичная IDE – это динозавр. Да, этот динозавр научился рефакторить и повысил нашу эффективность раза в полтора (не больше). Но реально он остался тем же, кем всега и был – текстовым редактором.

Вы когда-нибудь наблюдали ситуацию, когда в файле столько кода (методов, полей и т.п.), что ничего не понять – даже не понять что с чем взаимодействует? На самом деле, проблема этого проста до безумия: просто сейчас весь код нам выдается в вертикальной проекции: один метод над другим, и так далее. Мне кажется (я не эксперт, конечно), что этот метод представления уже устарел.

C другой стороны, программирование на sequence-диаграммах – это тоже фееричный бред и пустая трата времени. Их не только сложно читать, но вы еще и не поймете какой же код генерируется в результате всех этих вызовов. При этом идея-то в принципе хорошая. Наша 2010я студия уже научилась генерировать такие диаграммы из кода, что всяко лучше чем вся остальная поддержка UML, которая, согласитесь, без round trip просто бесполезна.

Мое предложение, которое вы сможете лицезреть в ActiveMesa Domain Workbench, заключается в том, чтобы, во-первых, попытаться перевести все алгоритмичные действия в функциональный ключ и, во-вторых, моделировать взаимодействие между функциями как графы. Мне видятся несколько положительных аспектов в таком подходе, а именно:

  • Последовательность действий наконец-то можно отследить и понять. Графы – если только вы не наделали месиво в стиле “все вызывают всех” – простая визуализация, которая понятна человеку даже без особого знания UML. Если использовать для нодов визуализацию – можно на них показывать документацию к методам. Тем самым, мы редуцируем код к читабельной блок-схеме.
  • Граф из функций автоматически параллелизуем путем топологической сортировки. Главное – это пометить то, какие параметры куда переходят и какие существуют временные зависимости между методами. Параллелизовывать этот код, конечно, будем не мы, а тот кто проводит “оркестровку”, то есть непостредственно вызов. Интересной особенностью является, например, то, что имея механизм универсального проброса какого-нибудь AsyncEnumerator через всю иерархию (напомню, что мы сидим “уровнем выше”), мы сможем гарантировать ситуацию, в которой уважается как требование параллелизовать все что можно, так и желание использовать APM-модель там, где это уместно.
  • Подобный конструкт может работать через парадигму ROC, в результате чего в нодах графа может инкапсулироваться алгоритм на любом языке программирования (который поддерживает ядро). Также туда могут попасть и ресурсы. Следствием всего этого является то, что получая максимальную гибкость в плане выбора метода реализации того или иного сервиса, мы тем не менее не теряем контроль над взаимодействиями этих сервисов.

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

23 responses to “За пределами уютного стека .Net”

  1. ROC может умереть не родившись по целому ряду причин, начиная от того, что это просто сложно отлаживать, заканчивая тем, что это на самом деле может работать оооочень медленно, действительно медленно, br по смещению в функции и рекурсивный вызов гиганского словаря роутинга, потом поиск обработчика, потом поиск трансформатора это вещи даже не одного порядка и всё это в рантайме каждый раз, компилируешь то ты один раз. Тем более что занимает больше всего при компиляции? Правильно – кодогенерация и все вещи которые с ними связаны. Проекты без неё, которые просто используют другие бинарные библиотеки компилируются мгновенно.

    1. Погоди, но насколько я понял в том же NK работает кэширование, которое (наверное) сможет оптимизировать процесс роутинга. Обработчика тоже искать не надо – он зареген в modules.xml, и тебе нужен максимум один проход чтобы понять, кто же обрабатывает определенный verb.

      1. да, но статических связях это просто call instance…

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

      3. Да, но сделать это только 1 раз :)

      4. А нифига. Взять web mining в котором 10 элементов инфраструктуры и алгоритм обхода который может меняться хоть ежедневно. А еще ты забыл про банальный фиксинг багов и расширение функционала.

  2. Станислав Avatar
    Станислав

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

    1. Это тоже вариант – я в свое время баловался FPGA/VHDL. А “кризиса” как такогого нет – просто есть усталось от того что уже все пройдено, и что любая новинка (например в C#) моментально поглощается и не приносит такой радости как раньше.

      1. Станислав Avatar
        Станислав

        Можно влиться в движение OpenSource на том же линуксе. Сделать, например, нормальные слои в Paint.NET… допилить что-нибудь :) А вообще… Тут лучше всего вообще увлечься не программированием, а чем-то другим. Например, поездками в Китай или Тибет :) Я, если честно, вообще от программирования устал, хотя мне всего 25 лет. Начинал в 7 классе, потому и устал. Берешься за любую программу. Снаружи все разное, а внутри – одно и то же.

  3. > моделировать взаимодействие между функциями как графы
    Последнее время занимаюсь на работе как раз именно этим.
    Есть граф, есть симулятор, что-то бегает, снимаются метрики и тд.
    У идеи создания программ рисование графа очень много противников, по разным причинам. Медленно, неудобно, код превращается в такого же динозавра.
    Зато автоматическое распараллеливание – это да. Борьба со сложностью. Тестирование.
    Основной вопрос в том, чтобы предоставить удобную среду для создания подобных графов. Если это будет не удобно – идея, при всех своих плюсах, загнется.

    1. Станислав Avatar
      Станислав

      Отношусь к таким вещам с подозрением, потому как то что получается от графов этих, распараллеленное, еще не факт что будет работать быстрее чем обычный код, оптимизированный ручками :) А программировать картинками… ну как-то… Не создается ощущения что не контролируете процесс?

      1. Ну тут распараллеливание не центральная фича. Главное – это возможность визуализировать алгоритмы. Иначе говоря, я предлагаю визуальный DSL для архитектуры, в то время как сами компоненты остаются кодом, только написанным в функциональном стиле.

      2. WF – это не о том же?

      3. Ну в принципе да, это сравнимые вещи.

      4. Возможность пролезть к кишкам никуда не девается :)
        Каждая вершина графа – какая-то функция на С.

        Программирование превращается в проектирование. Отдельно можно писать код, отдельно высокоуровневый алгоритм.

        Распараллеливание – ну тут смотря как граф маппить на железку/платформу/CPU. В общем, это тоже хорошая тема для обсуждения. Просто при работе с графами возможностей для автоматического распараллеливания значительно больше. Отчасти о функциональном программировании в последнее время активно заговорили именно по этой причине.

  4. Может усталость от языка можно перебить тем, что вместо погружения в глубины возможностей языка и сопуствующих ему технологий и идеологий погрузится в проект в какой-то суперглубокой и сложной предметной области? И усталость рукой снимет и все наработки по языку как раз придутся кстати. Что скажете?

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

  5. Это периодическое и проходящее. У самого иногда работая над очередным проектом возникает желание представить весь проект в виде диаграммы(желательно одной), так чтоб было всё чётко, прозрачно и понятно. Пробовал, но удобство работы с диаграммами быстро падает при увеличение их количества.

    1. Но иногда это сигнал что неправильно делаешь архитектуру.

  6. http://habrahabr.ru/blogs/net/105848/
    Кстати, интересный пост на Хабре. Честно говоря, я так и не понял, что конкретно не понравилось автору — больше похоже на рассуждения религиозной тематики.

  7. Спасибо, интересно. Но половину, а может и больше не понял)

  8. Кризис всегда будет, пока мы ставим не на те вещи. Вещи которые могут меняться, останавливаться, умирать и.т.д. Тоже самое можно сказать и про брак, например. Знаешь уже жену как облупленную, никаких сюрпризов, всё предсказуемо.

    1. Ну я бы не сказал что у нас прям кризис. Кризис – это когда все плохо, а у нас скорее все хорошо.

Оставить комментарий