C# 图书管理系统:基于 XML 存储的完整实现

在软件开发学习过程中,一个功能完整的管理系统是很好的实践项目。本文将介绍一个使用 C# 语言开发的图书管理系统,该系统采用 XML 文件作为数据存储方式,实现了图书的增删改查、借阅归还等核心功能。

系统架构设计

本图书管理系统采用面向对象的设计思想,主要包含以下几个核心类:

  • XmlManager 类:负责 XML 文件的读写操作,实现数据持久化
  • User 类:用户认证管理,实现管理员登录功能
  • Book 类:图书实体类,封装图书的属性和行为
  • Library 类:图书馆管理类,实现图书的各种操作
  • Program 类:主程序类,包含用户交互界面

系统整体架构图如下:

plaintext

┌───────────────┐     ┌───────────────┐     ┌───────────────┐
│   XmlManager  │─────►│     Library   │─────►│      Book     │
└───────────────┘     └───────────────┘     └───────────────┘
      │                                 ▲
      │                                 │
      └───────────────┬───────────────┘
                        │
┌───────────────┐     ┌▼───────────────┐
│     User      │─────┤    Program    │
└───────────────┘     └───────────────┘

核心功能实现

XML 数据操作

XmlManager 类是系统的数据持久层,负责 XML 文件的读取和写入操作。以下是该类的核心方法:

csharp

class XmlManager
{
    private const string filePath = "../../library.xml";
    
    // 加载XML数据到Library对象
    public static void LoadData(Library library)
    {
        XmlDocument xmlDocument = new XmlDocument();
        xmlDocument.Load(filePath);
        
        XmlNode rootNode = xmlDocument.DocumentElement;
        foreach (XmlNode bookNode in rootNode.ChildNodes)
        {
            string name = "", author = "", isbn = "";
            DateTime publishDate = DateTime.MinValue;
            int quantity = 0, borrowedCount = 0;
            decimal price = 0;
            
            foreach (XmlNode childNode in bookNode.ChildNodes)
            {
                switch (childNode.Name)
                {
                    case "Name": name = childNode.InnerText.Trim(); break;
                    case "Author": author = childNode.InnerText.Trim(); break;
                    case "PublishDate": DateTime.TryParse(childNode.InnerText, out publishDate); break;
                    case "Quantity": int.TryParse(childNode.InnerText, out quantity); break;
                    case "Price": decimal.TryParse(childNode.InnerText, out price); break;
                    case "ISBN": isbn = childNode.InnerText.Trim(); break;
                    case "BorrowedCount": int.TryParse(childNode.InnerText, out borrowedCount); break;
                }
            }
            library.AddBook(name, author, publishDate, quantity, price, isbn, borrowedCount);
        }
        Console.WriteLine("成功加载XML数据");
    }
    
    // 添加图书到XML文件
    public static void AddBook(Library library, Book newBook)
    {
        XmlDocument xmlDocument = new XmlDocument();
        if (File.Exists(filePath))
        {
            xmlDocument.Load(filePath);
        }
        
        XmlNode rootNode = xmlDocument.DocumentElement;
        XmlElement bookNode = xmlDocument.CreateElement("Book");
        rootNode.AppendChild(bookNode);
        
        AddChildElement(xmlDocument, bookNode, "Name", newBook.Name);
        AddChildElement(xmlDocument, bookNode, "Author", newBook.Author);
        AddChildElement(xmlDocument, bookNode, "PublishDate", newBook.PublishDate.ToString("yyyy-MM-dd"));
        AddChildElement(xmlDocument, bookNode, "Quantity", newBook.Quantity.ToString());
        AddChildElement(xmlDocument, bookNode, "Price", newBook.Price.ToString());
        AddChildElement(xmlDocument, bookNode, "ISBN", newBook.ISBN);
        AddChildElement(xmlDocument, bookNode, "BorrowedCount", newBook.BorrowedCount.ToString());
        
        xmlDocument.Save(filePath);
        Console.WriteLine("图书添加成功");
        library.AddBook(newBook.Name, newBook.Author, newBook.PublishDate, newBook.Quantity, newBook.Price, newBook.ISBN, newBook.BorrowedCount);
    }
    
    // 辅助方法:添加子元素
    private static void AddChildElement(XmlDocument doc, XmlNode parentNode, string elementName, string value)
    {
        XmlElement element = doc.CreateElement(elementName);
        element.InnerText = value;
        parentNode.AppendChild(element);
    }
    
    // 其他方法:删除、修改、查询图书...
}

图书实体与行为

Book 类不仅包含图书的基本属性,还封装了图书的借阅、归还等行为:

csharp

class Book
{
    private string name;
    private string author;
    private DateTime publishDate;
    private int quantity;
    private decimal price;
    private string isbn;
    private int borrowedCount; // 借阅次数
    
    public Book(string name, string author, DateTime publishDate, int quantity, decimal price, string isbn, int borrowedCount)
    {
        this.name = name;
        this.author = author;
        this.publishDate = publishDate;
        this.quantity = quantity;
        this.price = price;
        this.isbn = isbn;
        this.borrowedCount = borrowedCount;
    }
    
    // 只读属性
    public string Name => name;
    public string Author => author;
    public DateTime PublishDate => publishDate;
    public int Quantity => quantity;
    public decimal Price => price;
    public string ISBN => isbn;
    public int BorrowedCount => borrowedCount;
    public int AvailableCount => quantity - borrowedCount; // 可借阅数量
    public bool CanBorrow => AvailableCount > 0; // 是否可以借阅
    
    // 更新图书信息
    public void UpdateInfo(string newName, string newAuthor, DateTime newPublishDate, int newQuantity, decimal newPrice, string newISBN)
    {
        name = newName;
        author = newAuthor;
        publishDate = newPublishDate;
        quantity = newQuantity;
        price = newPrice;
        isbn = newISBN;
    }
    
    // 借阅图书
    public bool Borrow()
    {
        if (CanBorrow)
        {
            borrowedCount++;
            Console.WriteLine($"成功借出《{name}》,剩余库存: {AvailableCount}");
            return true;
        }
        Console.WriteLine($"《{name}》已全部借出,当前无库存");
        return false;
    }
    
    // 归还图书
    public bool Return()
    {
        if (borrowedCount > 0)
        {
            borrowedCount--;
            Console.WriteLine($"成功归还《{name}》,当前库存: {AvailableCount}");
            return true;
        }
        Console.WriteLine($"《{name}》未被借出,无需归还");
        return false;
    }
    
    public override string ToString()
    {
        return $"书名: {name}, 作者: {author}, 出版日期: {publishDate:yyyy-MM-dd}, " +
               $"数量: {quantity}, 价格: {price:C}, ISBN: {isbn}, " +
               $"状态: {AvailableCount}/{quantity} 可借阅";
    }
}

图书馆管理功能

Library 类是系统的核心控制类,协调各个功能模块实现图书管理:

csharp

class Library
{
    private List<Book> books = new List<Book>();
    
    // 添加图书
    public void AddBook(string name, string author, DateTime publishDate, int quantity, decimal price, string isbn, int borrowedCount)
    {
        if (FindBookIndex(name) != -1)
        {
            Console.WriteLine($"图书《{name}》已存在,无法重复添加");
            return;
        }
        books.Add(new Book(name, author, publishDate, quantity, price, isbn, borrowedCount));
        Console.WriteLine($"已添加图书: 《{name}》");
    }
    
    // 删除图书
    public void RemoveBook(string name)
    {
        int index = FindBookIndex(name);
        if (index != -1)
        {
            Book book = books[index];
            if (book.BorrowedCount > 0)
            {
                Console.WriteLine($"无法删除《{name}》,尚有 {book.BorrowedCount} 本未归还");
                return;
            }
            books.RemoveAt(index);
            Console.WriteLine($"已删除图书: 《{name}》");
        }
        else
        {
            Console.WriteLine($"未找到图书: 《{name}》");
        }
    }
    
    // 更新图书信息
    public void UpdateBook(string oldName, string newName, string newAuthor, DateTime newPublishDate, int newQuantity, decimal newPrice, string newISBN)
    {
        int index = FindBookIndex(oldName);
        if (index != -1)
        {
            Book book = books[index];
            if (oldName != newName && FindBookIndex(newName) != -1)
            {
                Console.WriteLine($"新书名《{newName}》已存在,无法更新");
                return;
            }
            book.UpdateInfo(newName, newAuthor, newPublishDate, newQuantity, newPrice, newISBN);
            Console.WriteLine($"已更新图书: 《{oldName}》 → 《{newName}》");
        }
        else
        {
            Console.WriteLine($"未找到图书: 《{oldName}》");
        }
    }
    
    // 列出所有图书
    public void ListAllBooks()
    {
        if (books.Count == 0)
        {
            Console.WriteLine("图书馆暂无藏书");
            return;
        }
        Console.WriteLine("图书馆所有图书:");
        foreach (var book in books)
        {
            Console.WriteLine(book);
        }
    }
    
    // 查找图书索引
    public int FindBookIndex(string name)
    {
        for (int i = 0; i < books.Count; i++)
        {
            if (books[i].Name == name)
            {
                return i;
            }
        }
        return -1;
    }
    
    // 其他方法:搜索、借阅、归还图书...
}

用户交互界面

Program 类实现了控制台交互界面,提供菜单驱动的用户操作:

csharp

class Program
{
    static async Task Main()
    {
        // 初始化管理员账户
        User admin = new User("admin", "123456");
        Library library = new Library();
        
        // 从XML加载数据
        Console.WriteLine("===对XML文件的相关操作===");
        Console.WriteLine("===加载相关数据===");
        XmlManager.LoadData(library);
        
        // 登录验证
        if (!AuthenticateUser(admin))
        {
            Console.WriteLine("登录失败,程序退出");
            return;
        }
        
        Console.WriteLine("\n=== 欢迎使用图书管理系统 ===");
        
        // 控制台菜单循环
        while (true)
        {
            DisplaySystem();
            string choice = Console.ReadLine();
            Console.Clear();

            switch (choice)
            {
                case "1": AddBook(library); break;
                case "2": RemoveBook(library); break;
                case "3": UpdateBook(library); break;
                case "4": library.ListAllBooks(); break;
                case "5": SearchBook(library); break;
                case "6": BorrowBook(library); break;
                case "7": ReturnBook(library); break;
                case "8": Console.WriteLine("感谢使用,再见!"); return;
                default: Console.WriteLine("无效选择,请重新输入"); break;
            }

            Console.WriteLine("\n按任意键继续...");
            Console.ReadKey();
            Console.Clear();
        }
    }
    
    // 显示系统菜单
    static void DisplaySystem()
    {
        Console.WriteLine("\n请选择操作:");
        Console.WriteLine("1. 添加图书");
        Console.WriteLine("2. 删除图书");
        Console.WriteLine("3. 修改图书信息");
        Console.WriteLine("4. 查看所有图书");
        Console.WriteLine("5. 查询单本图书");
        Console.WriteLine("6. 借阅图书");
        Console.WriteLine("7. 归还图书");
        Console.WriteLine("8. 退出系统");
        Console.Write("请输入选项: ");
    }
    
    // 其他方法:添加、删除、修改图书等...
}

系统使用示例

1. 系统启动与数据加载

系统启动后会自动从 XML 文件加载图书数据:

plaintext

===对XML文件的相关操作===
===加载相关数据===
成功加载XML数据

=== 管理员登录 ===
用户名: admin
密码: 123456

=== 欢迎使用图书管理系统 ===

请选择操作:
1. 添加图书
2. 删除图书
3. 修改图书信息
4. 查看所有图书
5. 查询单本图书
6. 借阅图书
7. 归还图书
8. 退出系统
请输入选项: 

2. 查看所有图书

选择选项 4 可以查看图书馆中的所有图书:

plaintext

图书馆所有图书:
书名: 红楼梦, 作者: 曹雪芹, 出版日期: 2020-01-15, 数量: 10, 价格: ¥58.00, ISBN: 978-7-101-08268-1, 状态: 8/10 可借阅
书名: 三国演义, 作者: 罗贯中, 出版日期: 2019-05-20, 数量: 15, 价格: ¥45.50, ISBN: 978-7-5321-6876-5, 状态: 12/15 可借阅
书名: 水浒传, 作者: 施耐庵, 出版日期: 2021-03-10, 数量: 8, 价格: ¥42.00, ISBN: 978-7-02-013456-7, 状态: 6/8 可借阅

3. 借阅图书

选择选项 6 可以借阅图书:

plaintext

=== 借阅图书 ===
请输入要借阅的书名: 红楼梦
成功借出《红楼梦》,剩余库存: 7

4. 归还图书

选择选项 7 可以归还图书:

plaintext

=== 归还图书 ===
请输入要归还的书名: 红楼梦
成功归还《红楼梦》,当前库存: 8

5. 添加新图书

选择选项 1 可以添加新图书:

plaintext

=== 添加图书 ===
书名: C#编程指南
作者: 微软官方
出版日期 (yyyy-MM-dd): 2023-06-01
数量: 5
价格: 88.5
ISBN: 978-7-115-50123-4
BorrowedCount: 0
已添加图书: 《C#编程指南》

系统扩展与改进方向

当前系统已经实现了图书管理的基本功能,但还有很多可以改进和扩展的地方:

  1. 数据存储优化

    • 可以考虑使用 SQLite 或 MySQL 等数据库替代 XML 文件
    • 实现数据备份与恢复功能
  2. 功能扩展

    • 添加读者管理功能,记录借阅者信息
    • 实现借阅期限管理和逾期提醒
    • 添加图书分类和标签功能
  3. 用户界面改进

    • 开发 Windows Forms 或 WPF 图形界面
    • 实现更友好的错误处理和输入验证
  4. 性能优化

    • 对于大量数据,实现分页查询
    • 优化 XML 文件操作性能

总结

这个 C# 图书管理系统是一个很好的面向对象编程实践项目,通过它我们可以学习到:

  • C# 面向对象编程的核心概念(类、对象、封装、继承等)
  • XML 文件的读写操作和数据持久化
  • 控制台应用程序的设计与实现
  • 软件系统的架构设计和模块划分

系统完整代码已经包含在本文中,读者可以直接复制使用,并根据自己的需求进行扩展和改进。通过这个项目,不仅可以巩固 C# 编程知识,还能培养软件开发的整体思维。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值