Pull to refresh
-3
0

Пользователь

Send message
Таких котлет и ноутбуков — вагон и тележка.
Обычай предписывает использовать для этого out-параметры

out-параметры — это минорная фича, необходимость в которой возникает крайне редко. Я не знаком с историей её возникновения, но предположу, что на 90% мотивация была — байндинги для сишного кода. Очень многие функции WinAPI возвращают «полезный результат» через параметр, а возвращаемое значение используют для кода возврата. Это традиция из культуры C — там нет исключений, поэтому возникает та самая интересная ситуация когда нужно и код возврата сообщить, и полезные данные вернуть. В Java, например, out-параметров вообще нет — проблем с этим не возникает.

В С++ есть функции, возвращающие пару — например, итератор и флажок при вставке в set.
Предложите, как пересмотреть ответственности для них.

У стандартной библиотеки C++ своя уникально-экзотическая философия из которой органично вытекает этот неповторимый извращённый дизайн. Во многих других мейнстримных языках аналогичный метод возвращает bool и сложностей ни у кого не возникает.
Вы считаете, что если сущность шарится между методами, то она важна.

Т.к. сущность шарится между методами, она является частью внутреннего интерфейса. Интерфейс — важен, будь он внутренний или внешний.

Вы правда мне предлагаете выделять новый тип данных?

Да, я предлагаю не мудрствовать, а просто взять и выделить новый тип данных. Не обязательно так громко, как вы описали: если речь идёт про реализацию одного единственного класса, достаточно сделать внутренний класс. Хотя, вообще говоря, и от лишнего файла Земля не остановится.

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

Наоборот. В голове намного проще удержать сущность, если у неё есть имя. Удержать в голове «ту штуку, в которой лежат a, b и c» — намного сложнее, т.к. вы не поднимаетесь выше a, b и c — они как были отдельными компонентами, так и остались.
если нужно вернуть просто два значения, никак не связанных между собой

Если возникает необходимость вернуть 2 значения, никак не связанных между собой, стоит пересмотреть ответственности, возложенные на метод. Предложите пример такого метода — интересно чем вы будете руководствоваться придумывая для него имя.
Магазину «Котлеты и Ноутбуки» срочно требуется определиться
1) Либо один большой говнометод
2) Много непонятных data-классов, которые нужны только в пределах двух-трех методов
3) Либо код будет содержать Tuple/KeyValuePair, что вообще читабельности не добавляет.

Всё верно — если программист решая задачу сталкивается с выбором из этих 3 пунктов, очевидно он сам не понял что напрограммировал. Есть большая разница между «кодом, который выдаёт нужные результаты» и «кодом, который решает задачу»: в первом случае просто проходят тесты, а во втором — в явном виде описываются намерения: вводятся термины, связи между ними, и уже в контексте этого небольшого «под-домена» описывается решение задачи.

Обратите внимание, ваше описание решаемой проблемы начинается с фразы «Вот пишешь ты метод, в нем юзаешь анонимный тип» — проблема появляется уже здесь, а не в момент «extract method»: вы посчитали, что «вот эта сущность» недостаточно важна, чтобы вводить её в явном виде, и ввели неявно. На следующем шаге вы об этом начинаете горько сожалеть, т.к. выясняется, что именно эта сущность связывает несколько частей решения задачи.
Вы бы лучше пример кода привели, чтобы показать где эта конструкция выигрывает по сравнению с явным типом. Что такое кортеж — вполне понятно. Также понятно какие проблемы будут возникать при его использовании. Что непонятно — какие проблемы он решает.
Кортежи — это очень спорная фича, особенно для языка со статической типизацией. Если раньше не-очень-хорошим-программистам приходилось напрячься, чтобы вводя новую сущность в коде дать ей внятное название, теперь они вообще напрягаться не будут прикрываясь «использованием языка на всю катушку».

list.Add("John Doe", 66); // Такое добавление данных в лист не может не радовать

Это как раз хреновый пример, который воспринимается на порядок хуже, чем длинное скучное:
list.Add(new Person 
{
  Name = "John Doe",
  Age = 66
});
Spring Boot делает ровным счётом то же самое, что вы описали в статье, но при этом позволяет использовать конфигурацию «по умолчанию» до тех пор, пока не требуется шаг в сторону. Как только возникает необходимость сделать шаг в сторону — достаточно в явном виде сконфигурировать только этот самый шаг и ничего больше.

В обоих случаях — и у вас, и в Spring Boot, декларируется «opinionated» подход: «конфигурация — вот такая, и это — данность», но разница заключается в том, что Spring Boot — это огромное комьюнити с документацией, туториалами, статьями, примерами и видео на YouTube, а в вашем случае — эксклюзивный вариант конфигурации Spring «под себя» — с лично вашей мотивацией, вашими ценностями, и пониманием что хорошо, а что плохо.
А зачем это всё, если уже изобрели Spring Boot?
Да ладно вам, я вот взял термин «сферическое миросозерцание» на заметку.
А снизу от списка тегов указаны «автор оригинала» и «автор поста».
Удалено — слишком долго писал.
Очень интересно было бы узнать мотивацию.

Для Puppet есть вот такие штуки:
forge.puppetlabs.com/simondean/iis
forge.puppetlabs.com/opentable/iis

Даже для MSBuild есть вот такая штука:
github.com/mikefourie/MSBuildExtensionPack/tree/master/Solutions/Main/IIS7

Был какой-то смысл своё делать?
Забавно, что двумя комментариями выше я предложил этот же самый вариант, но, кажется, был непонят.
Вы сразу несколько переходов сделали. Действие: «запустить ракету». Результат действия: «запуск ракеты» (читать как «один запуск ракеты»). В моём примере было действие: «сложить 2 числа», результат действия: «сумма двух чисел».
Самый простой и сравнительно честный способ оформлять «действия» в REST — вводить ресурс, представляющий результат этого действия:
Пример
// Это не REST
POST /AddNumbers
{
  "a": 2,
  "b": 3
}

ответ:
{ "result": 5 }


// Это REST
POST /NumberSums
{
  "a": 2,
  "b": 3
}

ответ:
201 - created
Location: /NumberSums/uhfweiufhi234uhr23e42342

далее:
GET /NumberSums/uhfweiufhi234uhr23e42342
{
  "value": 5
}

Статья называется «Простой webdev на Java 8». Расскажите пожалуйста, какие фичи Java 8 кроме единственного применения functional interfaces при регистрации маршрутов вы используете? Также интересно, если Spark, требующий Java 8, чем-то принципиально отличается от Spark, не требующего Java 8. Также интересно, если ORMLite имеет какое-то отношение к Java 8 — например умеет работать с Optional или CompletableFuture.
Компоненты, которые предложил ТС не простые, а именно примитивные. При чтении статьи удивление должно начинаться с фразы:
тем более что позитивный опыт работы с Express уже был

Express — это вообще не веб-фреймворк, это паттерн проектирования «декоратор», который хостится на HTTP-сервере, не более.
Ну не совсем. Давайте я в лоб вопрос задам. Почему не Spring Boot?

Конкретно про Hibernate vs. неHibernate: spring.io/guides/gs/accessing-data-jpa/ — где-то там внутри используется Hibernate, но вам его не видно. Код даже проще, чем ORMLite, при этом если Hibernate однажды понадобится — он тут как тут, а если не понадобится, то и ладно.

Примерно аналогичным образом хочется спросить про Spark. Есть же совершенно замечательный Spring MVC, который тоже поднимается в 3 строчки через Spring Boot: spring.io/guides/gs/rest-service/ — снова, кода столько же.

Остаётся jade4j, для которого есть интеграции со Spring опять же.

Кроме перечисленного, вы ещё в довесок получаете замечательный IoC-контейнер, благодаря которому избавляетесь от непонятного DbUtils со всеми его вызовами DaoManager.createDao.

Итак, почему не Spring Boot? :-)
Расскажите пожалуйста немного больше о вашем требовании:
Библиотеки должны быть легковесны

Как отличить легковесную библиотеку от нелегковесной? Какие минусы у нелегковесных библиотек?
О, спасибо. Если я правильно понял, можно предложить более простую иллюстрацию:
Пример на Java
class NumberAdder {
  private final int a;
  private final int b;

  public NumberAdder(int a, int b) {
    this.a = a;
    this.b = b;
  }

  public int addNumbers() {
    return a + b;
  }
}

// в вызывающем коде:
...
NumberAdder numberAdder = new NumberAdder(2, 3);
int result = numberAdder.addNumbers();

// или даже:
...
int result = new NumberAdder(2, 3).addNumbers();


Несколько раз встречал такой подход в коде коллег. На вопрос «зачем?» внятного ответа ни разу не получил, предпочитали молча переделать.

Information

Rating
Does not participate
Location
New Jersey, США
Date of birth
Registered
Activity