Skip to main content

HIT-Schedule-Master(CLI):基于MobileSuit的CLI程序MVC构建过程实录

· 7 min read
Ferdinand Su

前言

HIT-Schedule-Master(CLI)项目诞生于手机的更换。IOS平台下,没有可以方便导入来自教务系统的软件,再加上需要输入个人信息的软件用起来也不大放心,因此决定和@mahoshojoHCG开发(实际上是重写)一个可以把从教务系统上自己下载的xls格式课表转换成被各大平台日历系统所支持的iCalendar格式的软件。

前作因为教务系统上课表格式的变化不再可用,再加上是当时紧急赶工的产品,尽管是GUI程序,使用体验很一般,内核代码也比较混乱,因此本作的所有代码基本都是重写的,至少我是把他看成全新作品的

废话不多说,下面便是课表的开发过程!

Model-ADT

程序最核心的部分,在于课表的ADT表示和xls文档的输入。

本作中,负责这部分功能的组件被单独拆分为HIT-Schedule-Master-Core包,代码主要由我编写。

我设计的ADT分为两部分:课表条目ScheduleEntry,和课表Schedule。

课表条目ScheduleEntry

课表的一个条目,实际上是一门课在课表上占用的一个位置。然而一门课可以占用多个位置。比如在法外狂徒张三的课表中,甲课实际上占用了两个位置:周一12和周三34节,那么它实际上会被视为两个条目。

张三课表

ScheduleEntry的代码图如图所示:

课表条目代码图

作为课表条目的抽象,其设置了CourseName,DayOfWeek,Length,Teacher,StartTime,Location,Week等属性,来储存其名称、周几上课、长度、教师、起始时间、位置、上课的周数这些基本信息。

其它的属性和方法,则被用来辅助这些属性来进行工作。以Week属性为例,和它相关的方法和属性包括ChangeWeek(),ParseWeek(),MaxWeek,Week,WeekExpression。

WeekExpression是原始的周数表达式,来自xls格式的课表,形如"[1-6,8-10,12-14]周,[7,11]单周"这样。Week是按位储存的周数信息:如果第i周有课,则置第i位为1.MaxWeek是这门课的最大持续周数,如上一表达式中,MaxWeek的对应值就是14.

ChangeWeek()从表达式更改Week的值,它将调用ParseWeek(),ParseWeek()是私有的过程,它输入String而输出uint,这将是Week的新值。

课表条目类的设计,大体就是这样。

课表Schedule

Schedule类的设计如下:

课表类代码图

实际上,课表就是课表条目的集合。因此其结构本身不会很复杂,那么显然,这个类的核心在于

private readonly List<ScheduleEntry> _entries = new List<ScheduleEntry>();

其它的所有成员,要么是生成外界需要内容的组件,要么就是与外部交互其内容的方法/属性。

这其中最为重要的Item其实是索引器

public ScheduleEntry this[int index] => _entries[index];

可以提供到某一特定条目的只读访问。至于对于整个集合的访问则采用了防御性的拷贝,这一系列措施充分保证了数据安全和表示不变性。

public List<ScheduleEntry> Entries => new List<ScheduleEntry>(_entries);

类里的LoadFromStream()方法提供了从xls文档流的导入功能GetCalendar()则提供到iCalendar格式的导出功能。

本章小结

以上就是我在模型部分设计的全部内容。它能很好完成从数据源(xls)到程序的转接功能,并具有足够胜任此任务的数据安全性。

View-前端

尽管是CLI程序,HIT-Schedule-Master拥有一个相对友好的界面:

用户界面

看起来还算成熟这是基于我所设计的另一个项目前端架构MobileSuit生成的。

MobileSuit是一个基于反射的架构,因此在本作中,我对于视图的设计,除了添加的Attributes以外,就只有

(new MsHost(new Driver())).Run();

这一句了MobileSuit真是强大呢

有了强大的MobileSuit,这部分设计的工作量是基本可以忽略不计的。

Controller-控制器

Driver类是本作的控制器,也是除了Program类以外,程序本体里剩下唯一的一个类。

Driver类

它的每一个公有方法,都直接处理来自用户的指令。这一映射过程由MobileSuit完成。

这一类的中心,是Schedule属性,它是Schedule类的一个实例,表示当前储存的课表。

为了让程序看起来没那么水更强大,除了LoadXls和Export这两个核心的指令外,我还设计了LoadJson/Save来完成导入导出到Json,ImpCse/ExpCs来完成导入导出单个课程到Json,Add/Remove/Edit来增删改课程。

总结

尽管这一作品在开学前就一完成,但是我还是选择等到时机成熟指一直咕咕咕再把我设计整个程序的思路记下来,留存于此。

借此良机,我可以重新审视HIT-Schedule-Master(CLI),通过反思来找到自己的不足之处。同时,也可以为未来的自己留下宝贵的回忆黑 历 史