309
社区成员
发帖
与我相关
我的任务
分享在本单元的任务完成中,一阶类图往往需要在代码具体实现之前,先确定好系统的架构设计。完成类图首先要确定类的核心属性,以及类与类之间的关系。尤其是类与类的关系,直接关系到实际完成的程序中,哪些类能访问/修改其他类的内容。在我的历次代码实现架构中,往往是用一个LibraryManager类来统摄管理图书馆的各个类与属性,再另外用一个OperationProcessor类来处理main类接收到的所有输入指令,并和LibraryManager建立关系。要实现哪些方法,可以到后期再斟酌着补充。重点在于先把握类的关联与依赖关系。类图的测评要求对于方法、属性的后续补充其实比较宽容,具体的实现细节可以留到实际完成代码时再决定。
关于任务涉及到的各个具体地点,如APPOINTMENT_OFFICE,BORROW_RETURN_OFFICE,READING_ROOM等,我都将其作为类来处理,以更好地为它们设计各自的属性与方法,使之独立完成相应功能。在LibraryManager类中,我将这些地点类作为属性,以方便在需要时调用它们的方法。由此即可正确实现图书馆情景所需完成的种种任务。
在本单元的任务提交中,二阶类图与具体的代码实现在同一阶段一起提交。并且,评测将会检查各个类中方法、属性与模型图中的一致性,保证图中设计的属性与方法不低于代码中的60%。这体现出,二阶类图的重要任务,是更加真切细致地反映出代码的具体实现。
一般而言,如果实际进行代码编写时,发现了一些一阶类图构想时未能考虑到,但实际问题解决时确实需要的类间关系,也需要按照实际对类图进行微调,以期实现正确的二阶类图。
除类图此外,二阶类图还会需要一些其他图,如状态图与顺序图。这些图可以更好地反映出代码之中的一些抽象逻辑,如Book位置状态的变化历程,预约过程中的信息传递路线。由此,二阶类图得以从具体实现与抽象思路两个层面,更恰当真实地描述程序的运行机制。
正向建模的内在逻辑,是先识别现实世界对象,封装属性与行为,依靠对象之间交互完成业务。具体到实践方法上,就是先做分析设计(画UML),再写代码实现。从需求→设计→编码,自上而下推进。
从任务完成角度看来,正向建模与开发兼具多种优势。
提前规避架构重大缺陷,动笔写代码前理清所有实体(用户、图书副本、各个场馆、预约记录、借阅期限、信用分)、类之间关联、方法职责,不会写到一半发现类结构混乱、耦合爆炸,频繁大面积删改代码。
方便补齐遗漏需求,梳理UML过程中可以主动发现题目隐藏规则:信用分阈值、逾期扣分、续订逻辑、预约保留期、整理约束、精品书架切换等,避免编码中途反复回头补逻辑、漏判分支。
同时,也有助于配套模型统一设计,同步规划图书状态图、业务顺序图,状态转移、对象交互逻辑提前定好,后续加@Trigger注解、状态转移代码一一对应,满足状态图评测规则。
从专业软件开发层面,正向建模与开发还有更长远的益处。
思路清晰,降低复杂度:把复杂业务拆解成独立对象与职责,遵循面向对象封装、高内聚低耦合思想,避免面条式 if-else 堆砌,业务逻辑分层清晰。
便于团队沟通协作:UML 类图、时序图是可视化文档,多人开发时可以作为统一设计方案,每个人按照约定好的类、接口分工编码,减少理解分歧。
易维护、易扩展,便于测试与排查问题:后续新增功能(如本次新增信用分、续订、借阅期限),可以先在 UML 上修改验证方案,再修改代码;后期修改 bug、迭代需求改动范围可控,不会牵一发而动全身。设计阶段就能梳理所有业务分支、边界条件,提前规划测试用例;出现逻辑错误时,可以对照设计图定位是设计疏漏还是代码实现错误,排错效率更高。
可读性强,便于交接:UML 图相当于系统设计说明书,其他人接手项目时,可以快速看懂整体结构、类之间依赖关系,不用逐行啃代码理解整体逻辑。
我最终的架构设计总体由以下几个层级组成。
Main类负责程序入口,循环读入全部输入,OperationProcessor类负责处理输入的所有指令,据其调用对应的业务方法,并给出相应输出。
LibraryManager是本次图书馆管理系统实现中,统摄一切业务的核心类,管理各个地点对象、全部的用户、未处理预约与图书副本、图书评分。所有需要对图书馆资源进行操作的业务方法,都需要通过LibraryManager类来调用。尤其是open与close时图书馆进行的整理,都是在该类中进行一系列的check与clean方法,以检查清理各个地点应当被转移的图书副本。
包括Bookshelf、TreasuredBookshelf、BorrowAndReturnOffice、AppointmentOffice、ReadingRoom类。这一层所有类的共性是,都具有一个books属性,用于存储该地点上的图书副本,并且有相应的add与remove方法,用于添加或移除图书副本。根据各自业务不同,每个地点类都有自己的独特方法,用于实现该地点的功能。
User管理用户信用分和已借阅副本,Book表示具体图书副本,Appointment表示具体的预约。此外,还有UserNotes与Books类,用于管理多个特定User或Book对象,以提高代码封装度。
代码中的所有类,在UML类图中都具有对应的类。
访问权限匹配,UML中private/public,代码修饰符严格对应,不存在UML私有成员代码写成public的情况。数量与比例合规,UML单个类属性数量≥代码属性数的60%,代码属性均可在UML找到对应设计,新增属性为编码补充临时业务变量,不破坏主体匹配。类型匹配,UML标注LocalDate、HashMap、Queue、自定义类等类型,代码变量类型完全一致。
常规业务方法:borrowBook()、returnBook()、orderBook()、pickBook()、readBook()、renewBook()、gradeBook()、arrangeSortOut()。UML定义方法名、参数列表、返回值类型,代码方法签名完全对齐。
方法内部业务逻辑为设计的具体实现,职责和 UML 语义一致。
状态图每条迁移的trigger(方法名),在代码中存在带@Trigger注解的同名方法;注解内from、to状态名 = 状态图状态名称(InitState、bs、tbs、rr、bro、ao、user、FinalState)。
Guard条件使用的成员变量,均为对应类UML中已定义属性,表达式长度合规、逻辑互斥,可完整追溯。
LibraryManager与各个地点类双向关联,UML中两端显式关联连线,代码中场所构造持有LibraryManager 引用,关联关系落地可查。
依赖关系与单向关联关系:各个地点类单向关联Books类,代码上以其作为核心属性;代码上需要临时使用其他类,如returnBook需要使用User类,则使用依赖关系进行连接。
无不合理继承、无循环继承。
在本单元的系统建模与开发实践中,高效使用大模型的核心思路,是将整体复杂的设计与开发任务进行阶段性拆分,而非直接交由模型一次性完成整体作业。开展辅助设计时,需要人为界定清晰的任务边界,分步引导模型仅完成当前阶段的对应工作,避免模型超前生成冗余内容、干扰整体开发节奏,保证建模与编码流程循序渐进、规范可控。
同时,需要向模型提供完整、统一的参考材料体系,整合课程任务要求、建模规范、前期设计模型与已有代码成果,让模型的输出能够贴合整体项目架构与提交标准,有效规避信息偏差导致的设计偏离与格式错误。
此外,需要对模型的输出内容明确质量约束与规范要求,不仅关注基础内容的正确性,还需要兼顾UML模型的格式规范、元素对应关系、可视化布局以及代码与模型的一致性适配,确保设计成果满足课程各项校验规则。
最后,需主动要求模型对生成内容开展结构化自检,针对模型元素命名、结构层级、关联匹配、注解对应、流程完整性等细节问题进行逐一核查,弥补人工检查容易遗漏的细节缺陷,全面提升设计与实现的规范性和准确性。
大模型在辅助系统正向建模与开发的过程中存在明显的能力局限,无法完全替代人工的设计判断与细节把控。
首先,模型存在迎合表层规范关键词的生成倾向,容易为了贴合基础校验规则,新增部分无实际业务意义、不符合整体架构逻辑的冗余元素,盲目适配表层评分标准,破坏了模型与代码整体的一致性与合理性。
其次,模型仅能依据公开任务描述与已知样例进行设计和纠错,无法完全覆盖课程隐蔽的边界校验规则与评测细节,无法独立保证最终评测完全通过,仍需依靠人工结合实测反馈迭代修正设计与代码。
同时,大模型对专业建模工具的细节规范适配不足,对于建模软件的结构层级、图示格式、连线规则、流程约束等工具专属细节敏感度较低,容易产出格式不规范、不符合评测要求的模型内容,需要人工二次核对调整。
最后,模型的通用工程设计思维与课程专属评测规则存在偏差,部分符合实际工程逻辑的设计方案,可能并不适配课程的建模校验标准,模型无法自主识别这类适配差异,最终需要依靠开发者结合实测结果修正设计逻辑、对齐课程规范。
在这四个单元的OO编程过程中,我逐渐学会了从具体细节上抽离视线,转而关注抽象的逻辑、整体的关系。
第一单元,表达式解析化简。递归下降教会了我OO编程中方法与方法的关系,每个方法只需要承担完成一小部分任务的责任,并且“相信”其他的方法能向自己提供正确结果。分层思想把复杂的一连串表达式,抽象为了表达式、项、因子三个层级,由此实现完备的表达式表示,并且进而可以处理各种复杂的问题变体。这三级架构大大降低了每一级内部处理的复杂度,让我感受到优秀抽象架构带来的立竿见影的好处。此时是我首次接触到复杂的Java编程情景,初识优良架构的作用,尚无举一反三的能力。
第二单元,多线程电梯。这一单元引入了线程这一全新知识,数据结构、线程之间的协作及共享资源的安全性,成为了久久困扰我的梦魇。在这一单元我意识到,如果没有抽象的逻辑分析来理清线程访问共享资源的时间关系,将对程序的并发正确实现产生毁灭性的影响。从具体的代码中反推时间顺序太过艰难,在进行编程前应该预先思考决定所有共享资源访问情形。也就是架构设计要优先于具体实现。
第三单元,由JML规格完成视频网站系统。与其他单元不同的是,该单元对许多方法的实现都提出了严格要求,JML也由此已经提示了架构的设计思路。然而,出于性能的考量,本单元对于数据的缓存策略有了新的要求,这一点是JML规格中不曾明确指出,但性能评估限制所必需的。如果解读需求时提取出相应的缓存需求,代码实现才能达到指定要求。
第四单元,UML正向建模辅助图书管理系统开发。本单元要求使用UML图梳理代码中类、属性、方法的关系,是明确要求优先进行架构设计。一个好的架构设计,有助于在作业不断迭代产生新需求时,更好地适应新任务。在本单元的第一次作业之后,我基于完整的架构重构了代码,明确了LibraryManager类与其他各个地点类分别需要承担的功能。由此,实现了正确性与速度的双重飞跃。
经过四个单元的课程实践,我的软件测试与问题校验思维实现了阶段性迭代升级。课程初期,我主要依靠人工审查的方式排查程序问题,通过逐行梳理代码逻辑、模拟输入输出场景、推演程序分支与状态变化完成自测。这种人力测试方式效率不高,能够定位浅显的逻辑漏洞与边界错误,适配小规模简单程序的测试需求。但非常耗费时间,并且测试覆盖面和精准度都存在明显局限。不过,这种方式能集中测试一些易混易错的重难点问题。
随着课程作业难度与系统复杂度持续提升,我开始构造评测机完成测试工作。最主要的原因是第二单元的电梯输出信息,不仅具有一定随机因素,而且极其冗杂,难以人工核对。在AI协力之下,我开发了检验输出正确性及与输入匹配性的测试工具,能够根据输入,测试代码程序提供输出的正确性,并且在错误时明确指出错误原因。尽管依然依赖于手动构造输入导致测试覆盖不全面,这个工具也在修复已发现错误的错误定位与复现过程中,给予了我很大的助力。
在此基础上,我进一步结合大模型开展辅助测试工作,借助模型梳理业务规则、挖掘代码隐藏风险、搭建测试思路、解读差异化输出的合理性,有效弥补了常规测试的盲区。通过大模型构造输入,有效提高测试广度。但实践中也发现,大模型的分析结果仅可作为参考启发,无法替代真实的程序运行测试,所有模型给出的判断都需要通过实测数据、评测机运行结果与平台反馈进行核验。最终我形成了人工梳理核心逻辑、评测机测试快速验证、大模型查漏补缺的复合型测试思维,三者相互配合,大幅提升了程序校验的完整性与可靠性。
本次面向对象程序设计课程,让我彻底跳出表层的代码编写认知,建立了系统化、贴近实际工程的编程与建模思维。此前我对面向对象的理解仅停留在代码分层、类文件拆分的基础层面,经过四个单元的迭代学习,我深刻认识到面向对象是一种贴合现实业务的问题解决思路,核心是从复杂需求中抽象实体、界定实体数据与行为、明确各模块职责边界,实现对现实业务、状态变化与逻辑关系的规范化组织,杜绝无序的过程式代码堆砌。
同时,课程各单元的学习让我积累了扎实的技术能力,也让我养成了工程化的开发习惯,明白软件系统开发并非一蹴而就,而是在需求迭代、测试校验、问题反馈与持续重构中不断完善的过程。我逐步掌握了问题拆解、逻辑设计、实测验证、迭代优化的开发方法,培养了独立设计、自查自纠、优化重构的综合能力。整体而言,这门课程不仅提升了我的Java编程能力,更重塑了我应对复杂问题的思维模式,形成了先抽象建模、再划分职责、最后迭代验证的完整开发思路。