Каков наилучший подход для реализации этого алгоритма? - PullRequest
0 голосов
/ 06 апреля 2011

Как лучше написать такой алгоритм, как:

if (a) {
  doA();
  done();
}
else if (b) {
  doB();
  done();
}
else if (c) {
  doC();
  done();
}

другой подход, который я подумал:

done = true;
if (a) {
  doA();
}
else if (b) {
  doB();
}
else if (c) {
  doC();
}
else {
  done = false;
}
if (done) {
  done();
}

Что лучше? Есть ли другой лучший подход?

Ответы [ 6 ]

3 голосов
/ 06 апреля 2011

Без какого-либо контекста наиболее естественный для меня способ выглядит так:

bool do_it(int condition)
{
    switch (condition)
    {
        case a: doA(); return true;
        case b: doB(); return true;
        case c: doC(); return true;
        default: return false;
    }
}

// ...

if (do_it) done();

, поскольку он абстрагирует логику "если весь этот материал будет успешным, тогда вызовите done()".

Но есть много других способов сделать это.Особенно, если число условий, вероятно, будет расти в будущем, я бы не стал этого делать.

1 голос
/ 06 апреля 2011

Зависит от того, сколько условий / действий существует и какой язык вы используете.

ООП и полиморфизм могут хорошо работать.

0 голосов
/ 06 апреля 2011

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

#!/usr/bin/env python

def doA():
    pass
def doB():
    pass
def doC():
    pass
def done():
    pass

a = 3
b = 6
c = 8

doers = {}
doers[a] = doA
doers[b] = doB
doers[c] = doC
condition = a

# this is now the entire "algorithm":

if condition in doers:
    doers[condition]()
    done()
0 голосов
/ 06 апреля 2011

Я бы написал это как

var failed = false;
if (a) doA();
else if (b) doB();
else if (c) doC();
else failed = true;
if (!failed) done();

Мне не нравится устанавливать переменную, например done, сначала в значение true, а затем отменять ее, потому что работа не выполняется до запуска условия, поэтомувыглядит нелогично.

Мне также не нравится опция переключения регистра, потому что условия 'a', 'b', 'c' не обязательно являются взаимоисключающими;Каскад if ... else if ... else поддерживает неисключительные условия, но switch () может не зависеть от языка.Например, вы не можете преобразовать каскадирование, если ... еще нужно переключить в C ++.

Я думаю, что определенно важно удалить несколько точек вызова to done (), потому что это избыточность, а затем проблема обслуживания, если сделано (), напримерполучает параметры.

0 голосов
/ 06 апреля 2011

Если a, b и c - разные сложные условные выражения, тогда ваше первое решение является лучшим.Может быть, вы можете избежать элементов «else if», если этот код находится внутри функции, например:

private void doit() {
    if (a) {
        doA();
        done();
        return;
    }
    if (b) {
        doB();
        done();
        return;
    }
    if (c) {
        doC();
        done();
        return;
    }
}

Так что для меня это гораздо больше вопрос стиля кода.

0 голосов
/ 06 апреля 2011

Используйте оператор switch, устанавливая флаг isDone по пути, и вызывайте done () на основе флага.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...