Используется для синтаксиса цикла для «с (переменным)» блокировать анти-шаблон?

Я обманул себя с помощью for -loops, вспомнил with из delphi и придумал следующий шаблон (определенный как живой шаблон в IntelliJ IDEA):

for ($TYPE$ $VAR$ = $VALUE$; $VAR$ != null; $VAR$ = null) {
    $END$
}

Должен ли я использовать его в продуктивном коде? Я думаю, что это может быть удобно для создания временных переменных быстрого доступа, таких как эти односимвольные переменные в lamdas и couting для циклов. Кроме того, он проверяет, будет ли переменная, которую вы собираетесь использовать в блоке, сначала null. Рассмотрите следующий случай в приложении swing:

// init `+1` button
for (JButton b = new JButton("+1"); b != null; add(b), b = null) {
    b.setForeground(Color.WHITE);
    b.setBackground(Color.BLACK);
    b.setBorder(BorderFactory.createRaisedBevelBorder());
    // ...
    b.addActionListener(e -> {
        switch (JOptionPane.showConfirmDialog(null, "Are you sure voting +1?")) {
            case JOptionPane.OK_OPTION:
                // ...
                break;
            default:
                // ...
                break;
        }
    });
}
6 голосов | спросил Binkan Salaryman 12 42015vEurope/Moscow11bEurope/MoscowThu, 12 Nov 2015 17:10:13 +0300 2015, 17:10:13

2 ответа


33

Это не анти-шаблон, потому что это будет означать, что это часто используемый метод, который как-то проблематичен. Этот код не соответствует критерию «обычно используемый».

Однако это проблематично. Вот некоторые из его проблем:

  • Вводящий в заблуждение: он использует структуру цикла, но никогда не выполняется более одного раза.
  • Скрытие проверки: проверка! = null легко пропустить, где она размещена. Скрытый код сложнее понять. Также неясно, действительно ли условие действительно необходимо или просто прекратить цикл после первой итерации. (Ваши заявления о проверке показывают, что у вас есть ситуации, когда это необходимо, тогда как в вашем примере это не так, поскольку new никогда не возвращает null.)
  • Скрытие действия: оператор add (b) спрятан еще лучше. Это даже не последовательно в том месте, где вы ожидаете.
  • Ненужное: вы можете просто объявить локальную переменную. Если вы не хотите, чтобы его имя было видимым, вы можете использовать оператор блока, чтобы ограничить его область действия, хотя , что будет анти-шаблоном (или, по крайней мере, запахом кода), что указывает на то, что вы должен извлечь функцию.
ответил Sebastian Redl 12 42015vEurope/Moscow11bEurope/MoscowThu, 12 Nov 2015 17:22:47 +0300 2015, 17:22:47
29

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

{
    JButton b = new JButton("+1");
    b.setForeground(Color.WHITE);
    ...
}

Если вы используете lambdas, вы также можете определить статическую функцию with, которая позволяет использовать такие функции, как

with(new JButton("+1"), b -> {
    b.setForeground(Color.WHITE);
    ... 
});

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

ответил amon 12 42015vEurope/Moscow11bEurope/MoscowThu, 12 Nov 2015 17:24:10 +0300 2015, 17:24:10

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

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132