271
社区成员
发帖
与我相关
我的任务
分享
| 类 | 功能 |
|---|---|
| Main | 程序入口,读取总指令数和每条指令,分配给AdventurerCollection类 |
| AdventurerCollection | 分析每一条指令,提供指令对应的各种方法,同时管理adventurerMap(所有冒险者)、hireMap(雇佣关系图)、tokens(lr指令的序列)和curIndex(lr指令的index) |
| Adventurer | 冒险者类,实现所有冒险者的方法 |
| Bag | 背包类,实现所有关于背包的存储和更改方法 |
| Item | 物品类,定义物品普遍属性 |
| Bottle | 药水瓶类,包含属性和数值,设定使用方法 |
| HpBottle | 药水瓶子类,增加Hp属性 |
| AtkBottle | 药水瓶子类,增加Atk属性 |
| DefBottle | 药水瓶子类,增加Def属性 |
| ManaBottle | 药水瓶子类,增加Mana属性 |
| Magic | 魔法类 |
| HealSpell | 魔法类子类,回复HP |
| AttackSpell | 魔法类子类,减少HP |
| Equipment | 装备类 |
| Weapon | 装备类子类 |
| Sword | 剑类,提升Atk属性,发动物理攻击 |
| Armour | 防具类,增加Def属性 |
| MagciBook | 魔法书类,提上Atk属性,发动魔法攻击 |
| Factory | 工厂类,批量生产UsableItem |
| HireMap | 雇佣图类,提供各种雇佣关系的查询和调整(图的保存在AdventurerCollection) |
| Lexer | tokens处理类,进行词法处理 |
| Parser | 语法处理类 |
| 接口 | 功能 |
|---|---|
| UsableItem | 可用物品接口,定义使用方法 |
| Employer | 雇佣者类,定义雇佣、受伤和通知方法 |
| Employee | 被雇佣者类,定义援助方法 |
1)第二次作业中,所有的指令处理都被放在了Main类中,同时进行指令的读入和分析调用。在第三次时,我采取命令模式,选择单独设立一个AdventurerCollection类用于管理和处理读取后的指令,Main类只承担读入每一条指令的过程。虽然这一命令模式的设计在后来的迭代中承担了许多处理命令之外的功能,不是单纯的“命令模式”,但这一改动对后面的许多迭代任务都会很有帮助,例如在AdventurerCollection中可以管理全局的冒险者以及全局的雇佣关系图,实现了全局层面的关系管理,不然不我都不敢想到了第六次作业时为了雇佣关系的添加我需要重构多少代码。
2)在第三次迭代的时候使用了接口来构建可用物品的概念,但是一开始没有把可用物品的概念想好,导致好几次不是修改接口的实现而是接口本身。不过最后还是实现了可用物品的统一接口,利用子类的继承和重写方法实现可用物品的多态.
3)第五次迭代使用了工厂模式来实现所有可用物品的生成,把生成新的类包装到工厂类中,符合开闭原则。
4)比较难受的是第五次迭代的背包修改。之前我是直接在Adventurer类中设置了各种类型物品的HashMap,各种Map的多重判断来实现对“拥有”和“携带”的区分。这一次我仍试图在原来的多重判断上修修补补,但是会导致Adventurer类的方法十分复杂(虽然迭代到最后还是挺复杂的,不太OO),多重判断条件不利于辨认。所以另外设立一个Bag类,使用了一些新的容器,并提供各种显而易见的增删查改方法。第五次还有一个问题是fight方法的输出我写错了,直到第七次才de出来。
5)第六次实现雇佣系统,单独设立一个HireMap类,用邻接表的形式记录节点与其父节点的关系,用深搜实现路径查找和相关节点的搜索。HireMap实现各种图的增删查找,在AdventurerCollection中把雇佣关系图当做属性直接添加。这一次还实现了观察者模式,设立了Adventurer类之上的两个接口Employee和Employer,各自实现呼叫和援助方法,完成了类之间的“主动”交互。
6)第七次添加了递归下降的Parser类和处理词法的Lexer类,原来的架构没有变化。
单元测试对于一些小范围的输出问题很有效果,但是对于一个长逻辑链下的某些问题就没有办法通过一系列测试来检查出来(也有可能是我我不了解某些测试的构建方法),还是需要直接的捏数据来测试整个程序。此外为了满足测试的分支覆盖率问题,力求满覆盖率,我对各个类的方法都进行了较为严密的分支检查和梳理,这帮助我de出来好几个分支遗漏和分支重合的问题。
首先就是从面向过程转换到面向对象的编程思维,在每个类的设立之前都要想好这个类应该实现什么,但更重要的是这个类不应该自己去实现什么,把相较于当前的类的“细节工作”交给别的类或者新的类去完成。其次是封装、继承和多态,不光是问题的拆解,还需要有相同问题的整合,从不同的“具体对象”中抽离出共同的属性和方法,上升为一个新的类来实现。
最最重要的一点是,我很感激checkstyle。这种强制性的规范彻底纠正了我设立变量或者方法时喜欢脸滚键盘随意命名的习惯,使每一个变量和方法都能显而易见的传达他的含义和作用。这种命名规范在迭代的调用中极为重要,可以向其他类中传递有效的信息。
我爱OO
1、可以提前给一点java语言自学的文档,初次接触这种纯面向对象的语言还是有一定的困难。
2、Junit的教程可不可以详细一点。
zxyynb