面向对象设计与构造第四单元总结

22371328曹玮琳 2024-06-17 17:58:47

UML正向建模与开发

在面向对象设计与构造的最后一堂课中,我们深入探讨了UML(统一建模语言)正向建模与开发的重要性及其在实际项目中的应用。通过这一单元的学习与实践,我们不仅对UML的核心理念有了更深刻的理解,而且能够将其应用于实际的项目开发过程中,为项目的成功实施奠定了坚实的基础。

一、UML正向建模概述

UML正向建模是指从需求分析开始,通过一系列建模活动,逐步构建出系统的逻辑模型、物理模型以及最终的实现模型的过程。它强调从用户需求出发,通过逐步细化和完善模型,确保系统的设计与开发始终与用户需求保持一致。UML提供了丰富的建模元素和图形表示法,使得我们可以更加直观地描述系统的结构和行为。

二、UML正向建模实践
想象一下,UML正向建模就像是一位细心的画家,在空白的画布上,一笔一划地勾勒出系统的轮廓。从最初的混沌无序,到逐渐展现出清晰的线条和色彩,每一步都充满了惊喜和期待。

在需求分析阶段,我们像是与用户的心灵使者,通过深入的对话,捕捉他们内心深处的需求和期望。然后,我们运用UML的用例图,将这些需求转化为直观的图形,让系统的功能边界和用户与系统之间的交互过程一目了然。

接下来,在系统设计阶段,我们就像是建筑师,用UML的类图、包图、组件图等工具,搭建起系统的骨架。类图展现了系统中的各个角色和它们之间的关系,包图则像是分类的文件夹,帮助我们组织和管理这些角色。而组件图则像是系统的蓝图,描绘了各个物理组件之间的依赖关系。

  1. 需求分析阶段

在需求分析阶段,我们像是与用户的心灵使者,通过深入的对话,捕捉他们内心深处的需求和期望。然后,我们可以使用UML中的用例图来描述系统的功能需求,通过用例和参与者之间的交互关系,清晰地展现系统的功能边界和用户与系统之间的交互过程。

  1. 系统设计阶段

在系统设计阶段,我们就像是建筑师,用UML的类图、包图、组件图等工具,搭建起系统的骨架。类图展现了系统中的各个角色和它们之间的关系,包图则像是分类的文件夹,帮助我们组织和管理这些角色。而组件图则像是系统的蓝图,描绘了各个物理组件之间的依赖关系。我们根据需求分析的结果,描述系统的静态结构和动态行为。类图用于展现系统中的类和它们之间的关系,如继承、关联、聚合等;包图用于组织和管理系统中的类和接口;组件图则用于描述系统中的物理组件以及它们之间的依赖关系。通过这些图形表示法,我们可以更加深入地理解系统的内部结构和运行机制。

  1. 编码实现阶段

在编码实现阶段,我们可以根据系统设计阶段生成的UML模型,使用面向对象的编程语言(如Java、C++等)来编写系统的实现代码。通过UML模型与代码之间的映射关系,我们可以确保代码的实现与系统设计保持一致,从而提高代码的可维护性和可扩展性。

三、UML正向建模开发的优点

  1. 提高开发效率:UML正向建模通过逐步细化和完善模型,使得开发人员能够更早地发现和解决问题,从而减少了后期修改和调整的工作量。

  2. 降低开发风险:UML正向建模强调从用户需求出发,通过逐步细化和完善模型来确保系统的设计与开发始终与用户需求保持一致。这有助于降低因需求变更或理解偏差导致的开发风险。

  3. 提高代码质量:UML正向建模使得开发人员能够清晰地理解系统的内部结构和运行机制,从而编写出更加健壮、可维护的代码。
    在UML类图中,箭头用于表示类之间的不同关系。以下是UML类图中几种主要箭头及其含义的详细解释:

四、UML类图中的箭头含义

  1. 泛化(Generalization)

    • 概念:表示类之间的继承关系,即一个更泛化的元素(父类)和一个更具体的元素(子类)之间的关系。
    • 表达方式:使用实线空心三角箭头,箭头从子类指向父类。例如,Person是父类,Student和Professor是子类。
  2. 实现(Realization)

    • 概念:表示类实现了某个接口,即类是接口所有特征和行为的具体实现。
    • 表达方式:使用虚线空心三角箭头,箭头从实现类指向接口。这表示实现类遵循了接口的约定。
  3. 依赖(Dependency)

    • 概念:表示一个类(或其他实体)在运行时依赖于另一个类。通常是因为一个类的方法参数、局部变量或其他成员使用了另一个类的对象。
    • 表达方式:使用虚线箭头,箭头从使用类指向被使用的类。这表示一个类需要另一个类来完成其相关任务。
  4. 关联(Association)

    • 概念:表示类之间的关联关系,即一个类知道另一个类的属性和方法。这种关系比依赖更强,通常表示长期的、非临时的关系。
    • 表达方式:使用实线箭头,箭头从使用类指向被使用的类。这表示一个类的全局变量引用了另一个类的对象。
  5. 聚合(Aggregation)

    • 概念:表示整体和部分的关系,即“has-a”的关系。整体对象包含部分对象,但部分对象可以属于多个整体对象,也可以为多个整体对象共享。
    • 表达方式:使用尾部为空心菱形的实线箭头,菱形指向被聚合类(部分),箭头指向聚合类(整体)。
  6. 组合(Composition)

    • 概念:表示整体和部分的关系,即“contains-a”的关系。组合是一种特殊的聚合,其中部分对象的生命周期由整体对象控制。整体生命周期结束,部分的生命周期也结束。
    • 表达方式:使用尾部为实心菱形的实线箭头,菱形指向被组合类(部分),箭头指向组合类(整体)。

三次作业的架构设计以及演进

最开始接触到图书馆作业时,我感觉到想设计出一个很好的架构是棘手的。
涉及到四个部门,分别是借还处,预约处,书架,漂流角(后加入)。
除此之外至少还应该有用户,以及一个管理类型。
我并不喜欢做非常多的类,比如将每种指令、开关门的行为、书籍类、副本类、甚至具体的某一项行为,判定,后果都单独写成类,这样给人一种食品过度包装的感觉,不利于清晰的看到整体图书馆运行时的每一部分之间的真实关系,而且这样的类图真的可以在代码之前设计出来吗?事实上我在之前作业的互测中经常看到设计出非常多类的同学,而且这次作业其实我更好奇其他同学架构,却因没有开放互测无法知晓。在群里看到一个采用类似于离散数学完全图的画法的同学,将类图画为了一个环状,每个类伸出很多个类型各自不同的触手(关系箭头)向各个其他类,这样实在让人无法感受到图书馆的类之间的关系,我认为这样的画法应该极力避免,越是复杂的类图越是需要清晰的层次。
那么刚才提到的几个部门+一个管理类+用户类可以实现我们需要的功能了吗?
几乎可以。
让我们回顾一下题目的最重要要求。

本次作业中,我们规定书籍仅可以存在于如下四个位置:书架、预约处、借还处和用户。
图书馆系统提供自助查询机查询书籍状态。
图书馆开馆后接收用户请求,输出处理结果;开馆和闭馆整理图书时,输出图书的转运路径。

首先,题目中明确说:书架,预约处,借还处,用户都是“位置”,并且书仅能存在于这四个“位置"。
那么我们让书架,预约处,借还处,用户都继承 “位置”这个类,即Place。则Place类应该具有的属性为,一个容器,包含了书的ID,以及书的副本的数量,HashMap完美符合,还应具有属性name。应该具有的行为是:moveTo(LibraryBookId id, Place otherPlace) ,表示将书移到某个其他地方,还应具有receive,接受来自其他位置的书。query用来查询其所拥有的书籍信息。这样所有的移动都可以通过moveTo或重写的moveTo来实现,使得移动行为可以进行统一处理。

然后,管理类最好的理解就是图书馆本身,具有开馆,闭馆,处理用户请求如借书,取书,查询等功能,拥有的属性是部门的单例,以及在图书馆中创建的“用户”,这里的用户如果理解成实际存在的客户则不好,因为这些用户的对象并不一直存在,只能根据用户的请求来创建,所以可以理解为是图书馆中注册的虚拟用户,对应着实体用户,但是其创建和行为是只由图书馆决定的。因此只需要让图书馆调用这些部门的单例中的方法以及用户的方法,而部门之间则完全不需要知晓彼此的存在。这样形成了由图书馆管理部门以及用户的全部行为,而不需要复杂的流程和依赖关系。

最后,开馆、闭馆、用户查询、借书、取书等等行为,都看成图书馆类的一个行为而不是用户的行为,让图书馆这个上帝视角的管理部门去对对象进行操作。且每个具体的部门可能具有特殊的行为属性。

那么类图的设计也就成型了。后续作业只加入了漂流角(一个行为比较简单的Place子类)和信誉积分规则(可以看作是用户的属性,因此不需要额外加入一个新类),整体的架构没有变化。
第一次:

img

第二次:

img

第三次:

img

状态图:

img

此外开馆时的行为比较复杂,因此以最后一次作业为例,简单梳理一下开馆时的行为顺序。

img

然而最开始图的设计和代码的设计往往并不是完全符合的,这是因为具体的行为中是否需要分解是无法在类图中确定的,比如在reserveOffice中可以预料的是checkAndReturn方法,而需要的额外方法比如需要加入书籍进入的时间点等信息需要额外的方法,再比如检查书籍是否在属于“有效预约”,其中是否在预约处的检查reseved()是后加入的,对于部门的代码实现是有无限可能的,在三次作业中变化比较大。

架构设计思维的演进

img


在面向对象设计与构造课程的四个单元作业中,你的架构设计思维的演进可以总结如下:

第一次作业:层次化设计

  • 初步理解:在这一阶段,我开始接触到面向对象的层次化设计思想,学会了如何将复杂的表达式解析和化简任务分解为不同的层次和组件。
  • 思维演进
    • 识别了不同功能的组件,如表达式解析器、运算符处理器等。
    • 理解了层次之间的交互和协作方式,如解析器将解析好的表达式传递给化简器进行处理。
    • 开始思考如何封装和复用代码,以提高代码的可维护性和可重用性。

第二次作业:多线程电梯调度设计

  • 深入应用:在这一阶段,我开始将面向对象设计应用于多线程环境中,处理了复杂的并发问题。
  • 思维演进
    • 学会了如何将电梯调度问题抽象为多个线程之间的协作。
    • 理解了线程间的同步和通信机制,如使用锁、信号量等来控制线程的执行。
    • 思考了如何设计高效且稳定的电梯调度算法,以优化乘客的等待时间和电梯的运行效率。

第三次作业:JML语言与社交网络模拟

  • 功能实现与性能优化:在这一阶段,我使用JML语言来准确表达函数功能,并实现了模拟社交网络的功能。
  • 思维演进
    • 学会了如何使用JML来严格定义函数的前置条件和后置条件,以确保函数的正确实现。
    • 理解了时间复杂度对程序性能的影响,学会了通过优化算法和数据结构来降低时间复杂度。
    • 思考了如何在保证功能正确性的同时,提高程序的运行效率。

第四次作业:小型图书管理系统实现

  • 系统设计与建模:在这一阶段,我通过UML类图、状态图和时序图来设计和实现一个小型图书管理系统。
  • 思维演进
    • 学会了如何使用UML来清晰地表达系统的结构和行为。
    • 理解了类之间的关系,如继承、关联、聚合等,并学会了如何合理地设计类的层次结构。
    • 思考了如何在满足用户需求的同时,设计出易于维护和扩展的系统架构。

总结

  • 从基础到进阶:我的架构设计思维从最初的层次化设计开始,逐渐深入到多线程并发控制、功能实现与性能优化,并最终达到系统设计与建模的高度。
  • 不断学习与提升:在每个阶段,我都积极学习新的知识和技能,并将其应用于实际的作业项目中,从而不断提升自己的架构设计能力。
  • 注重实践与思考:我不仅注重代码的实现,还深入思考了如何优化系统架构、提高代码质量和性能等问题,展现出了良好的实践能力和创新思维。

测试思维的演进

初期阶段:基础测试思维

  • 黑盒测试:在这个阶段,我主要依赖于黑盒测试方法。我关注于系统的输入和输出,设计测试用例以验证系统是否按照预期产生正确的结果。我使用了等价类划分、边界值分析、错误推测等黑盒测试技术。
  • 测试用例设计:我开始设计简单的测试用例,主要关注于系统的基本功能和常见场景。我认识到测试是确保软件质量的关键步骤,并努力覆盖尽可能多的场景。

发展阶段:引入白盒测试

  • 白盒测试:随着对系统内部结构和逻辑的理解加深,我开始引入白盒测试方法。我关注于系统的源代码、数据结构、算法和逻辑路径,设计测试用例以验证这些内部元素的正确性。我使用了代码审查、单元测试、集成测试等白盒测试技术。
  • 测试覆盖率:我开始关注测试覆盖率,努力设计测试用例以覆盖尽可能多的代码路径和条件。我理解到测试覆盖率是衡量测试完整性和充分性的重要指标。

深化阶段:综合测试策略

  • 测试策略:在这个阶段,我开始采用综合测试策略,结合黑盒测试和白盒测试的优势。我理解到每种测试方法都有其适用的场景和局限性,需要根据实际情况选择合适的测试方法。
  • 性能测试:我开始关注系统的性能表现,设计测试用例以评估系统的响应时间、吞吐量、资源利用率等性能指标。我使用性能测试工具和技术来模拟用户负载和并发场景,以发现性能瓶颈和优化点。
  • 安全测试:随着对系统安全性的重视加深,我开始引入安全测试方法。我关注于系统的安全漏洞、攻击面和数据保护等方面,设计测试用例以验证系统的安全性。我使用了渗透测试、模糊测试等安全测试技术。

成熟阶段:自动化和持续测试

  • 自动化测试:在这个阶段,我开始引入自动化测试工具和技术,以提高测试效率和准确性。我编写自动化测试脚本,用于执行重复的、可预测的测试用例,并监控测试结果。自动化测试不仅提高了测试速度,还降低了人为错误的风险。
  • 持续测试:我开始实施持续测试策略,将测试活动嵌入到开发过程中。我使用持续集成和持续部署工具,在代码提交或合并时自动触发测试执行,并快速反馈测试结果。持续测试有助于及时发现问题、降低风险,并支持快速迭代和交付高质量的软件产品。

总结

  • 我的测试思维从基础的黑盒测试发展到综合测试策略,再到自动化和持续测试,展现了对测试技术的深入理解和应用能力。
  • 我不断学习和探索新的测试方法和工具,以应对日益复杂的软件系统和挑战。
  • 我注重测试策略的制定和实施,努力确保软件的质量、性能和安全性。

课程的收获

在整个课程中,我获得了丰富的知识和宝贵的经验,这些收获不仅提升了我的专业技能,也拓宽了我的视野和思维方式。

首先,我深入了解了软件测试的基本原理和方法,包括黑盒测试、白盒测试、性能测试、安全测试等,这些理论知识为我后续的实践提供了坚实的基础。同时,我也学会了如何制定测试计划、编写测试用例、执行测试并分析结果,这些技能对于提高软件质量至关重要。

其次,通过课程中的项目实践,我得以将理论知识应用于实际情境中,这不仅加深了我对测试流程的理解,也锻炼了我的问题解决能力。在实践中,我遇到了各种挑战和困难,但通过不断尝试和反思,我逐渐找到了解决问题的方法,这种经历让我更加自信和有能力应对未来的挑战。

此外,课程还培养了我的团队合作能力和沟通技巧。在团队项目中,我学会了如何与他人协作、分工合作,并共同解决问题。同时,我也学会了如何有效地沟通,包括如何清晰地表达自己的观点、如何倾听他人的意见以及如何协调不同意见等。这些能力对于我的职业发展具有重要意义。

最后,整个课程也提升了我的学习能力和自我管理能力。面对新的知识和技术,我能够主动学习和探索,并通过不断实践来加深理解。同时,我也能够合理安排时间和任务,确保自己的学习效率和工作进度。

总之,整个课程让我收获颇丰,不仅提升了我的专业技能和解决问题的能力,也培养了我的团队合作能力和沟通技巧。这些收获将对我未来的职业发展和个人成长产生积极的影响。

...全文
182 回复 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

302

社区成员

发帖
与我相关
我的任务
社区描述
2023年北航面向对象设计与构造
学习 高校
社区管理员
  • YannaZhang
  • CajZella
  • C_ecelia
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧