在软件开发学习过程中,一个功能完整的管理系统是很好的实践项目。本文将介绍一个使用 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#编程指南》
系统扩展与改进方向
当前系统已经实现了图书管理的基本功能,但还有很多可以改进和扩展的地方:
-
数据存储优化:
- 可以考虑使用 SQLite 或 MySQL 等数据库替代 XML 文件
- 实现数据备份与恢复功能
-
功能扩展:
- 添加读者管理功能,记录借阅者信息
- 实现借阅期限管理和逾期提醒
- 添加图书分类和标签功能
-
用户界面改进:
- 开发 Windows Forms 或 WPF 图形界面
- 实现更友好的错误处理和输入验证
-
性能优化:
- 对于大量数据,实现分页查询
- 优化 XML 文件操作性能
总结
这个 C# 图书管理系统是一个很好的面向对象编程实践项目,通过它我们可以学习到:
- C# 面向对象编程的核心概念(类、对象、封装、继承等)
- XML 文件的读写操作和数据持久化
- 控制台应用程序的设计与实现
- 软件系统的架构设计和模块划分
系统完整代码已经包含在本文中,读者可以直接复制使用,并根据自己的需求进行扩展和改进。通过这个项目,不仅可以巩固 C# 编程知识,还能培养软件开发的整体思维。