302
社区成员




在面向对象设计与构造的最后一堂课中,我们深入探讨了UML(统一建模语言)正向建模与开发的重要性及其在实际项目中的应用。通过这一单元的学习与实践,我们不仅对UML的核心理念有了更深刻的理解,而且能够将其应用于实际的项目开发过程中,为项目的成功实施奠定了坚实的基础。
一、UML正向建模概述
UML正向建模是指从需求分析开始,通过一系列建模活动,逐步构建出系统的逻辑模型、物理模型以及最终的实现模型的过程。它强调从用户需求出发,通过逐步细化和完善模型,确保系统的设计与开发始终与用户需求保持一致。UML提供了丰富的建模元素和图形表示法,使得我们可以更加直观地描述系统的结构和行为。
二、UML正向建模实践
想象一下,UML正向建模就像是一位细心的画家,在空白的画布上,一笔一划地勾勒出系统的轮廓。从最初的混沌无序,到逐渐展现出清晰的线条和色彩,每一步都充满了惊喜和期待。
在需求分析阶段,我们像是与用户的心灵使者,通过深入的对话,捕捉他们内心深处的需求和期望。然后,我们运用UML的用例图,将这些需求转化为直观的图形,让系统的功能边界和用户与系统之间的交互过程一目了然。
接下来,在系统设计阶段,我们就像是建筑师,用UML的类图、包图、组件图等工具,搭建起系统的骨架。类图展现了系统中的各个角色和它们之间的关系,包图则像是分类的文件夹,帮助我们组织和管理这些角色。而组件图则像是系统的蓝图,描绘了各个物理组件之间的依赖关系。
在需求分析阶段,我们像是与用户的心灵使者,通过深入的对话,捕捉他们内心深处的需求和期望。然后,我们可以使用UML中的用例图来描述系统的功能需求,通过用例和参与者之间的交互关系,清晰地展现系统的功能边界和用户与系统之间的交互过程。
在系统设计阶段,我们就像是建筑师,用UML的类图、包图、组件图等工具,搭建起系统的骨架。类图展现了系统中的各个角色和它们之间的关系,包图则像是分类的文件夹,帮助我们组织和管理这些角色。而组件图则像是系统的蓝图,描绘了各个物理组件之间的依赖关系。我们根据需求分析的结果,描述系统的静态结构和动态行为。类图用于展现系统中的类和它们之间的关系,如继承、关联、聚合等;包图用于组织和管理系统中的类和接口;组件图则用于描述系统中的物理组件以及它们之间的依赖关系。通过这些图形表示法,我们可以更加深入地理解系统的内部结构和运行机制。
在编码实现阶段,我们可以根据系统设计阶段生成的UML模型,使用面向对象的编程语言(如Java、C++等)来编写系统的实现代码。通过UML模型与代码之间的映射关系,我们可以确保代码的实现与系统设计保持一致,从而提高代码的可维护性和可扩展性。
三、UML正向建模开发的优点
提高开发效率:UML正向建模通过逐步细化和完善模型,使得开发人员能够更早地发现和解决问题,从而减少了后期修改和调整的工作量。
降低开发风险:UML正向建模强调从用户需求出发,通过逐步细化和完善模型来确保系统的设计与开发始终与用户需求保持一致。这有助于降低因需求变更或理解偏差导致的开发风险。
提高代码质量:UML正向建模使得开发人员能够清晰地理解系统的内部结构和运行机制,从而编写出更加健壮、可维护的代码。
在UML类图中,箭头用于表示类之间的不同关系。以下是UML类图中几种主要箭头及其含义的详细解释:
四、UML类图中的箭头含义
泛化(Generalization)
实现(Realization)
依赖(Dependency)
关联(Association)
聚合(Aggregation)
组合(Composition)
最开始接触到图书馆作业时,我感觉到想设计出一个很好的架构是棘手的。
涉及到四个部门,分别是借还处,预约处,书架,漂流角(后加入)。
除此之外至少还应该有用户,以及一个管理类型。
我并不喜欢做非常多的类,比如将每种指令、开关门的行为、书籍类、副本类、甚至具体的某一项行为,判定,后果都单独写成类,这样给人一种食品过度包装的感觉,不利于清晰的看到整体图书馆运行时的每一部分之间的真实关系,而且这样的类图真的可以在代码之前设计出来吗?事实上我在之前作业的互测中经常看到设计出非常多类的同学,而且这次作业其实我更好奇其他同学架构,却因没有开放互测无法知晓。在群里看到一个采用类似于离散数学完全图的画法的同学,将类图画为了一个环状,每个类伸出很多个类型各自不同的触手(关系箭头)向各个其他类,这样实在让人无法感受到图书馆的类之间的关系,我认为这样的画法应该极力避免,越是复杂的类图越是需要清晰的层次。
那么刚才提到的几个部门+一个管理类+用户类可以实现我们需要的功能了吗?
几乎可以。
让我们回顾一下题目的最重要要求。
本次作业中,我们规定书籍仅可以存在于如下四个位置:书架、预约处、借还处和用户。
图书馆系统提供自助查询机查询书籍状态。
图书馆开馆后接收用户请求,输出处理结果;开馆和闭馆整理图书时,输出图书的转运路径。
首先,题目中明确说:书架,预约处,借还处,用户都是“位置”,并且书仅能存在于这四个“位置"。
那么我们让书架,预约处,借还处,用户都继承 “位置”这个类,即Place。则Place类应该具有的属性为,一个容器,包含了书的ID,以及书的副本的数量,HashMap完美符合,还应具有属性name。应该具有的行为是:moveTo(LibraryBookId id, Place otherPlace) ,表示将书移到某个其他地方,还应具有receive,接受来自其他位置的书。query用来查询其所拥有的书籍信息。这样所有的移动都可以通过moveTo或重写的moveTo来实现,使得移动行为可以进行统一处理。
然后,管理类最好的理解就是图书馆本身,具有开馆,闭馆,处理用户请求如借书,取书,查询等功能,拥有的属性是部门的单例,以及在图书馆中创建的“用户”,这里的用户如果理解成实际存在的客户则不好,因为这些用户的对象并不一直存在,只能根据用户的请求来创建,所以可以理解为是图书馆中注册的虚拟用户,对应着实体用户,但是其创建和行为是只由图书馆决定的。因此只需要让图书馆调用这些部门的单例中的方法以及用户的方法,而部门之间则完全不需要知晓彼此的存在。这样形成了由图书馆管理部门以及用户的全部行为,而不需要复杂的流程和依赖关系。
最后,开馆、闭馆、用户查询、借书、取书等等行为,都看成图书馆类的一个行为而不是用户的行为,让图书馆这个上帝视角的管理部门去对对象进行操作。且每个具体的部门可能具有特殊的行为属性。
那么类图的设计也就成型了。后续作业只加入了漂流角(一个行为比较简单的Place子类)和信誉积分规则(可以看作是用户的属性,因此不需要额外加入一个新类),整体的架构没有变化。
第一次:
第二次:
第三次:
状态图:
此外开馆时的行为比较复杂,因此以最后一次作业为例,简单梳理一下开馆时的行为顺序。
然而最开始图的设计和代码的设计往往并不是完全符合的,这是因为具体的行为中是否需要分解是无法在类图中确定的,比如在reserveOffice中可以预料的是checkAndReturn方法,而需要的额外方法比如需要加入书籍进入的时间点等信息需要额外的方法,再比如检查书籍是否在属于“有效预约”,其中是否在预约处的检查reseved()是后加入的,对于部门的代码实现是有无限可能的,在三次作业中变化比较大。
在整个课程中,我获得了丰富的知识和宝贵的经验,这些收获不仅提升了我的专业技能,也拓宽了我的视野和思维方式。
首先,我深入了解了软件测试的基本原理和方法,包括黑盒测试、白盒测试、性能测试、安全测试等,这些理论知识为我后续的实践提供了坚实的基础。同时,我也学会了如何制定测试计划、编写测试用例、执行测试并分析结果,这些技能对于提高软件质量至关重要。
其次,通过课程中的项目实践,我得以将理论知识应用于实际情境中,这不仅加深了我对测试流程的理解,也锻炼了我的问题解决能力。在实践中,我遇到了各种挑战和困难,但通过不断尝试和反思,我逐渐找到了解决问题的方法,这种经历让我更加自信和有能力应对未来的挑战。
此外,课程还培养了我的团队合作能力和沟通技巧。在团队项目中,我学会了如何与他人协作、分工合作,并共同解决问题。同时,我也学会了如何有效地沟通,包括如何清晰地表达自己的观点、如何倾听他人的意见以及如何协调不同意见等。这些能力对于我的职业发展具有重要意义。
最后,整个课程也提升了我的学习能力和自我管理能力。面对新的知识和技术,我能够主动学习和探索,并通过不断实践来加深理解。同时,我也能够合理安排时间和任务,确保自己的学习效率和工作进度。
总之,整个课程让我收获颇丰,不仅提升了我的专业技能和解决问题的能力,也培养了我的团队合作能力和沟通技巧。这些收获将对我未来的职业发展和个人成长产生积极的影响。