简体   繁体   中英

Accessing potential changes in code from one location

I am a new programmer, learning C# as a hobby. I am writing a library navigator where the user can search books by name, genre, author etc.. I am reaching the end of this project and so far I have tackled all problems and solved them on my own. But I am now stuck and therefore writing on StackOverflow to get help from the experts out there. I will try to explain my issue as clearly as possible.

My program currently features 4 book genres: Horror, Fiction, Fantasy & Mystery.

Since in the future I might add more genres, I do not want to find myself navigating through hundreds of lines of code to edit an if/case statement and add the new genre.

Is there a practical way to centralize all the information that I might edit in the future into one place?

Below are the Lists I declared:

    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"};

Now, these lists are called from various parts of the code such as this one:

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;
                    }
                }

And code like:

                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;

So like this, if I had to edit the code to add more genres, I would have to scroll through my code and edit them individually. Not to mention the mess and confusion this would create..

I have tried putting the if statement block of case 1: in a separate Method but it did not work. I have also tried putting everything in another class and call the blocks case 1: and case 4: from there but that also did not work.

By not working, I mean that Genre: + the genre did not output on the Console.

So, in a nutshell, is there a way to centralize all of the above code so if a new book/genre/author comes along, I won't have to navigate? Because I think that would be bad practice.

Thanks in advance and sorry for the long post!

Typical solution would be to use object orientation to associate a book with its genre. Something like this

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);
}

and you can filter books by genre or search by title like this:

        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"));

In the future you might want to extend books to have a list of genres instead of a single one. You can also continue adding properties like author, ISBN etc. It is possible to serialize a list of books to a json file for storage, or to store books in a database using something like entity framework. The exact approach would depend on what you would require of the system. I would encourage you you read some articles about databases for more insight into the topic, especially database normalization.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM