114
社区成员
发帖
与我相关
我的任务
分享| 这个作业属于哪个课程 | 软件工程实践 |
|---|---|
| 这个作业要求在哪里 | 软件工程实践总结 |
| 这个作业的目标 | 软件工程实践总结 |
最初的困惑:课程初期接触TDD时,我认为“先写测试再写代码”是在浪费时间,尤其是在个人项目中,觉得直接编写实现代码更高效。
认知转变过程:
初次实践(个人项目阶段):
深度阅读与讨论:
团队项目实践验证:
新的理解:TDD不是单纯的“先写测试”,而是一种设计工具。它通过“红-绿-重构”循环,引导开发者从用户角度思考接口设计,最终提升的是代码的可维护性和可扩展性,而不仅是减少bug。
原来的困惑:认为文档是“应付作业”,应该把时间尽量用在写代码上。
厘清过程:
痛苦的经历:
关键转折点:
建立新认知:
遗留的不明白:如何量化文档的“恰到好处”?是否有工具能自动评估文档的充分性?
产生的新问题:在敏捷开发中,文档的“轻量级”边界在哪里?如何避免文档不足导致的团队认知不一致?
| 阶段 | 最大收获 | 具体体现 |
|---|---|---|
| 需求分析 | 需求辨析能力 | 学会区分用户“说的需求”和“真实需求”,通过用户画像和场景分析挖掘隐含需求 |
| 设计阶段 | 接口设计思维 | 从“实现功能”转向“设计契约”,理解松耦合的重要性 |
| 实现阶段 | 代码可读性意识 | 不再追求“巧妙”的代码,而是追求清晰易懂的代码 |
| 测试阶段 | 测试分层策略 | 单元测试、集成测试、端到端测试的合理分工与配合 |
| 发布阶段 | 部署自动化 | 理解CI/CD流水线如何保证发布质量,减少人为失误 |
个人项目:最大的教训是“过早优化是万恶之源”。我曾花费大量时间优化一个只占5%执行时间的函数,而忽略了整体架构的清晰性。
结对编程:深刻体会到“四只眼睛比两只眼睛看得更清楚”。与同伴的实时讨论不仅减少了bug,更重要的是在设计层面就避免了多个潜在问题。
团队项目:学会了“妥协的艺术”。技术决策需要考虑团队整体水平,选择“足够好”而非“最好”的方案往往更有利于项目推进。
| 目标 | 掌握程度(百分制) | 解释 |
|---|---|---|
| 目标1 | 85 | 通过案例分析理解了软件伦理的重要性,但缺乏真实商业环境中的实践检验 |
| 目标2 | 88 | 能够熟练使用UML和用户故事地图表达需求,但对模糊需求的挖掘仍需加强 |
| 目标3 | 82 | 掌握了基本的设计原则,但在大型系统的架构设计上经验不足 |
| 目标4 | 80 | 能够评估设计方案,但对性能瓶颈的预判能力有待提高 |
| 目标5 | 90 | 文档撰写能力显著提升,掌握了多种表达工具和规范 |
| 目标6 | 87 | 团队协作能力增强,但在冲突解决方面仍需积累经验 |
| 目标7 | 78 | 理解了项目管理的基本要素,但对复杂项目的风险控制缺乏实战经验 |
在第一次作业中,我制定了Spring Boot后端开发的学习路线。目前已经完成了以下进展:
项目名称:奖状识别
项目目标:构建一个识别奖状内容的平台
技术栈:
关键决策:
主要挑战与解决方案:
具体实践:
优点:
缺点:
对项目的影响:
| 开发模式 | 适用场景 | 不适合场景 |
|---|---|---|
| 瀑布模型 | 需求明确、变更少的政府/军工项目 | 互联网产品、需求频繁变更的项目 |
| 敏捷开发 | 需求不确定、需要快速试错的创业项目 | 有严格合规要求的金融系统 |
| DevOps | 需要频繁部署的云服务、SaaS产品 | 传统企业内网应用 |
不要盲目跟风:我们最初完全照搬Scrum,发现部分实践不符合团队实际情况。后来调整为“Scrum But”模式,保留了核心实践但调整了细节。
混合模式可能是最佳选择:对于大型项目,可以考虑:
团队成熟度是关键:初创团队适合更结构化的流程,成熟团队可以更敏捷。
工具不是万能:我们尝试了多个项目管理工具,最终发现工具只是辅助,团队沟通才是核心。
个人体会:软件开发模式本质上是团队协作的“算法”,需要根据“输入”(项目特性、团队能力)选择合适的“算法”,并在运行中不断调整参数。没有最好的模式,只有最适合的模式。
在团队项目中,我们遇到了一个典型的开发痛点:日志记录散落在各个方法中。每次排查问题都要从几十个Controller方法里找日志,代码重复率高,维护成本大。
传统方式的问题:
log.info()AOP的优势:
我的设计思路很简单:拦截+记录+存储。
请求 → 方法执行 → AOP拦截 → 记录信息 → 异步存储
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogRecord {
String module(); // 业务模块
String action(); // 操作类型
String description(); // 操作描述
}
@Aspect
@Component
public class LogAspect {
// 切入点:所有带@LogRecord注解的方法
@Around("@annotation(logRecord)")
public Object recordLog(ProceedingJoinPoint joinPoint,
LogRecord logRecord) throws Throwable {
// 1. 记录开始时间和基本信息
LogEntity log = new LogEntity();
log.setModule(logRecord.module());
log.setAction(logRecord.action());
// 2. 执行原方法
Object result = joinPoint.proceed();
// 3. 记录执行结果和时间
log.setSuccess(true);
log.setDuration(System.currentTimeMillis() - startTime);
// 4. 异步保存
asyncSave(log);
return result;
}
}
@RestController
public class UserController {
@LogRecord(module = "用户管理",
action = "创建用户",
description = "新增系统用户")
@PostMapping("/users")
public User createUser(@RequestBody User user) {
// 纯业务代码,没有日志干扰
return userService.save(user);
}
}
解决方案:异步记录
@Async注解@Async("logThreadPool")
public void asyncSave(LogEntity log) {
// 保存到数据库或文件
}
解决方案:参数过滤
private String filterSensitive(String params) {
return params.replaceAll("password\":\"[^\"]*\"",
"password\":\"******\"");
}
解决方案:分级记录
// 每个方法都要写日志
public User updateUser(User user) {
log.info("开始更新用户:{}", user.getId());
try {
// 业务逻辑
log.info("用户更新成功");
} catch (Exception e) {
log.error("更新失败", e);
}
}
@LogRecord(module="用户管理", action="更新")
public User updateUser(User user) {
// 纯业务逻辑
return userRepository.save(user);
}
统计效果:
在团队项目中,这个AOP日志方案带来了明显的提升:
通过这次AOP日志实践,我深刻理解了关注点分离的价值。AOP让我们能够把日志、安全、事务等横切关注点从业务逻辑中抽离出来,让代码更加清晰、更易维护。
核心收获:
适用场景: