270
社区成员
发帖
与我相关
我的任务
分享历经5次迭代,硬核且精彩的oopre迎来了完美的落幕。依稀记得刚接触java时的毫无头绪,敲了一天屎山代码的痛苦,但这些杀不死我的,最终都会使我更强大。这篇博客,就当作我对oopre的告别吧,同时也是对下学期oo的展望。
以下是最终的架构:

创建三个类:Adventurer,Bottle,Equipment,为了实现冒险者对药水瓶和武器的增删操作,我们可以创建两个列表来管理。
ℹ️ 列表和哈希表:
列表里的数据是有序的,而哈希表是无序的。因此,如果需要一个有序的集合,或需要通过整数索引来频繁地访问元素,我们就选择列表;反之,如果需要快速地通过键来查找数据,而不在乎这些数据是如何排序的,我们就选择哈希表。
这次的作业就复杂许多,涉及到了继承和接口的设计。
对于 Bottle 细分成 HpBottle,DefBottle 等,我们就可以用继承来实现,因为HpBottle作为子类,需要实现父类 Bottle 的属性和方法,Spell 类也是同理。
如何 Use 呢?我们可以用接口来实现。接口用来定义一组方法的契约或规范,由此我们可以在不同的类中使用 Use 接口,如 Spell,Bottle.从而我们就可以把不同类的对象视为同一种接口类型。
实现了 Use 接口后,我们可以考虑创造一个 Item 接口,来管理 Bottle, Spell, Equipment,不仅实现了获取 id, type,还包括了它们的使用,即Use接口继承了Item接口,因为 Equipment 类并不要实现 Use 接口,而我们需要把这三个大类统一起来。
⚠️ 注意!
接口中的方法默认都是 public abstract 的,实现接口的类必须提供所有抽象方法的具体实现。
这次迭代涉及到了工厂模式,更加考验我们的代码框架。工厂模式需要我们将创造对象的过程封装起来,而不是在各个地方用 new 创建。我们通过在 Factory 类里面创建对象,实现良好的封装性。
从这次作业开始,我们需要考虑怎么处理主类了,因为过多指令会使Main变得冗长,难以理解。(肯定不是因为满足不了checkstyle的要求)在输入的时候我们已经把指令“切成”了数组,接着我们可以再创造一个Operation类,用于处理这个数组,将其解析为Adventurer类中对应的方法。
这次迭代则需要我们使用观察者模式来解决问题。所谓观察者模式,就是当一个对象(被观察者)的状态发生改变时,所有依赖于它的对象(观察者)都会得到通知并自动更新,从而避免了互相影响。所以我们再创建两个接口,分别是 Employer, Employee;Adventurer类则实现这两个接口。
最后一次作业则着重于新的算法实现--递归下降。具体过程为:
对表达式进行词法分析,将其细化为一系列独立的token
对表达式进行语法分析,判断这些token的组合是否符合定义的语法规则
自顶向下建树,局部分析每个节点,比如:每个表达式由若干个项相加,但是我们不用管项是否符合规则,只需传入项的解析结果即可。
那么递归下降的递归在哪里呢?其实,当表达式复杂以后,会产生许多方法的互相调用,而递归正是多个方法之间形成了一个优雅的、相互协作的调用结构。
JUnit主要用于我们自己对代码的测试,我们可以设计一些边缘数据来测试我们的代码是否存在漏洞,比如空指针。
在写JUnit时,可以通过assert断言检查我们是否得到了想要的数据,从而减少逻辑上的错误。
⚠️在每次迭代后记得思考一下,改过的代码是否会影响JUnit代码,是否需要重新修正测试代码。
第一次迭代时,我只是为了完成这次作业而写的代码,但随着迭代次数的增加,我也意识到一个好的代码框架的重要性。比如在设计工厂模式中,我们把所有对象的创造方法封装起来,这样就提高了代码的扩展性,如果以后需要加入新的类或者改变旧的类,不必在整个项目中操作,只需聚焦于Factory这一个类。
理解高内聚低耦合的代码设计思想。即我们在设计框架时,需要让能实现同一功能的对象尽量内聚在一起,从而便于理解和维护;同时尽量降低不同模块之间相互依赖的程度。如此一来,我们就不必担心在修改一个模块时,会对其他的模块产生影响,降低了产生bug的概率。
c语言是面向过程的语言,它聚焦于解决问题所用的函数,而java作为面向对象的语言,则着重考虑对象之间的相互协作,外界不能随意修改对象内部的数据,只能通过对象提供的接口(方法)来交互。
希望开设一个使用git工具和gitlab的专题,加强我们的理解和掌握。
可以预先讲一下java的语法和一些使用,刚开始的时候会有点不适应。