BUAA_OO_Unit4

王宇汀-22371351 学生 2024-06-10 23:52:44

目录

  • 一、正向建模与开发
  • 二、第四单元架构设计
  • 1.类图
  • 2.架构分析
  • 数据结构
  • 开闭关书籍整理移动流程
  • 用户请求处理
  • 信用积分更新
  • 三、谈谈自己设计思维的演进(8分)
  • Unit1.层次化设计
  • Unit2.多线程设计
  • Unit3.规格化设计
  • Unit4.正向化设计
  • 四、谈谈自己测试思维的演进(6分)
  • 1.白嫖测评机
  • 2.手搓特殊数据
  • 3.拍拍你的
  • 4.耐心测试
  • 五、课程收获

一、正向建模与开发

hw13刚开始并没选择正向建模 本单元理想的正向建模与开发belike:

需求分析:等等党等2天,将指导书、讨论区、微信群的需求整合起来,形成图书管理系统的需求文档

类图建模:根据需求文档,大致划分需要的类,预期类的属性和方法以及类与类之间的关系,并大体粗略绘制类图

顺序图建模:结合类图分析,绘制顺序图以描述对象之间的交互

状态图建模:绘制状态图,梳理对象之间的交互关系,对象之间的消息传递顺序

设计与实现:基于上述模型正向开发,进行代码实现,并对模型图进行调整与修改

验证与测试:通过跑测评机和手搓特殊数据确保代码正确性,通过肉眼反复比对类图和代码是否实现一致

在后续我感受到了正向建模开发的唯一好处,有效减少了开发迭代过程中的工作量,可以通过先在上一单元的UML类图进行修改,然后再实现代码,前后变化一目了然的。

二、第四单元架构设计

1.类图

img

你猜为什么没有顺序图和状态图?(太水了,懒得喷.jpg)(。•̀ᴗ-)✧

2.架构分析

数据结构

Library 图书馆:储存所有在架书籍,储存所有有过操作的用户,分发请求

BorrowLibrarian 借阅处:储存所有被扣书籍,处理borrowreturnrenew

OrderLibrarian预约处:储存所有预定书籍,处理orderpick

ArrangeLibrarian 中转站:储存所有accept但未分配书籍的请求,处理开闭关的书籍整理移动

DriftLibrarian 图书漂流角:储存所有野书,处理donate

Machine查询机器:处理query

开闭关书籍整理移动流程

为了操作的简便性,只在夜晚进行书籍移动,其实可以在开馆的时候对处理完的过期预约,进行再次分配,但我是懒狗(゚Д゚≡゚д゚)!?

if (command.getCmd().equals("OPEN")) {
    //更新用户信用积分
    library.renewStuScoreOpen(date);
    //1.清理过期预约(中间可能歇业了?)
    library.getOrderLibrarian().clearToShelfOpen(date);
    library.getArrangeLibrarian().printInfo(date);

} else if (command.getCmd().equals("CLOSE")) {
    //更新用户信用积分
    library.renewStuScore(date);
    //1.清理过期预约
    library.getOrderLibrarian().clearToShelf(date);
    //2.借还处所有的书还回去
    library.getArrangeLibrarian().moveBorrowToShelf();
    library.getArrangeLibrarian().moveBorrowToDrift();
    //3.新预约运到预约处
    library.getArrangeLibrarian().arrangeOrder(date);
    library.getArrangeLibrarian().printInfo(date);
} 

用户请求处理

borrowreturnpickdonatequery:较为常规,省略

orderpick:我的设计最为抽象的部分来了

数据结构十分复杂 边查边删十分丑陋

public class OrderLibrarian {
    //储存预约书籍
    private TreeMap<LocalDate, HashMap<String, HashMap<LibraryBookId, Integer>>> orderBooks;
    
    //清理过期预约
    public void clearToShelf(LocalDate date) {
        Iterator<LocalDate> iterator = orderBooks.keySet().iterator();
        while (iterator.hasNext()) {
            LocalDate date1 = iterator.next();
            long cha = date1.until(date, ChronoUnit.DAYS);
            if (cha >= 5) {
                for (Map.Entry<String, HashMap<LibraryBookId, Integer>> entry :
                        orderBooks.get(date1).entrySet()) {
                    library.getStudents().get(entry.getKey()).orderOverdue(entry.getValue());
                    library.getArrangeLibrarian().moveOrderToShelf(entry.getValue());
                }
                iterator.remove();
            }
        }

    }   
}
public class ArrangeLibrarian {
    //储存所有accept但未分配书籍的请求
    private ArrayList<LibraryRequest> needArrangeOrder;
    
    //每晚闭馆看看书架上有没有能分配的预约
    public void arrangeOrder(LocalDate date) {
        Iterator<LibraryRequest> iterator = needArrangeOrder.iterator();
        while (iterator.hasNext()) {
            LibraryRequest request = iterator.next();
            if (haveBookToOrder(date, request)) {
                iterator.remove();
            }
        }
    }
}

信用积分更新

这块我也写的特别抽象.....(゚Д゚≡゚д゚)!?

因为我开闭馆都要进行信用积分更新,怎么才能保证一本书过期学生的信用积分只减一次

我利用数据局限性,学生只能同时持有一个书号的书,设置了HashSet<LibraryBookId> overDue,起到一个Flag标记位的作用

//Student.java
public void updateScore(int x) {
    int old = score;
    score = Math.min(old + x, 20);
}

public void renewScore(LocalDate date) {
    for (Map.Entry<LibraryBookId, Integer> entry : borrowBooks.getBooks().entrySet()) {
        if (entry.getValue().equals(0) || overDue.contains(entry.getKey())) {
            continue;
        }
        //.....
        if (date.isAfter(store.plusDays(tmp))) {
            score = score - 2;
            overDue.add(entry.getKey());
        }
    }

}
//ArrangeLibrarian调用
public void orderOverdue(HashMap<LibraryBookId, Integer> map) {
    for (Integer integer : map.values()) {
        if (integer.equals(0)) {
            continue;
        }
        updateScore(-3 * integer);
    }
}

三、谈谈自己设计思维的演进(8分)

Unit1.层次化设计

忆往昔峥嵘岁月稠,我现在仍能回忆起我最满意的架构

分工明确 高内聚低耦合(u‿ฺu✿)

表达式预处理Predeal

表达式解析,递归下降法构建Lexer类和Paser

表达式类Expr、项类Term、因子Fatcor

Factor 实现类

  • VarFactor幂函数因子 ,定义为x^a
  • ExprFactor表达式因子 ,定义为(expression)^a
  • NumberFactor常数因子
  • FuncFactor 自定义函数因子

单项式类Mono、多项式类Poly
$$
Mono = ax^bexp^c(Poly)
$$

Unit2.多线程设计

一朝被蛇咬,十年怕井绳

  • 数据与行为分离,注意线程安全已经刻烟吸肺了º·(˚ ˃̣̣̥᷄⌓˂̣̣̥᷅ )‧º·˚ ~

  • 对于死锁和轮询,不打不相识,也有了很深刻的认识

  • 感受到了sleep睡眠大法的作用,这招名为:以退为进

Unit3.规格化设计

《重生之我是算法高手》

《图论入门与数据构造》

《三层循环会不会梦到TLE》

懒得喷 学完感觉自己就是笨蛋 退学打三年OI再来吧

意识到了规格与实现分离分离的重要性

  • 规格里的数据结构与实现分离

  • 规格里的方法与实际实现方法分离

Unit4.正向化设计

意识到了正向化建模设计的重要性,先画图再写代码效率UpUp

(下次一定)(下辈子一定)

四、谈谈自己测试思维的演进(6分)

1.白嫖测评机

伟大的稳定的DPO,在我每次写完之前就能完成更新

每次写完先交他几十发

有时测评机生成数据规模较大,就要手动分析并删繁就简,方便定位bug

2.手搓特殊数据

针对题目要求的功能实现,设计一些刁钻的数据点

比方说围城必阙,我这辈子忘不了你!!!!!

3.拍拍你的

和伟大的舍友进行对拍

数据规模较大时,在测试数据中逐行加入query指令,很快能定位到错误

4.耐心测试

对于Unit2来说,复现bug和抽SSR的概率差不多

对于大规模的项目来说,耐心,才是debug最需要的

五、课程收获

连载文《失败的艺术》正式完结( ´͈ ᵕ `͈ )◞♡

人生的道路才刚刚开始~

我失去了很多

  • 安逸自得离开了我,在自习室书桌前从早坐到晚,细想已经多久没有抬头看看晚霞了

  • 兴趣爱好离开了我,多久没有上号回家看看,多久没有拾起画笔,多久没有阅读小绿书

  • 安于现状离开了我,靠着差不多的脑子(现在我承认我是笨蛋!!!),得到差不多的成绩,来到差不多的学校,本想过着差不多的生活

    但在OO这个课程,没有差不多一词,不是AC就是WA,不优化到极致,你就有TLE的风险,不努力就真的会寄˚‧º·(˚ ˃̣̣̥⌓˂̣̣̥ )‧º·˚

我得到了更多

  • 编程能力提升了!没有OO我这辈子不会好奇dfs、bfs怎么写┐=͟͟͞͞( ̄ー ̄)┌,但我认为这是最不值一提的收获

  • 抗压能力提升了!清明三天不眠不休昼夜颠倒debug,从hw1周四开始公测还没写完到hw15没写完淡定准备通宵,没有什么好怕的了.jpg

  • 心态改变了!半年之期已到,oopre失去的统统夺回来,经历了自信心的大起大落落落落落,失去的一些回来了一些(抽象的想法),总之轻舟已过万重山

  • 良师益友增加了!报菜名一样罗列略显不优雅,不如这样!

    感谢某准备浅熬一夜的老师、某emoji群名群、某期末交流群、某三字群群u们(你们应该能认出来吧((

    你们的精神支持/自习陪伴/debug帮助/nullpointerexception啥也没有/拉扯我熬过了OO课呜呜

    ˚‧º·(˚ ˃̣̣̥⌓˂̣̣̥ )‧º·˚已经是过命的交情了!!!!!

最后感谢传道授业的课程组、助教老师们,搭测评机的&讨论区援疑质理的&研讨课高谈阔论的老师们

受益匪浅,感谢相遇,顶峰再见 ——6.10

...全文
92 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

301

社区成员

发帖
与我相关
我的任务
社区描述
2023年北航面向对象设计与构造
学习 高校
社区管理员
  • YannaZhang
  • CajZella
  • C_ecelia
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧