антиесли кампания

int i;
for (i = 0; i < ARRAY_SIZE; ++i)
{
  myArray[i] = VALUE;
}

я думаю, что это лучше, чем

int myArray[10] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5...

, упаковывают размер изменений массива.

29
задан Andrew Siemer 22 July 2009 в 19:49
поделиться

15 ответов

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

РЕДАКТИРОВАТЬ: Кроме того, как указывали другие, вы должны использовать полиморфизм (если он доступен ), когда вы используете операторы if для проверки типа объекта, но операторы if сами по себе являются очень полезными и фундаментальными конструкциями.

59
ответ дан 28 November 2019 в 00:32
поделиться

... Что?

Я не могу представить, как сделать что-то подобное без какого-либо сравнения. Вообще.

Я могу себе представить кампанию анти-goto, но она мне кажется чертовски необходимой структурой потока управления.

6
ответ дан 28 November 2019 в 00:32
поделиться

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

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

Я не уверен, что полиморфизм - правильный ответ на этот вопрос.

1
ответ дан 28 November 2019 в 00:32
поделиться

Быть противником if - это глупо.

Иногда замена условного выражения через полиморфизм является правильным решением, но в этих случаях это не было оператором if это была настоящая проблема. Настоящая проблема заключалась в работе с абстрактными типами не абстрактными способами, то есть в неспособности мыслить на уровне абстракции базового класса.

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

Но чаще всего оператор if не имеет ничего общего с полиморфизмом.

23
ответ дан 28 November 2019 в 00:32
поделиться

Операторы переключения часто можно заменить полиморфизмом:

abstract class WidgetBase {
  public abstract void DoSomething();
}

class Widget1 : WidgetBase {
  public override void DoSomething() {
    // Do something ...
  }
}

class Widget2 : WidgetBase {
  public override void DoSomething() {
    // Do something ...
  }
}

...

Widget widget = new Widget1(); // Use a factory pattern instead.
widget.DoSomething();
14
ответ дан 28 November 2019 в 00:32
поделиться

Вы можете использовать Командный шаблон для выполнения команд на основе некоторых значение или ввод.

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

var commands = new Dictionary<WidgetTypes, Action>()
    {
        { WidgetTypes.Type1, () => Console.WriteLine("Type 1") },
        { WidgetTypes.Type2, () => Console.WriteLine("Type 2") },
        { WidgetTypes.Type3, () => Console.WriteLine("Type 3") },
        { WidgetTypes.Type4, () => Console.WriteLine("Type 4") }
    };

commands[WidgetTypes.Type1]();

public interface ICommandHandler
{
    void HandleCommand();
}

public class Command1Handler : ICommandHandler
{
    public void HandleCommand()
    {
        Console.WriteLine("Type 1");
    }
}

// ...

var commands = new Dictionary<WidgetTypes, ICommandHandler>()
    {
        { WidgetTypes.Type1, new Command1Handler() },
        { WidgetTypes.Type2, new Command2Handler() },
        { WidgetTypes.Type3, new Command3Handler() },
        { WidgetTypes.Type4, new Command4Handler() }
    };

commands[WidgetTypes.Type1].HandleCommand();

И бонусный метод отражения для вызова метода для текущего объекта с тем же именем:

public void Type1()
{
    Console.WriteLine("Type 1");
}

//...

var type = WidgetTypes.Type2;
typeof(MyClass).GetMethod(type.ToString()).Invoke(this, new object[] { });

Примечание: на самом деле этого не делают

12
ответ дан 28 November 2019 в 00:32
поделиться

Не беспокойтесь о простом операторе if или прямом операторе switch.

Беспокойтесь об этом:

  1. Ужасно вложенные операторы if (антипаттерн Arrowhead). Эти вещи невозможно читать и отлаживать.
  2. if (или case) с множеством строк кода в них. "Хорошо, мы делаем то и это .... в этом случае, и то, и то ... в этом случае. Также очень трудно читать. Практически невозможно проверить или отладить.
  3. Сверхсложные условия: if (Bow И кухонная раковина, или ванна, И ...). Что вы снова тестируете? Оберните это в метод - в данном случае: CanHoldWater ().
6
ответ дан 28 November 2019 в 00:32
поделиться

Это зависит от того, как вы справляетесь с ситуацией. Если вы вызываете другую функцию, используя ту же сигнатуру, у вас может быть словарь, в котором ключ будет типом и значением, которое делегат указывает на реальный обработчик. Таким образом, вы можете избавиться от переключателя и просто выполнить

_myDictionary[ _myType ]( param1, ... );
3
ответ дан 28 November 2019 в 00:32
поделиться

Реализовать эту идею на C-подобном языке очень неубедительно ... но на правильном функциональном языке с защищенным сопоставлением с образцом это смею добавить, гораздо более идиоматический и более богатый способ выражения условных выражений.

2
ответ дан 28 November 2019 в 00:32
поделиться

Полиморфизм - правильный путь, когда логика должна быть встроена в классы.

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

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

Я не говорю о прямом внедрении исходного кода в базу данных varchar () и компилируем его на лету.

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

В мире, где только код, у вас будет подкласс для каждого типа поля, каждое из которых реализует, скажем, это '

2
ответ дан 28 November 2019 в 00:32
поделиться

Вау ... это на самом деле?

Вы можете попробовать перехватить абсолютно все возможные исключения, когда вы выберете неправильный путь выполнения, пока не попадете в путь выполнения, который НЕ нарушает , но это НАМНОГО хуже, чем если бы.

Вы можете использовать шаблон Command или Map, когда объектная ориентация и полиморфизм естественны, но что, если вы имеете дело с результатами пользовательского ввода, которые являются сложными и НЕ входят в сами по себе объекты?

1
ответ дан 28 November 2019 в 00:32
поделиться

Операторы case отлично подходят для организации вложенных if.

0
ответ дан 28 November 2019 в 00:32
поделиться

Думаю, я понимаю, что они означают. Мы, вероятно, не выживем без if и переключателей, но верно , что глубоко вложенные условные блоки трудно читать.

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

Я придумал шаблонная структура кода, которая позволила мне «объявлять» нужные функции (около 30 или около того) вместо того, чтобы объединять их в одну процедуру диспетчеризации.

Это позволило нам очень быстро добавлять новые варианты параметров конфигурации , и вроде как "копия" уравнения из математического обзора. Действительно, неплохая победа.

0
ответ дан 28 November 2019 в 00:32
поделиться

В Java легко использовать перечисления в качестве полиморфных агентов против if.

public class AntiIf {
  public enum WidgetTypes {
    Type1 {
      public void doSomething() {
        //...
      }},
    Type2 {
      public void doSomething() {
        //...
      }},
    Type3 {
      public void doSomething() {
        //...
      }},
    Type4 {
      public void doSomething() {
        //...
      }};

    public abstract void doSomething();
  }

  WidgetTypes _myType; // set by someone to one of the types.

  public void someFunction() {
    //...
    _myType.doSomething();
    //...
  }
}
35
ответ дан 28 November 2019 в 00:32
поделиться
Другие вопросы по тегам:

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