《软件工程实务》课程学习心得

一、课程学习概述

在本次《软件工程实务》课程中,我系统地学习了软件开发的完整生命周期,从需求分析到系统维护的全过程。通过理论学习和项目实践相结合的方式,我不仅掌握了软件工程的基本原理和方法,还通过实际编码练习加深了对这些概念的理解。下面我将从几个主要方面总结我的学习收获。

二、需求分析与设计

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'
    )

七、课程建议

  1. 希望增加更多实际项目案例的分析

  2. 建议引入更多自动化测试和持续集成的内容

  3. 可以增加一些性能优化和系统架构设计的高级主题

  4. 建议组织更多的代码审查实践环节

结语

通过《软件工程实务》课程的学习,我深刻理解了软件开发不仅仅是编写代码,而是一个系统的工程过程。从需求分析到设计实现,再到测试部署,每个环节都需要严谨的态度和专业的方法。课程中的项目实践让我获得了宝贵的实战经验,这将对我未来的职业发展产生深远的影响。

在未来的学习和工作中,我将继续应用这些软件工程的最佳实践,不断提高自己的开发能力和项目管理水平。同时,我也会持续关注软件工程领域的新发展,学习新的工具和方法,以适应快速变化的技术环境。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值