OO_Unit4

[TOC]

一、正向建模与开发

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

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

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

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

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

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

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

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

二、第四单元架构设计

1.类图

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

2.架构分析

数据结构

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

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

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

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

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

Machine查询机器:处理query

开闭关书籍整理移动流程

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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:我的设计最为抽象的部分来了

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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();
}
}

}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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标记位的作用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//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

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