Доступ к потенциальным изменениям в коде из одного места

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

Моя программа в настоящее время включает 4 книжных жанра: ужасы, художественная литература, фэнтези и мистика.

Так как в будущем я могу добавить больше жанров, я не хочу продираться через сотни строк кода, чтобы отредактировать оператор if/case и добавить новый жанр.

Есть ли практический способ централизовать всю информацию, которую я могу редактировать в будущем, в одном месте?

Ниже приведены списки, которые я объявил:

    public static List<string> bookList = new List<string> {"shindler's list", "it", "maltese falcon", "bfg", "hobbit"};
    public static List<string> fiction = new List<string> {"shindler's list"};
    public static List<string> fantasy = new List<string> {"bfg", "hobbit"};
    public static List<string> horror = new List<string> {"it"};
    public static List<string> mystery = new List<string> {"maltese falcon"};

Теперь эти списки вызываются из различных частей кода, таких как этот:

case "1":
                Seperation();
                Console.Clear();

                Console.Write("Enter book name: ");
                var bookTitleUserInput = Console.ReadLine();

                Console.WriteLine("You searched for: " + bookTitleUserInput);

                foreach (string s in bookList)
                {
                    if (s.ToLowerInvariant() == bookTitleUserInput.ToLowerInvariant())
                    {
                        Console.WriteLine("\n");
                        Seperation();
                        OutputBookSummary(bookTitleUserInput.ToLowerInvariant());
                        Seperation();
                        if (fiction.Contains(bookTitleUserInput.ToLowerInvariant()))
                        {
                            Console.WriteLine("Genre: Fiction");
                            Console.WriteLine("\n");
                        }
                        else if (horror.Contains(bookTitleUserInput.ToLowerInvariant()))
                        {
                            Console.WriteLine("Genre: Horror");
                            Console.WriteLine("\n");
                        }
                        else if (mystery.Contains(bookTitleUserInput.ToLowerInvariant()))
                        {
                            Console.WriteLine("Genre: Mystery");
                            Console.WriteLine("\n");
                        }
                        else if (fantasy.Contains(bookTitleUserInput.ToLowerInvariant()))
                        {
                            Console.WriteLine("Genre: Fantasy");
                            Console.WriteLine("\n");
                        }
                        else
                        {
                            Console.WriteLine("");
                        }

                        break;
                    }
                }

И код типа:

                case "4":
                Console.Clear();
                Console.WriteLine("Settings Menu");
                Seperation();
                Console.WriteLine("1) Search By Genre");
                Console.WriteLine("2) Search By Author");
                Console.WriteLine("3) Search By Book Name");
                Console.WriteLine("4) Back to Main Menu");
                Seperation();

                Console.Write("Choice: ");
                var settingsMenuSelection = Console.ReadLine();

                switch (settingsMenuSelection)
                {
                    case "1":
                        Console.WriteLine("1) Horror");
                        Console.WriteLine("2) Mystery");
                        Console.WriteLine("3) Fiction");
                        Console.WriteLine("4) Fantasy");
                        var genreMenuSelection = Console.ReadLine();

                        break;

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

Я попытался поместить блок операторов if case 1: в отдельный метод, но это не сработало. Я также пытался поместить все в другой класс и вызвать оттуда блоки case 1: и case 4:, но это тоже не сработало.

Под неработающим я подразумеваю, что Genre: + жанр не выводился на консоль.

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

Заранее спасибо и извините за длинный пост!


person Patrick    schedule 03.09.2020    source источник
comment
Ну, у вас есть жестко закодированные списки, так что вы уже заблокированы. Обычно вы храните свои данные в центральном хранилище данных, например в базе данных. Тогда Жанр, возможно, будет одной таблицей (или коллекцией, но давайте придерживаться реляционных баз данных ради аргумента), а конкретный жанр книги будет ссылкой на эту таблицу из столбца таблицы книг. Затем ваш уровень доступа к данным в приложении преобразует ваши бизнес-кейсы в связанные запросы (создание, чтение, обновление, удаление) в базу данных.   -  person Fildor    schedule 03.09.2020
comment
^^ Так что здесь, если вы добавите еще один жанр, это будет так же просто, как вставить еще одну строку в таблицу жанров.   -  person Fildor    schedule 03.09.2020
comment
Как сказал @Fildor, база данных была бы идеальной, но если вы не хотите усложнять, вы все равно можете хранить их в файле JSON или XML. Затем напишите свой уровень данных, который с ним взаимодействует. Это также дает вам то преимущество, что если вы позже захотите перейти на более традиционную базу данных, вам просто нужно изменить уровень данных.   -  person gmiley    schedule 03.09.2020
comment
@gmiley Я обычно соглашаюсь, но с однофайловыми базами данных, такими как SQLite, которые находятся в свободном доступе, я чувствую, что файловое (json/xml) хранилище данных хуже. Но это только я. (Хотя всему свое место)   -  person Fildor    schedule 03.09.2020
comment
Я решил, что поместил бы это там, поскольку новому разработчику может быть сложнее беспокоиться об этом. Простой доступ к файлам для небольших наборов данных вполне подходит для быстрого решения, которое позволяет выиграть время для дальнейших исследований и обучения.   -  person gmiley    schedule 03.09.2020
comment
Привет, ребята, большое спасибо, что связались со мной так быстро! Я рассмотрю создание базы данных SQL Server. Как вы думаете, это объяснило бы мне, что мне нужно сделать, чтобы это сделать? Или это будет отличаться/сложнее, чем SQLite?   -  person Patrick    schedule 03.09.2020
comment
@gmiley, я тоже рассмотрю ваше предложение, спасибо!   -  person Patrick    schedule 03.09.2020


Ответы (1)


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

public enum Genre
{
    Horror, Fiction, Fantasy, Mystery
}

public class Book
{
    public string Title { get; }
    public Genre Genre { get; }
    public Book(string title, Genre genre) => (Title, Genre) = (title, genre);
}

и вы можете фильтровать книги по жанру или искать по названию следующим образом:

        var books = new[]
        {
            new Book("bfg", Genre.Fiction),
            new Book("it", Genre.Horror),
        };
        var horrorBooks = books.Where(b => b.Genre == Genre.Horror);
        var foundByname = books.FirstOrDefault(b => b.Title.Contains("MySearchTerm"));

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

person JonasH    schedule 03.09.2020
comment
Большое спасибо за это! Я рассмотрю то, что вы предложили. - person Patrick; 03.09.2020