Удобочитаемость тяжелого вложения вызова функции?

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

// Totally unreadable:
auto linesIter = filter!"a.length > 0"(map!strip(File(filename).byLine())))


// Perfectly readable.  The only difference is formatting.
auto linesIter = filter!"a.length > 0"(
    map!strip(
         File(filename).byLine()
    )
);

// Readable, but unnecessarily verbose:
auto rawLines = File(filename).byLine();
auto stripped = map!strip(rawLines);
auto filtered = filter!"a.length > 0"(stripped);

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

for(i = 0; i < 10; i++) { for(j = 0; j < 10; j++) { if(x < 2) { z++; } else { y++; }}}

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

5
задан 2 revs, 2 users 100% 10 October 2011 в 02:04
поделиться

4 ответа

ImmutureList подобен Collections.unmodifyList (новый ArrayList (список)) . Обратите внимание, что вновь созданный ArrayList не назначен полю или переменной.

-121--1065016-

Не используйте систему Source Safe! Это не только плохо для системы управления версиями, но и плохо для всего мира.

Я использую Subversion с черепахой. Мне очень нравится. Довольно легко встать и бежать. Ветвление/слияние все еще может быть кошмаром.

Визуальный SVN тоже хорош.

-121--3227025-

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

0
ответ дан 14 December 2019 в 19:12
поделиться

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

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

В вашем примере 2 нет ничего плохого, но он намного длиннее, и я бы его, конечно, разобрал. Поблагодарите себя за отладку ...

2
ответ дан 14 December 2019 в 19:12
поделиться

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

public abstract class Spell
{
   public string Name { get; set; }
   public int ManaCost { get; set; }
   public Spell(string name, int manaCost)
   {
      Name = name;
      ManaCost = manaCost;
   }

   public void Cast(Creature caster, Creature targetCreature)
   {
       caster.SubtractMana(ManaCost); //might throw NotEnoughManaException? 
       ApplySpell(caster, targetCreature);
   }

   protected abstract void ApplySpell(Creature caster, Creature targetCreature);
}

Кроме того, должен ли Wizard расширить StartCharacter, который бы расширил Существо?

-121--2970310-

После прочтения первой части связанной статьи мне не понравились две вещи:

  • реализации определены в интерфейсе (с помощью @ Mixins ) - что, если над ними следует издеваться, или реализации изменены?
  • требует кастинга

Не имея опыта с Qi4J, не могу сказать, как это получается на практике,

-121--2964736-

Я предпочитаю не использовать слишком много переменных b/c они часто являются источником ошибок. Если я могу выразить что-то как одно выражение, я предпочитаю это так. Я бы, наверное, пошел с твоим вторым примером.

0
ответ дан 14 December 2019 в 19:12
поделиться

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

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

1
ответ дан 14 December 2019 в 19:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: