软件构造----关于实验三的初步感受与思考

首先,简单介绍一下实验的完成过程(未完成,只是记录前三个任务):

最开始的时候,也是先听了老师对这个项目的分析,然后再开始实验。但很多时候就是机缘没到,听了的效果也是很微小,所以,最开始的时候绕过开篇的分析,直接从任务一开始做起。最开始的三个任务是很简单的,相应的,所以对这部分的一些要求就感觉比较琐碎,尤其是测试代码部分,因为程序的功能过于简单,所以测试代码写的很没意思很混乱,但也算完成了。值得一提的是,在写equals,hashcode函数的时候,发现了一个以前从来没有注意的防御式拷贝问题(见附1),在解决这个问题之后,其实在Vote<C>处遇见了一个问题,private Calendar calendar = Calendar.getInstance();这一行代码总是运行中出错,然后莫名奇妙修改过了之后又没有报错,不知道为什么。

然后,就是这个poll接口了,说实话,这个问题一直困扰了我很久,我不知道这个接口应该如何测试,因为它就只有一个函数能够返回,而且,这个函数还调用了两个strategy接口,所以,我就很难知道该如何测试,我进行的努力是查阅实验二,发现其实例操作的测试依赖于vertices方法的返回,所以,目前也不知道该怎么测试static方法,同时,当时认为,输出结果依赖于具体的操作,而我连操作是什么都不清楚,更无法想象结果应该是什么,所以这个的测试可以说直接让我无从下手。其实,到这里,我的实验就结束了,目前实际进展就这么些。剩下的内容,主要是我思考后的结果,并没有真正地进行实践。

之后,写一下我思考的内容:

在目前我的认知当中,按照实验指导上按部就班地做还是相当有难度的,其实,我的第一步应当从APP的框架开始,而不是从接口到APP的实现。很幸运的是,有一个election的类,尽管是一个具体类,但不妨碍它来帮助我解决问题。

election的类最大的帮助其实就是告诉我这个实验的结果是什么,操作流程是什么,客户端该怎么使用,让我对这个adt有了一定的认识。在election类中,依次创建了投票人,权重,候选人,每个投票人的投票结果,在此基础之上,再调用了poll中的函数,最终,调用结果函数,进行结果输出。尽管这个过程很简单,但它其实是告诉我这个投票adt的流程应该是什么,以及,抛开版本控制这些诸多因素,一个投票应该是怎么样的。

在此基础之上,我开始了对设计这个系统整体框架的理解:

首先要抽象出最基本的东西,也就是候选人,投票者,投票的类型,无论投票活动是什么,这些个要素都应当存在的,都应当出现在poll函数中。而在poll中,我们应当有一个实时的数据库用来存储已经获得的信息,我打算用一个Map<voter,vote<C>>的格式,这样可以保存每次投票的投票人信息,避免出现多投票的情况。然后投票活动的操作需要两个参数,一个是选票,一个是投票人。我打算在设计一个统计函数,因为不管投票活动是什么,对一次投票结果的所有类型进行初步数量统计AAA都是有用的。至此,都是通用的poll函数,都应当在通用的impl中实现,其实,在这里就出现了一个关于权值的统计问题。个人感觉,比较方便的办法是设置一个通用的Map,而对添加投票人的操作进行重载,允许其接受一个键值对(表示对应的权值)或者一个对象(默认此次选票是无权的,但会默认给此投票人设置权1),然后都会得到选票与投票人对应的map,都可以进行统计。这样,对有无权值其实就不再是一个差异性的问题。按照题目中的思路,唯一有差异的其实就是结果的统计。而我认为,能够实现差异性的策略有两种:一种是继承/一种是委派。在继承中,写处具体的拓展类来,但很明显,感觉这种拓展写死了,实用性特别差。不如用委派,委派,我的理解就是strategy。每个strategy就相当于含有一个方法,进行差异性处理。关于不同方法的具体统计,我还是存有疑惑的,如果,我们已经有了votetype类型的数值对应关系,那么,统计其实不再存在具有差异性,只需要按需分值进行计算了。所以,在这里,其实有一个关于客户端与设计者之间的交互问题。我们要不要把这个设计分值的任务交给客户端。如果后续实验可以的话,我觉得,这个任务并不是设计者需要做的,所以,我认为,在votetype中的构造方法中,对于遴选数量(value值为0/1的情况),应当根据用户传递的参数程序进行value值的匹配,那么,三个方法的遴选策略就是唯一的了,就可以给任意的投票活动进行分数评价。(但个人感觉,这种统计方式太过单调固定,尽管三个程序都是一模一样的统计方式,仍旧可以用一个只有一个实现的接口来完成)。那么评价的结果应当是什么?应该是计算的分数。这里,其实可以看到一种比较低的拓展性,进行统计函数之后,我们由候选者的各个选票数量变成了选票的分数,丢失了相当一部分信息,在一些特殊情况下,实际上就不太适合实际要求了。主要原因是目前我也没有想到其它可能的统计方式,所以,也只能按ppt中的Map<C,Double>的方式来进行结果存储。遴选这部分实际上就有很多种拓展了,比较典型的是1,2,1代表的遴选策略是与标准线比较,过线则保留,否则就抛弃。2表示分数最大向上取整,保留策略是给定标准排名个数,将各个元素的排名标成数组(不存在排名相同的两个元素),取标准排名的下一名的分数,若之前的分数大于,则保留,否则,抛弃。3表示分数最大完全取整,直接按排名取走前n位即可。

综上,三个实验最大的区别其实在于最终的遴选策略。我们可以用委派的方式,在三个子类中选择不同的委派策略。其次不同的便是合法性检查2,这个检查的目的是:“一个人所投特定种类的选票是有上限的”,相对,合法性检查1,这很明显是一种不同的(并非所有投票都需满足的)投票策略,可以在统计策略中委派出去,那么,此时在得到初步统计结果【set<K>,其中,K={C+Map<VoteType.key,number>}】之前(这样之后就失去了map<voter,vote>的信息了),就需要先进行统计,剔除非法选票(注意,此时没有给用户反馈。为了更多的统一性特征,我们没有在addvote处进行判断,按照常理来讲,应当在此处进行判断||代码可选择在此处进行判断,并增加一个空函数,用来满足日后可能让用户重新投票的可能)。上述思路,便大致可以完成实验的演示阶段,后续需要对其进行修改以满足各个任务的要求。

实验中的问题:

在poll中,Set<Vote>感觉并不是一个很好的类型,它无法加入两个相同的选票,同时,在有一个field是voters表示权值时,这个集合也不是很容易能根据权值来增加数据,所以,选择了map<voter,vote>的数据

这个impl类是否可以是一个抽象类(暂时不是特别明确抽象类的定义,只是先认为它有一个方法没有具体实现,等着它后续的扩展类来实现)?统计,遴选策略都需要具体的要求配置,也就是说,这个impl类是不会被任何app具体使用的,那么,是不是把它设置成抽象类即可?后续实验可能会尝试将其作为抽象类,看能否完成。

三个子类的共性与个性,这方面也很有一定的困扰,一个方法,其spec可以细致可以宽泛,它越细致,就越能体现共性,越宽泛,那么,就可以涵盖更多的情况,可以提取更多的共性。在statistics-strategy中,我用一个实现类就可以实现三种方法,而且也挺合理的,那么,是否需要再细分?同时,比较经典的就是权值问题与分数问题,我的选择是进行了一种宽泛化,类似适配器的模式,尽管用户可能传递无权值的投票人,没有分数只在意数量的投票选项,但我也是先宽泛化,地设置权值(统一权值),设置分数(要投地选项置分数为1),个人感觉这样提高了代码地复用性,而且,对一些操作(无权值地)的拓展也并不是很多,相对是我更喜欢的操作。目前,我也是更喜欢这种把一些相对简单的不同事物抽象合并为共同事物的操作。

对可拓展性的理解:正如第三个选项的候选人数量问题,这类要求要不要拓展,要不要增加这个属性,需不需要进行委派?我的感觉是,这不算是一个特别重要的需求,就不在主类中拓展了,只在子类中进行添加,同时增加设置函数,尽管不太严谨的OCP原则,但目前能想到的投票要求也就这么多,哪怕就是再写一个impl的实现子类也并不难。

最后其实是客户端与程序员的之间的调和,客户给的要求我需要不需要让它再输入,让他额外操作,输入自己要求的一些参数条件实际上增加了客户的负担,但不让他修改实际上,就限制了客户一定的自由度,感觉比较好的是,有些方面,不要让客户再输入,而是提供修改函数,程序主体有一个客户默认的参数(quantity),如客户不加修改,则就用默认的要求,也不需要它再输入。其实,这就相当于,我提供的具体类,其统计遴选策略相当于写死了,没有给客户端更多地修改空间,方面某一具体情况的执行,但也不方便客户端要求的修改。需要提供一定的set方法来修改一些参数。

最后的最后,其实是接口和抽象类的测试,其实也想不测试他们,感觉只要各个具体类实现就行了,还需要好好研究怎么测试这种比较抽象的东东。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值