一、课程学习概述
在本次《软件工程实务》课程中,我系统地学习了软件开发的完整生命周期,从需求分析到系统维护的全过程。通过理论学习和项目实践相结合的方式,我不仅掌握了软件工程的基本原理和方法,还通过实际编码练习加深了对这些概念的理解。下面我将从几个主要方面总结我的学习收获。
二、需求分析与设计
1. 需求分析实践
我们小组选择了开发一个"图书馆管理系统"作为课程项目。在需求分析阶段,我们首先进行了用户访谈,然后使用用例图来描述系统功能。
# 用例图文本描述(使用PlantUML语法)
@startuml
left to right direction
actor 图书管理员
actor 读者
rectangle 图书馆管理系统 {
图书管理员 --> (添加新书)
图书管理员 --> (删除书籍)
图书管理员 --> (处理借阅)
图书管理员 --> (处理归还)
读者 --> (查询书籍)
读者 --> (预约书籍)
}
@enduml
2. 数据库设计
根据需求分析结果,我们设计了以下核心数据库表:
# models.py (使用Django ORM)
from django.db import models
class Book(models.Model):
ISBN = models.CharField(max_length=13, unique=True)
title = models.CharField(max_length=200)
author = models.CharField(max_length=100)
publisher = models.CharField(max_length=100)
publish_date = models.DateField()
available_copies = models.IntegerField(default=1)
def __str__(self):
return f"{self.title} ({self.author})"
class Reader(models.Model):
reader_id = models.CharField(max_length=10, unique=True)
name = models.CharField(max_length=100)
email = models.EmailField(unique=True)
phone = models.CharField(max_length=15)
class BorrowRecord(models.Model):
book = models.ForeignKey(Book, on_delete=models.CASCADE)
reader = models.ForeignKey(Reader, on_delete=models.CASCADE)
borrow_date = models.DateField(auto_now_add=True)
due_date = models.DateField()
return_date = models.DateField(null=True, blank=True)
STATUS_CHOICES = [
('B', '已借出'),
('R', '已归还'),
('O', '超期未还'),
]
status = models.CharField(max_length=1, choices=STATUS_CHOICES, default='B')
三、核心功能实现
1. 图书借阅功能
# views.py
from django.shortcuts import render, get_object_or_404
from django.contrib import messages
from django.utils import timezone
from datetime import timedelta
from .models import Book, Reader, BorrowRecord
def borrow_book(request, book_id, reader_id):
book = get_object_or_404(Book, pk=book_id)
reader = get_object_or_404(Reader, pk=reader_id)
# 检查图书是否可借
if book.available_copies <= 0:
messages.error(request, "该图书已全部借出")
return redirect('book_detail', book_id=book_id)
# 检查读者是否已有超期未还图书
overdue_books = BorrowRecord.objects.filter(
reader=reader,
status='O'
).count()
if overdue_books > 0:
messages.warning(request, "您有超期未还图书,请先归还")
return redirect('reader_detail', reader_id=reader_id)
# 创建借阅记录
BorrowRecord.objects.create(
book=book,
reader=reader,
due_date=timezone.now() + timedelta(days=30),
status='B'
)
# 更新图书可用数量
book.available_copies -= 1
book.save()
messages.success(request, "借书成功")
return redirect('book_detail', book_id=book_id)
2. 图书查询功能
# views.py
from django.db.models import Q
def search_books(request):
query = request.GET.get('q', '')
if query:
# 使用Q对象实现多字段搜索
books = Book.objects.filter(
Q(title__icontains=query) |
Q(author__icontains=query) |
Q(ISBN__icontains=query)
).order_by('title')
else:
books = Book.objects.all().order_by('title')
return render(request, 'search_results.html', {'books': books, 'query': query})
四、测试与质量保证
1. 单元测试
# tests.py
from django.test import TestCase
from django.utils import timezone
from .models import Book, Reader, BorrowRecord
class LibraryTestCase(TestCase):
def setUp(self):
self.book = Book.objects.create(
ISBN="9787111636667",
title="Python编程:从入门到实践",
author="Eric Matthes",
publisher="人民邮电出版社",
available_copies=3
)
self.reader = Reader.objects.create(
reader_id="R2023001",
name="张三",
email="zhangsan@example.com",
phone="13800138000"
)
def test_book_availability(self):
"""测试图书可用性检查"""
self.assertEqual(self.book.available_copies, 3)
def test_borrow_process(self):
"""测试借书流程"""
from .views import borrow_book
request = self.client.request().wsgi_request
borrow_book(request, self.book.id, self.reader.id)
# 检查图书可用数量是否减少
updated_book = Book.objects.get(pk=self.book.id)
self.assertEqual(updated_book.available_copies, 2)
# 检查借阅记录是否创建
record = BorrowRecord.objects.filter(
book=self.book,
reader=self.reader
).first()
self.assertIsNotNone(record)
self.assertEqual(record.status, 'B')
2. 集成测试
# tests.py
from django.test import Client
class IntegrationTests(TestCase):
def test_search_flow(self):
"""测试搜索流程"""
c = Client()
# 添加测试数据
Book.objects.create(
ISBN="9787115524635",
title="深入理解计算机系统",
author="Randal E.Bryant",
publisher="机械工业出版社",
available_copies=2
)
# 执行搜索
response = c.get('/search/?q=计算机')
self.assertEqual(response.status_code, 200)
self.assertContains(response, "深入理解计算机系统")
五、项目部署与维护
我们使用Docker容器化部署了应用,以下是Dockerfile示例:
# Dockerfile
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
ENV DJANGO_SETTINGS_MODULE=library.settings
RUN python manage.py collectstatic --noinput
EXPOSE 8000
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "library.wsgi"]
对应的docker-compose.yml文件:
version: '3.8'
services:
web:
build: .
ports:
- "8000:8000"
environment:
- DJANGO_SETTINGS_MODULE=library.settings
depends_on:
- db
db:
image: postgres:13
environment:
POSTGRES_DB: library
POSTGRES_USER: library
POSTGRES_PASSWORD: library123
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
六、学习收获与反思
1. 主要收获
-
掌握了软件开发的完整流程,从需求分析到部署维护
-
学会了使用Django框架进行Web开发
-
理解了测试驱动开发(TDD)的重要性
-
熟悉了团队协作工具(Git, Jira)的使用
-
掌握了基本的数据库设计和优化技巧
2. 遇到的挑战及解决方案
挑战1:数据库性能问题
在开发初期,我们遇到了列表页加载缓慢的问题。通过分析发现是由于没有合理使用select_related导致的N+1查询问题。
优化前的代码:
# 问题代码:每次循环都会查询数据库
records = BorrowRecord.objects.all()
for record in records:
print(record.book.title) # 每次都会查询Book表
优化后的代码:
# 优化代码:使用select_related一次性获取关联数据
records = BorrowRecord.objects.select_related('book').all()
for record in records:
print(record.book.title) # 不会产生额外查询
挑战2:并发借书问题
当多个用户同时借同一本书时,可能会出现超借的情况。我们通过使用数据库事务和乐观锁解决了这个问题。
from django.db import transaction
@transaction.atomic
def borrow_book_safe(request, book_id, reader_id):
book = Book.objects.select_for_update().get(pk=book_id)
if book.available_copies <= 0:
raise ValueError("No available copies")
book.available_copies -= 1
book.save()
BorrowRecord.objects.create(
book=book,
reader=get_object_or_404(Reader, pk=reader_id),
due_date=timezone.now() + timedelta(days=30),
status='B'
)
七、课程建议
-
希望增加更多实际项目案例的分析
-
建议引入更多自动化测试和持续集成的内容
-
可以增加一些性能优化和系统架构设计的高级主题
-
建议组织更多的代码审查实践环节
结语
通过《软件工程实务》课程的学习,我深刻理解了软件开发不仅仅是编写代码,而是一个系统的工程过程。从需求分析到设计实现,再到测试部署,每个环节都需要严谨的态度和专业的方法。课程中的项目实践让我获得了宝贵的实战经验,这将对我未来的职业发展产生深远的影响。
在未来的学习和工作中,我将继续应用这些软件工程的最佳实践,不断提高自己的开发能力和项目管理水平。同时,我也会持续关注软件工程领域的新发展,学习新的工具和方法,以适应快速变化的技术环境。