309
社区成员
发帖
与我相关
我的任务
分享从创建一个类的简单操作到能够实现包括十余个类相互协作的近千行的 Java 代码,在半个学期的面向对象编程先导课的学习中收获颇多。
|-src |- MainClass.java |- DataProcessing.java |- Adventurer.java |- Package.java |- Item.java |- Bottle.java |- Spell.java |- Equipment.java |- Factory.java |- Lexer.java |- Parser.java |-test |- AdventurerTest.java |- BottleTest.java |- EquipmentTest.java |- ...
以下是在作业迭代过程中比较重要的几次架构上的调整
相对于 C 语言中的数组,Java 里面具备基础容器(ArrayList)来实现类与类之间的包容关系。在第一次作业中,利用容器,既能管理所有冒险者Adventurer,也能管理每一个冒险者所拥有的药水瓶Bottle和装备Equipment。并且利用容器自带的add和remove方法实现了:
加入一个需要管理的冒险者(新加入的冒险者不携带任何药水瓶和装备)
给某个冒险者增加一个药水瓶
给某个冒险者增加一个装备
删除某个冒险者的某个药水瓶
删除某个冒险者的某个装备
继承关系(Extend)的引入让类与类之间的关系更加清晰。如下图,引入可用物品useable的概念,并分为法术Spell和药水瓶Bottle两类时,Bottle又细分为体力恢复药水HpBottle、力量药水AtkBottle、防御药水DefBottel和魔力药水ManaBottle,Spell也细分为HealSpell和AttackSpell,基础的装备Equipment,细分装甲Armour与武器Weapon两类,武器下再详细为两类:剑Sword与魔法书Magicbook。
HashMap
HashMap 是一个散列表,它存储的内容是键值对 (key-value) 映射。区别于 ArrayList 的有序性,HashMap 是无序的,即不会记录插入的顺序。
HashSet
HashSet 是基于 HashMap 来实现的,是一个不允许有重复元素的集合,同时也允许有 null 值的出现。同 HashMap 一样,HashSet 也是无序的即不会记录插入的顺序,且 HashSet 中的元素也是对象。
HashMap<String,Adventurer> adventurers = new HashMap<>();
相比于ArrayList的遍历寻找,HashMap通过Adventurer的Id查找,使代码更为简洁。
工厂模式(Factory Pattern)中,我们定义一个用于创建对象的接口,让子类决定实例化哪个类。工厂方法使一个类的实例化延迟到其子类。 工厂模式和简单工厂模式都属于面向对象设计方法中的创建型模式,它们的目标都是解决对象的创建过程。他们都用于创建对象,将对象的实例化与客户端代码分离。 但二者仍然有不同之处。 首先,二者的抽象程度不同:工厂模式更抽象,它通过定义一个抽象工厂接口和多个实现工厂子类来生产不同类型的产品;而简单工厂模式是由一个具体的工厂类负责创建所有的产品对象。
观察者模式(Observer Pattern)是一种行为型设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,其所有依赖者都会收到通知并自动更新。
为了能随时查看雇佣关系,我在代码实现上采用了递归的思想。每位Adventurer只直接管理与之有直接上下级的雇员,当需要查看雇佣关系时,通过雇员不断遍历自己的雇员直至找到或到达递归终点。
private final ArrayList<Adventurer> employees = new ArrayList<>();
引入递归下降法处理复杂指令解析,简化复杂语法解析,需定义清晰的文法规则以避免歧义。
新增Lexer类:拆分输入字符串为词法单元(如指令类型、参数),验证格式合法性。
实现Parser类:基于文法规则(如<指令> → <类型> <参数列表>)递归解析词法单元,生成执行逻辑。
充分测试是使代码能够在一次一次的迭代中屹立不倒的必要条件。
使用Junit可以很方便快捷地进行单元测试,从而知道一个方法是否正确执行,这样可以让我们在整体运行测试之前,先对各个单元进行充分测试,很有效地降低了测试的难度。
覆盖率是主体,边界场景的覆盖更是关键。高覆盖率一定程度上代表了代码在主体上是经过考验的,而bug常出现的地方往往是边界场景。如:冒险者的血量为负的情形。
注意类方法测试的顺序问题。先测试独立的方法,再测试与其他方法相关联的方法。
在本课程中,我经历了从面向过程编程(POP)到面向对象编程(OOP)的转变。可谓是一场 “思维范式的重构”。
从关注 “步骤和流程” 到聚焦 “实体和交互”,从零散的代码堆砌到结构化的系统设计。这种转变不仅提升了代码的可维护性,更重塑了我分析和解决问题的方式。
OOP 的封装、继承、多态三大特性给我留下了深刻的影响。
封装:将代码模块化,使程序更为清晰,调用时更加便捷。刚开始理解 “封装” 时,总觉得是 “把变量设为 private,还得通过创建类方法访问”,甚至觉得多此一举 —— 直接改变量不是更方便吗?我现在明白了,封装的核心是 “控制访问权限,保护内部逻辑的完整性。
继承:使代码得以复用。
多态:让代码更为灵活。
对于题意的大段文字性的解释容易让人感到乏力和费解,所以建议在界定题意范围的地方能够多举一些典型的例子。
╔════╗ ╔╗ ╔╗ ╔════╗ ║╔══╗║ ║║ ║║ ║ ╔══╝ ║║ ║║ ║╚═╝║ ║ ║ ║╚══╝║ ╚╗ ╔╝ ║ ╚══╗ ╚════╝ ╚═╝ ╚════╝