Lab3实验总结

本次实验旨在通过构建具有可复用性和可维护性的软件,运用子类型、泛型、多态等技术实现ADT,应用于TrackGame、AtomStructure和SocialNetworkCircle场景。实验涉及环境配置、面向复用的设计、设计模式(如Strategy和Memento)以及实验进度和困难解决。通过实验,体验了API设计、复用带来的便利以及设计模式和语法驱动编程的价值。
摘要由CSDN通过智能技术生成

1.实验目标概述

本次实验覆盖课程第 23 章的内容,目标是编写具有可复用性和可维护性

的软件,主要使用以下软件构造技术:

l 子类型、泛型、多态、重写、重载

l 继承、委派、CRP

l 语法驱动的编程、正则表达式

l 设计模式

本次实验给定了多个具体应用,学生不是直接针对每个应用分别编程实现,

而是通过 ADT 和泛型等抽象技术,开发一套可复用的 ADT 及其实现,充分考虑

这些应用之间的相似性和差异性,使 ADT 有更大程度的复用(可复用性)和更

容易面向各种变化(可维护性)

2.实验环境配置

简要陈述你配置本次实验所需环境的过程,必要时可以给出屏幕截图。

特别是要记录配置过程中遇到的问题和困难,以及如何解决的。

3.实验过程

请仔细对照实验手册,针对每一项任务,在下面各节中记录你的实验过程、阐述你的设计思路和问题求解思路,可辅之以示意图或关键源代码加以说明(但千万不要把你的源代码全部粘贴过来!)。

3.1待开发的三个应用场景

首先请列出你要完成的具体应用场景(至少3个,1和2中选一,3必选,4和5中选一,鼓励完成更多的应用场景)。

  1. TrackGame
  2. AtomStructure
  3. SocialNetworkCircle

分析你所选定的多个应用场景的异同,理解需求:它们在哪些方面有共性、哪些方面有差异。

共性:

  1. 需要完成功能相同:都需要对于轨道进行添加删除,添加删除Object,检查轨道是否相同,检查轨道的合法性使用相同。
  2. 轨道对象内容相同:都有中心物体,轨道,轨道物体。

差异:

  1. Trackgame 轨道很多而其他轨道只有一个。
  2. AtomStructure 需要设计实现轨道跃迁。
  3. SocialNetwork 需要实现物体关系,设计相应代码。

3.2面向复用的设计:CircularOrbit<L,E>

方法与解释如下:

Public Boolean addTrack(Track newTrack)

向physicalObjectMap中添加新轨道

Public Boolean removeTrack(Track rmTrack)

从physicalObjectMap中删除轨道,轨道上物体随之被删除,调用removePhysicalObject。

Public void addCentralObject(L co)

添加中心物体

Public void AddPhysicalObj2Track(E po,Track tk)

向轨道tk上添加新物体po,修改relOf2TraObjs

Public void removePhysicalObject(E po)

在轨道系统中删除轨道物体po,需要在关系表中删除所有与之相关的关系

Public void addRelationOfCentralObj2TrackObj(L co,E po,double weight)

向relOfCob2TraObj中添加关系

Public void remove RelationOfCentralObjs2TraObj(L eo,E po)

在relOfCob2TraObj中删除该关系。

Public boolean addRelationOf2TrackObs(E po1,E po2,double weight)

在relOf2TraObjs添加该关系

Public Boolean removeRelationOf2TrackObs

在relOf2TrackObs中删除该关系

Public void transit(E oldObj,E newObj,Track t)

将原来的轨道物体oldObj(Immutable)修改基本信息后生成的新物体newObj放到轨道t上。

Public void move(E oldObject,E newObject)

将原有的轨道物体oldObject修改基本信息为新的轨道物体newObject。

Public double getObjectDistributionEntropy()

获取轨道系统的熵值,每一条轨道上的物体数目/轨道系统所有物体数目作为p,使用entropy=-sigma(pi*log2(pi))公式计算轨道系统熵值。

Public int getLogicalDistance(E e1,E e2)

使用BFS算法计算e1和e2之间的逻辑距离。

Public Difference getDifference(CircularOrbit<L,E> that)

获得自身轨道系统与同类型轨道系统that之间的系统差异。获得两者经过排序之后的轨道(这里的轨道比较按照由内向外因此比较而不是按照半径相等对应比较),将进行比较的两轨道传入Difference对象中,交给Difference对象处理。最后返回Difference对象。

Public Boolean checkOrbitAvailable()

检查系统是否合法,直接返回true交给具体应用系统进行重写。

Public Iterator<E> iterator()

返回iterator迭代器。

3.3面向复用的设计:Track

Immutable类。只有一个radius域。

方法:

getter,静态工厂方法getInstance,compareTo(Comparable接口),equals,hashCode。

 其中,覆盖equals方法,Track使用Radius判断两个Track是否相等。

3.4面向复用的设计:L

构造CommonObject作为CentralObject和PhysicalObject的父类。其中包括obName与pos分别代表物体名称以及物体位置,Position是Immutable类型。

方法:getter,drawGraphics,hashCode,toString

声明:Public void drawGraphics(Graphics g,GraphicsPainter painter):接受Graphics类与画笔信息类在g上根据画笔信息画出物体,所谓画笔信息类是一个mutable类,承载物体中心在g上的位置、物体绘制颜色、字体信息。在物体类中声明绘制方法是想将具体绘制方法委托到具体的类,而不是通过获取物体信息然后统一绘制。

3.5面向复用的设计:PhysicalObject

Immutable类,继承自CommonObject。(没有设计为抽象类)

方法:equalsObject,compareTo(Comparable接口)

声明:1)public boolean equalsObject(Object obj),比较当前object与obj是否值相等,这里不覆盖equals,equals依旧是通过内存地址判断相等。

3.6可复用API设计

  1. 计算轨道系统熵值。在ConcreteCircularOrbit中已经具体实现。
  2. 获取最短逻辑距离。在ConcreteCircularOrbit中已经具体实现。
  3. 获取物理距离:因为在三个应用中不考虑物理位置,所以不予实现。
  4. 计算两个多轨道系统之间的差异:

在ConcreteCircularOrbit中我们将两个对应的轨道物体集合添加到Difference对象中。下面声明Difference的类设计。

每一对比较的轨道,各自形成集合且只保留各自轨道上独有的轨道物体(去除交集,这里的比较使用equalsObject进行值比较),通过两个集合构造trackDifference对象,一个轨道系统的Difference由多个trackDifference构成。在trackDifference中提供toString方法将差异转化为字串,需要注意的是,如果两个集合都为空则说明两轨道上物体完全相同,这时候不输出“物体差异”。

3.7设计模式应用

3.7.1TrackGame

实现strategy设计模式。

设计接口类AssignmentStrategy,其中只有一个List<Map<Track,List<Runner>>> assign(List<Track> tracks,List<Runner> runnerList)声明。

分别实现具体策略类,简单编排SimpleStrategy,随即编排RandomStrategy,按bestscore排序编排SortedScoreStrategy。具体类中实现assign函数。

3.7.2AtomStructure

实现Memento设计模式管理电子跃迁的状态。

设计ElectronTransitMemento类,保存电子轨道跃迁信息,分别保存跃迁电子electron,源轨道fromTrack,目标轨道toTrack。

设计ElectronTransitCareTaker类,负责保存所有的动作列表,回退历史信息(返回删除点之后的所有操作列表)。回退动作先从CareTaker类中获得删除点之后的所有历史信息,然后传入轨道系统中反方向执行操作。

3.7.3SocialNetworkCircle

不需要实现设计模式

3.8应用设计与开发

3.8.1TrackGame

  1. 初始化和清空
  2. 计算距离
  3. 调整分组
  4. 增删运动员

3.8.2​​​​​​​AtomStructure

  1. 初始化和清空
  2. 计算距离
  3. 调整分组
  4. 增减电子

3.8.3​​​​​​​SocialNetworkCircle

  1. 初始化和清空
  2. 计算距离
  3. 调整分组
  4. 增删朋友

3.9

  1. 应对应用面临的新变化
    1. TrackGame

将数据结构修改以此实现多人同组问题,将每个分组进行同一指向,即可实现四人一组情况。

​​​​​​​​​​​​​​        ​​​​​​​       2.AtomStructure

将轨道物体存储进行修改,设计质子中子类,来区分质子和中子。

​​​​​​​​​​​​​​        ​​​​​​​       3.SocialNetworkCircle

为关系增加方向性:在原来的实现中,无向边使用两条有向边表示,这里只需要改一下,添加/删除关系的时候只需要操作一条边即可。

忽略边:在读入边的时候,如果存在轨道物体向中心点的边则不操作,然后将其他所有的边加入,这里当然也包括了外层轨道到内层轨道的边,但是这里我们保留它,因为从实际应用角度出发,虽然一条边是从外层轨道到内层轨道的,但是在添加/删除关系之后这条边也可能变成内到外的边。

4.实验进度记录

请使用表格方式记录你的进度情况,以超过半小时的连续编程时间为一行。

日期

时间段

计划任务

实际完成情况

2023.4.20

15:45-17:30

完成第一部分即对于circularObject和centralObject方面

完成了circularObject相关代码的编译,centralObject尚未完成

2023.4.27

15:45-17:30

完成剩余centralObject并编译physicalObject

已完成

2023.5.3

15:45-17:30

19:00-21:00

完成第一个track方面相关代码

完成第三个相关代码

已完成

2023.5.7

16:00-21:00

将第五个要求完成

写报告

已完成

5.实验过程中遇到的困难与解决途径

遇到的难点

解决途径

不了解什么是API

上网查询相关资料

对于部分要求无法做到有效解决

询问同学,并寻找相关处理方案

对于用例规约和测试用例没有头绪

上网查找类似方案,学习

提交时IDEA报错无法上传

查询资料用git将文件push上去

 

  1. 实验过程中收获的经验教训、感想
    1. 实验过程中收获的经验教训

学会了如何使用IDEA这种IDE来完成有关于ADT的操作,能够将自己的代码变得更加简单,能够将自己的实验变得更加正确,并且更加通俗易懂,并且在涉及到API的方面有了一定的了解,对于工业化编程有了更深层次的认知。

教训:该实验表面并没有很多要求,但是对于真正深入操作时发现要编写很多代码,并查询很多资料,这样导致了在完成时时间不是很充裕,比较赶,下次应注意完成时间。

    1. 针对以下方面的感受
  1. 重新思考Lab2中的问题:面向ADT的编程和直接面向应用场景编程,你体会到二者有何差异?本实验设计的ADT在五个不同的应用场景下使用,你是否体会到复用的好处?

面对ADT更加易于理解,ADT编程相当于对问题进行逐层抽象,而使用面向应用场景编程相当于全局抽象,在ADT的设计的时候,从某种意义上来说只需要关注当前子问题层面,所以容易将问题简单化。体会到了复用的好处,复用可以使操作更加简便,便于后续操作,使得代码更加清晰完整,易于理解。

        3.重新思考Lab2中的问题:为ADT撰写复杂的specification, invariants, RI, AF,时刻注意ADT是否有rep exposure,这些工作的意义是什么?你是否愿意在以后的编程中坚持这么做?

意义:有助于区分责任,让客户理解程序,也能提高代码效率。

愿意坚持。

        4.之前你将别人提供的API用于自己的程序开发中,本次实验你尝试着开发给别人使用的API,是否能够体会到其中的难处和乐趣?

体会到了一些困难,与之前的实验相比有一些出入,不过做完整个实验看到成果还是很有成就感的,感觉到了一分耕耘一分收获。

        5.在编程中使用设计模式,增加了很多类,但在复用和可维护性方面带来了收益。你如何看待设计模式?

设计模式能够更好地约束编译者,使之能够更有条理的运行相应程序。

        6.你之前在使用其他软件时,应该体会过输入各种命令向系统发出指令。本次实验你开发了一个解析器,使用语法和正则表达式去解析输入文件并据此构造对象。你对语法驱动编程有何感受?

语法驱动可以更好的省略许多实验中需要的判断语句,可以使代码更加便捷美观。

        7.Lab1和Lab2的大部分工作都不是从0开始,而是基于他人给出的设计方案和初始代码。本次实验是你完全从0开始进行ADT的设计并用OOP实现,经过三周之后,你感觉“设计ADT”的难度主要体现在哪些地方?你是如何克服的?

困难主要在于对Java语言的不够熟悉,对于该实验的部分内容没有明确的想法,对于整体构架把握不够明确,对于不同应用特性分析较为不明。

        8.你在完成本实验时,是否有参考Lab4和Lab5的实验手册?若有,你如何在本次实验中同时去考虑后续两个实验的要求的?

没有。

        9.关于本实验的工作量、难度、deadline。

工作量较大,难度较高,deadline较为紧张。

        10.到目前为止你对《软件构造》课程的评价。

在这门课程中学会了如何自己学习代码,对于Java有了初步的了解,对于如何科学化编程有了一些认知,对于工厂类编程有着很大的帮助,对于以后的编程能够有着更好的帮助,可以使自己的编程更加的系统化,正确化。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值