Как эффективно структурировать терминальное приложение с несколькими меню? - PullRequest
2 голосов
/ 29 октября 2010

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

#include <iostream>
#include <cstdlib>
using namespace std;

int main()
{
    int choice;
    do
    {
        cout << "\E[H\E[2J" // Clear the console
             << "Main menu" << endl << endl
             << "Please select one of the following options by entering it's "
             << "number in the prompt below and pressing [ENTER]. "
             << endl << endl
             << "1. Pay my bill as a guest" << endl
             << "3. Log in" << endl
             << "2. Create an account" << endl
             << "4. Quit program" << endl;

        cin >> choice;
        switch (choice)
        {
            case 1: // Pay the bill as a guest to the system
            case 2: // Log in to the system
            case 3: // Create an account with the system
            case 4: // Quit the program
            default: // Prompt the user to choose again
        }
    } while !(default);

    // Await user input to terminate the program
    cout << "Please press [ENTER] to continue...";
    cin.get();
    return 0;
}

Целью приведенного выше кода является предоставление списка опций для выбора пользователя, с циклом do-while, работающим вместе с оператором default в switchчтобы поймать любой неожиданный ввод.Каждый case будет вызывать функцию, которая представляет другое меню со своим собственным списком опций, который будет структурирован с использованием того же метода do-while, switch.Меня беспокоит то, что по мере роста моей программы число вызовов функций, вложенных в другие функции, будет увеличиваться, так что в конечном итоге я получу функцию, вызываемую изнутри функции, вызываемой из функции, и так далее.Это, очевидно, будет иметь серьезные последствия для удобства сопровождения программы: вызовы функций будут перемещаться все дальше и дальше от main(), а выходные данные этих функций будут иметь запутанный путь вокруг программы.

Можно ли структурировать мою программу таким образом, чтобы как можно чаще возвращать выполнение к main(), или описанная выше проблема является просто следствием такого рода программирования?

NB: Я задаю этот вопрос при том понимании, что определяемые пользователем функции должны быть вспомогательными для main(), и что они должны выполнить задачу, прежде чем вернуть управление на main() как можно раньше.,Я занимаюсь этим всего пару месяцев, поэтому, пожалуйста, потерпите мое невежество / недоразумение.Кроме того, игнорируйте любые возможные ошибки компилятора в коде, я еще не тестировал его, и он предоставляется только в качестве помощника в моем концептуальном вопросе.

Ответы [ 5 ]

2 голосов
/ 29 октября 2010

Я бы применил некоторый ОО-дизайн и создал бы класс меню, который в основном хранит элементы / подменю в векторе. Это позволило бы легко перейти к иерархическим меню

2 голосов
/ 29 октября 2010

Нет ничего особенно плохого в том, что вы сделали.

Я не понимаю, почему это мешает сопровождению вызова функций из функций и так далее. Во всяком случае, это ремонтопригодность по СПИДу, так как вы можете переместить обычные операции кода в отдельные функции. Таким образом, вы делаете исправление в одном месте и мгновенно исправляете и остальные места, которые он использовал.

1 голос
/ 29 октября 2010

Другой возможный подход - создать класс, определенный как список пар (menu_option, function) и ноу-хау, чтобы превратить их в меню.Тогда функция может быть вызовом меню экземпляра другого класса или может выполнять некоторые операции с вашей базой данных.Это позволяет вам упорядочить свои данные вне бизнес-логики «как отобразить это меню» и легко добавлять меню и пункты меню.

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

Подумайте об этом так: функция выполняет одно действие, но на более высоком уровне абстракции, чем ее тело.Итак, main() запускает вашу программу.create_account() создаст учетную запись, которая является частью запуска программы.create_account сам вызывает несколько других вещей, которые делают строительные блоки, необходимые для создания учетной записи.Является ли определение имени новой учетной записи одной вещью?Это идет в своей собственной функции.Определение индекса новой учетной записи в базе данных?Слишком низкий уровень.Поместите его в функцию «запихните в базу данных».

1 голос
/ 29 октября 2010

Ну, вы можете реализовать свою структуру меню как конечный автомат, так что вы почти всегда будете в основном цикле.Но это может привести ваш код к более низкому уровню, потому что вы будете эффективно программировать не на C ++, а в коде, близком к процессору конечного автомата.Если ваш конечный автомат будет достаточно хорош, это не проблема.

Или вы можете использовать простой класс бегунка меню, который в результате выведет запрос на подменю, поэтому вы просто обменяетесь (возможно, используястек) описание текущего запущенного меню.

Кстати, я не вижу проблем в глубокой вложенности функций.

1 голос
/ 29 октября 2010

Сложность кода будет соответствовать функциональности, предлагаемой программой. Я бы не стал беспокоиться об этом прямо сейчас, вернемся к рефакторингу, когда у вас будет две или триста строк.

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