\documentclass[实验报告模板]{subfiles} \renewcommand{\mydate}{ 2023/10/20 } \renewcommand{\mychapternum}{3} \begin{document} \mytitle \begin{enumerate} \myitem{实验目的}{ \item 使用第三章知识解决链表队列问题。 } \myitem{实验内容}{ \item 使用链队列模拟银行窗口业务。假设每位客户有 2 项信息:序号、金 额。早上开张后,按随机时间有客户上门办理业务,假设携带的现金是 1-20 万之间的随机数。来一位客户,就将其加入队列,等待办理业务。 假设办理业务所需要消耗的时间和金额成正比(可设置一个系数),位 于队头的客户办理完业务后,就从队列中移走。请编写程序动态模拟这 个过程。 \item (选做)在第一题的基础上,如果银行有多个窗口。 \begin{enumerate} \item 客户过来时挑队列最短的排队,后面不会换队列。 \item 如果排队过程中,出现相邻队列比自己所排队列短,则可以重新 选择队列。 \end{enumerate} } \myitem{实验原理}{ \item 程序设计原理。 } \myitem{实验步骤}{ \item 问题抽象 \item 编写程序 \item 调试程序 \item 完善总结 } \myitem{调试过程、结果和分析}{ \item C++采用面向对象的方式设计复杂程序时,要处理非常多的类型,因此可能会比较复杂; \item 传参数有引用传递、指针传递、值传递; \item 类的模板是静态多态,类的继承是动态多态; \item 子类对父类函数的重写、重载、覆盖; \item 私有、保护、公共、友元的成员访问权限; \item 比起Python和JavaScript,C++的各种类型、各种限制、各种访问权限非常复杂,由于初次调试这种复杂的程序,出现各种错误时也需要查资料解决,导致花费大约三天时间才完成这次作业; \item 但也许这就是C++这种强类型语言的特点,编写代码时需要对类型进行非常确定的定义(模板可能是例外),但这也保证了运行效率和安全性; \item 此次作业没有尝试使用异步、多线程、多进程等并发执行方式来提升执行效率并改善图形(命令行)界面体验,之后可以尝试加入; \item 也是初次使用cmake进行程序的构建、测试、打包,cmake用来管理这种多文件的复杂程序时确实比较方便。 } \myitem{总结}{ \item 对于这种较为复杂的程序,首先考虑它的架构,由于此程序需要使用到链队列的模型,而且还需要进行图形化或命令行的展示,因此考虑采用MVC架构,但又由于程序功能较少,因此不想使用多线程或异步的事件循环,因此尝试是否能在单线程同步的架构下实现MVC架构; \item 事实证明是可以在单线程同步的架构下实现MVC架构的,但是可能一些细节会有所更改,例如: \begin{enumerate} \item MVC中的Controller接受用户事件并通知Model,这种行为在没有事件循环的情况下采用了View直接调用Model来实现; \item Model通知View进行修改的行为,改为View直接依赖Model,之后更改View的时候只需调用View::refresh的方法,View就会从自己已经绑定的Model中获取数据并进行刷新。 \end{enumerate} 但是这样造成了View依赖Model,Controller依赖View和Model,也许可能不太符合MVC。 \item 之后就需要考虑如何拆分各个模块,这里采用了面向对象的思想: \begin{enumerate} \item Model: 链队列的实现、客户对象; \item View: 背景界面、排队的显示、客户的显示、走路过程中的客户的显示; \item Controller:实现主循环,单个Controller绑定Model和View,调度Model和View的更新; \item MVC: 调用主循环,综合多个Controller,统一调度所有Controller的更新,之后所有View一起更新; \item main: 实现根据用户输入进行调整调用参数,是入口文件。 \end{enumerate} 每个文件中也有类之间的继承关系: \begin{enumerate} \item SingleQueueModel继承了Model; \item SimpleQueueView继承了QueueView,QueueView继承了View; \item SingleQueueController继承了Controller,DriftingController也继承了Controller。 \end{enumerate} \item 虽然采用面向对象,总体是成功实现了,但各个模块之间的职责划分仍不是特别清晰,并且产生了很多依赖关系,因此仍需改进。 \item 由于时间有限,暂未实现相邻队列换位的模拟。 } \item \textbf{附件}\\ 运行时截图:\\ \includegraphics[width=1\linewidth]{imgs/2023-10-29-10-52-02.png} \begin{enumerate} \item 单个队列\\ \includegraphics[width=1\linewidth]{imgs/2023-10-29-10-38-47.png} \item 多个队列\\ \includegraphics[width=1\linewidth]{imgs/2023-10-29-10-40-00.png} \item 自定义\\ \includegraphics[width=1\linewidth]{imgs/2023-10-29-10-53-57.png}\\ \vspace{1em}\\ \includegraphics[width=1\linewidth]{imgs/2023-10-29-10-45-41.png} 代码:\\ \begin{enumerate} \itemsep 5em \item constants.h \inputminted[linenos=true,breaklines=true]{cpp}{../C++/第三章作业/include/constants.h} \item model.hpp \inputminted[linenos=true,breaklines=true]{cpp}{../C++/第三章作业/include/model.hpp} \item view.hpp \inputminted[linenos=true,breaklines=true]{cpp}{../C++/第三章作业/include/view.hpp} \item controller.hpp \inputminted[linenos=true,breaklines=true]{cpp}{../C++/第三章作业/include/controller.hpp} \item MVC.h \inputminted[linenos=true,breaklines=true]{cpp}{../C++/第三章作业/include/MVC.h} \item MVC.cpp \inputminted[linenos=true,breaklines=true]{cpp}{../C++/第三章作业/src/MVC.cpp} \item main.cpp \inputminted[linenos=true,breaklines=true]{cpp}{../C++/第三章作业/src/main.cpp} \item CMakeLists.txt \inputminted[linenos=true,breaklines=true]{cmake}{../C++/第三章作业/CMakeLists.txt} \end{enumerate} \end{enumerate} \end{enumerate} \end{document}