UML及oo总结
前言
仿佛是昨天,我还在de第一单元多项式的bug,回忆起Unit1的痛苦经历,再看到Unit4满分(难度不一样哈哈哈,不过也确实是成长了),感慨万分,可能是因为oo让我这个学期过于充实了吧,所以感觉是如此的快,要和oo告一段落了。
UML正向建模与开发
在本单元,我们实践了先进行UML图的建模再根据UML图来构建自己的代码的过程,三次作业分别让我们画了UML类图、状态图和时序图。
UML正向建模给我的第一印象是比直接写code要复杂的,究其原因肯定在于我们的项目比较简单,当项目的初始规模非常复杂后,UML的作用就能体现出来了,这个单元前两次作业我耐着性子先画出了UML图再进行代码的编写的,以体会UML的价值所在。提前设计好类并构想好关键类的协作与状态转变,其实相当于把以前写代码时边写边想的过程分离了,这个思想感觉也有些面向对象的感觉哈哈哈。
我们在设计的时候只需要保证设计的合理与正确即可,写code的时候也只需要保证代码符合设计并且不出错即可。这样设计与实现分离的想法为复杂工程带来了可能性。写代码时可能会遇见初始设计不合理的地方,这时就要停止code的工作去更改设计,然后再继续进行code的编写。
UML图在测试时也给我们提供了方向,我们还可以测试code与UML模型之间的统一性。
架构设计与统一性
下面是我这单元的UML类图和UML状态图以及对应的代码(时序图画的过于简单就不展示了)
首先是UML类图:

对应的代码为:
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 29 30 31 32 33 34 35 36 37 38 39 40
| public class Library { private BookShelf bookShelf = new BookShelf(); private BookShelf hotBookShelf = new BookShelf(); private HashSet<LibraryBookIsbn> toBeHot = new HashSet<>(); private HashSet<Book> bro = new HashSet<>(); private HashMap<String, ReserveOrder> ao = new HashMap<>(); //stuId-order private ArrayDeque<ReserveOrder> orderDeque = new ArrayDeque<>(); private HashSet<String> hadOrderdIds = new HashSet<>(); private HashMap<String, Book> rr = new HashMap<>(); //stuId-Book private HashMap<LibraryBookId, Book> books = new HashMap<>(); private HashMap<String, User> users = new HashMap<>(); //stuId-User private HashMap<LibraryBookId, Pair<LocalDate, String>> borrowedBooks = new HashMap<>(); private LocalDate lastOpen = null; operations... } public class Book { private LibraryBookId id; private LibraryBookState state = LibraryBookState.BOOKSHELF; private ArrayDeque<LibraryTrace> deque = new ArrayDeque<>(); private int due; operations... } public class BookShelf { private HashMap<LibraryBookIsbn, HashMap<LibraryBookId, Book>> bookShelf = new HashMap<>(); operations... } public class User { private String stuId; private Book bbook; private HashMap<LibraryBookIsbn, Book> cbooks; private int credit; operations... } public class ReserveOrder { private String usrId; private LibraryBookIsbn isbn; private Book book; private LocalDate date; operations... }
|
我对这次作业的图书馆系统设计了几个关键的类,首先是Book、Library、User,这三个类是最容易抽象出来的,所承担的任务也是最重的,Library负责接受各种命令,User和Book负责和Library交互。
同时为了方便管理Book,我还设计了一个BookShelf类,对外提供简介的拿取和放置接口。
为了简洁的实现预约功能,我还抽象了一个Order类负责记录各种预约的信息,方便查询和过期处理。
然后是UML状态图:

和对应的代码:
1 2 3 4 5 6 7 8 9 10 11 12
| @Trigger(from = "InitState", to = "BookShelf") @Trigger(from = "BookShelf", to = {"User", "HotBookShelf", "AppointmentOffice", "ReadRoom"}) @Trigger(from = "User", to = "BorrowReturnOffice") @Trigger(from = "HotBookShelf", to = {"User", "BookShelf", "AppointmentOffice", "ReadRoom"}) @Trigger(from = "Appointment Office", to = "BookShelf") @Trigger(from = "BorrowReturnOffice", to = "BookShelf") @Trigger(from = "ReadRoom", to = "BorrowReturnOffice") public void move(LocalDate date, LibraryBookState nextState) { LibraryTrace trace = new LibraryTrace(date, state, nextState); deque.addLast(trace); state = nextState; }
|
我的Book的状态转移很简单,就是一个move,参数有下一个状态,Book内部记录当前状态,改变当前状态时会记录下这次转移,方便下次查询。
Book的状态其实就是Book处于什么位置,Book可能出现的位置有:BookShelf、User、AO、BRO、RR、HotBookShelf,一一注意即可。
UML时序图我画的非常简单,就不展示了。
大模型辅助正向建模体验
本次作业助教创新性的引导我们使用大模型来帮我们辅助正向建模。
用好大模型不是把指导书全丢给他就行了,因为大模型对于业务的理解能力非常差,而要用好大模型,我们就做到对指导书的理解,然后让大模型发挥它的长处(补全)
大模型补全能力是非常强的,我们只需要加以提示和引导就能构建一个不错的模型。在对于指导书的理解的基础上,给出自己模型的框架,比如需要有什么类,类里有什么基础的属性和方法,承担了什么功能,把这些描述好后让大模型去“补全”就能得到初版,这已经为我们节省了很多的工作,同时我们的思路也能得到新的启发。
四个单元中架构设计思维的演进与四个单元中测试思维的演进
设计思维
首先讲讲设计思维的变化
由于oopre的作用,我在接触第一单元时没有那么的吃力,但是现在回顾起当时的设计,还是觉得非常丑陋的,也因此吃了设计不好的亏,第一单元错了很多。
一开始只知道要设计类,但是并没有太注意类之间的协作,同时为了实现简介干净,还需要理解封装的重要性。到了第四单元,这些已经改善了许多。
然后是一开始是想一出是一出,在屎山上不断的打补丁,这也是非常不好的,首先要做好初步的设计,然后每次迭代都要在原有的设计上重新设计再去code。
测试思维
java有两种测试方法
一种是面向评测机的测试(bushi,另外一种是写单元测试那一套。
第一单元我还不知道测试的重要性,过了中测就没管了,果然强测惨不忍睹。
后来我学会了搭建评测机,但是自己编写的实在太简单了,又引入了大模型的帮助,来帮我完善评测机的功能。
在JML一章,我还领略了单元测试的强大,在设计上针对每一处做好测试,基本能保证最后的功能正确。
课程收获
在oo这门课上我最大的收获是抗压能力变强了,学期初在oo上栽了一个大跟头,但也慢慢的调整了过来,没有脱离大部队的脚步。
然后是我通过oo这门课学会了工业中存在“设计”这门“艺术”,像荣老师所说,至少知其然也浅浅的知其所以然,算是踏上了成为一名合格的程序员的第一步。
在此感谢oo这一学期的陪伴,感谢老师与助教的工作!也希望自己能成为oo助教,为课程组带了新的东西!