第二次软构实验总结


date: 2019-03-26 16:45:47

Lab2

有惊无险总算算是搞完了。

这次实验感觉……就有点刺激了?

和之前的一样,还是糊弄着大概捋一下整个实验的过程吧。

(是的没错我没写P4)

Abstraction Function

抽象函数

大概就是……建立起一个映射,一种由所有变量构成的集合到现实生活中对应的东西的映射。

比如Graph类是由vertices和edges构成的,那就可以写成:

AF(vertices,edges) = A graph made up of vertices and edges

(大概就是这个意思?但是似乎还是用集合的语言描述更吼一点)

Rep Invariant

表示不变量

唔,我的理解就是,对这个类里面的东西进行任何的操作,最后必须满足的条件。

比如人际关系图的Rep的其中一条就应该是,权值必须为正/为1。

所以最后类里所有的mutator最后return之前都要加上checkRep函数进行检查。

P1

这个任务要求先实现几个具体的用String构图的两种类型的图,再泛型化(我也不知道叫什么总之就是变成泛型?)。

这里要求实现的图分两种,一种是通过边(Edge)的列表(List)和顶点(Vertex)的集合(Set)确定的图,需要实现的是Edge类;另一种是通过Vertex的List确定的图,需要实现的是Vertex类。

大概……是这么回事。

Edge图

第一种,我们简称Edge图好了。

要求Edge得immutable。

大概就是……所有的Edge都装在一个List里面,所有的Vertex都装在一个Set里面,需要啥就遍历着找。

虽然实现简单但是显然……干啥基本都得遍历整个List,效率可能比较差。

Vertex图

第二种,我们简称Vertex图。

要求Vertex得mutable。(那就加几个mutator,跟上面其实没有本质的区别)

每个Vertex里面都有一个id表示边的起点,剩下一个Map,表示终点和边的长度的映射关系。

这个用来写那个targets(source)就方便多了,直接返回一个Map就得了,非常方便。

但是码量似乎比Edge图更大一点。(似乎也没有大很多,去掉mutator应该还少了)

泛型化

直接把所有的String都改成L,然后你会发现飘红一片,原因大概率是没有加尖括号L和用了String特有的CompareTo(所以之后我全用equals了)

综合上面说的两种图的优劣,我还是用了Vertex图来填充Graph.empty()。

P2

P2非常简单,就是Lab1的P3的重构。

写起来非常快

但是

要注意

Person这个类有问题

Person里面应该是只有Name这个东西的。

因为L要求是个Immutable的类。

原因如果想知道的话,可以看下面:(不想看可选跳过)

example

首先,我们所有的起点都是固定的对象,所以我们要做到跑完这四个函数不能对对象本身作出修改,否则就会出现targets返回的Map里面找不到对象的对应关系。

形象点说就是,船的所有部件都换了,只是名字没换,那么曾经在这艘船上的船员不能单凭名字判断这是他们曾经待过的船。

如果要修改也不是不行,但是代价实在太大了。

所以,step和vis还是通过Map来实现吧。

P3

P3比较麻烦,说他麻烦是麻烦在设计上。

首先,我们有了已知的几个类:ChessGame, Game, Player, Piece, Board, Position, Action。

ChessGame就是个用来get游戏是什么、玩家叫什么的大模拟,写完就完了,中间调用一下游戏就可以开始玩了,感觉没啥好说的。

Player里面只有个String,也没啥好说的。

Position就是个x和y的整形坐标,还是没啥说的。

Board是一个有自己对应的游戏种类、自己的规定大小、最开始填满null的二维ArrayList,似乎……也不用说?

比较麻烦的应该是剩下的三个:Game、Piece、Action。

Piece

棋子……是我要素过全太菜了吧,感觉写着很累。

最开始设计的时候一点思路都没有,然后开始脑补:

我是神!

创世之初,我手里有一团黏土,想着捏什么棋子比较好。

首先,它得有颜色,这样我才知道这个棋子是谁的。然后我给它染成了黑色/白色。

其次,它得有自己属于的游戏,于是我命令这块黏土必须是用来玩国际象棋/围棋的。

然后,它还得有自己的名字,这样我才知道自己碰的是什么棋子,所以这块黏土变成了马的形状/扁平的圆形。

最后,它在棋盘上有个自己的位置。(这个似乎没什么必要,但是还是加上吧不然Position就没用了)

完成!

Game

Game我定义成了一个抽象类,从中衍生出两个子类——Chess和Go。

Chess和Go里面初始化成棋局最开始的形状。

除了初始化稍微麻烦点似乎也没啥了。

大概我的实现就是这样(

show

当然,最好是多处理异常,防止 居心叵测的助教卡你 代码的鲁棒性不够。

Action

Action我的思路是……定义三个基本的方法:Add、Remove、Move

其中Move可以是Add然后就Remove

Chess、Go都有自己单独的ChessMove等等。

当然,他们都是boolean的,这样如果有问题可以根据情况处理,比如这个玩家重新操作啥的BlahBlah。

唔……应该就这么多了?

总结?

这次实验写的很累,跟上次累的还不一样

上次累在测试样例,这次

不仅测试样例写着累人

注释写着也很累人

Abstraction Function还有Rep Invariant什么的……想想真的是似乎没必要写,但是不写还真的怕错。

怕了怕了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值