Go-Agenda
会议管理系统
Go-Agenda 为简单的会议管理系统,采用 Go
语言进行开发,开发者为xwy27 和 SiskonEmilia,开发基础与要求参阅pmlpml 课程要求
目录
项目架构解读
- Go-Agenda
- cmd (存储指令处理文件)
- root.go
- *.go (指令与其参数解析)
- data (存储数据文件)
- meetings.json
- session.json
- users.json
- global (存储全局文件)
- logger.go (Error 处理)
- model
- meeting.go (会议模型与相应数据操作)
- session.go (登陆会话模型与相应数据操作)
- storage.go (数据读入写入)
- user.go (用户模型与相应数据操作)
- operation
- meetingOperation.go (会议相关操作)
- userOperation.go (用户相关操作)
- samples (样例数据)
- sample_Meetings.json
- sample_Session.json
- sample_Users.json
- main.go
- cmd (存储指令处理文件)
项目使用 cobra 进行命令行参数解析。所以,main.go 与 cmd 文件夹为 cobra 项目初始化自动生成。
- model 文件夹存储数据模型,项目的底层结构,直接进行数据读写
- operation 文件夹定义模型的抽象操作,调用 model 包导出函数完成数据同步。其中,operation 进行部分抽离,调用数据同步前的进行参数合法性校验,保证底层数据操作可以无需关心数据合法性
- cmd 文件夹内每个go文件对应一条指令,并解析各自命令行参数;解析完毕后调用相应 Operation 包导出的函数
源码解读
命名
常用变量名与函数名采用驼峰式命名(除
Go
要求包导出变量与函数的首字母必须大写,其余均符合)循环变量等暂时变量采用单字母命名
注释
本次编程注释采用 Go Comment 规范,保证源码可读性。依据项目架构解读进行理解后,可阅读源码进行深入了解或维护。
包内导出函数包含函数注释说明,了解函数用途与返回值
1
2
3
4
5
6// ValidateMeeting validates meeting time properties and returns, if something wrong, an error
// Valid meeting contains start time and end time and the time interval is right while,
// sponsor and participators only attend this new meeting in the meeting time interval
func ValidateMeeting(meeting *model.Meeting) error {
/* Code here */
}函数内执行过程,采用注释说明当前执行逻辑
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67func AddMeeting(Title string, Participators []participator, StartTime string, EndTime string) error {
// Check log in
currentUser, err := model.GetCurrentUserName()
if err != nil {
return err
}
// Validate Title
if len(Title) == 0 {
return errors.New("Meeting Title is required")
}
// Check Title existence
m, err := model.FindMeetingByTitle(Title)
if err != nil {
return err
}
if m != nil {
return errors.New("Meeting: " + Title + " is existed")
}
// Validate participator
if len(Participators) == 0 {
return errors.New("Meeting Participator is required")
}
for _, p := range Participators {
user := model.FindUserByName(p.Username)
if user == nil {
return errors.New("Participator: " + p.Username + " does not exist")
}
}
// Check Sponsor without in participator
for _, p := range Participators {
if currentUser == p.Username {
return errors.New("You could not attend meeting sponsored by you as a participator")
}
}
// Check valid time
s, err := time.Parse(timeFormat, StartTime)
if err != nil {
return errors.New("Start Time is invalid")
}
start := s.Unix()
e, err := time.Parse(timeFormat, EndTime)
if err != nil {
return errors.New("End Time is invalid")
}
end := e.Unix()
newMeeting := &model.Meeting{
Title: Title,
Sponsor: currentUser,
Participators: Participators,
StartTime: start,
EndTime: end,
}
if err := ValidateMeeting(newMeeting); err != nil {
return err
}
err = model.AddMeeting(newMeeting)
return err
}Robust
所有函数出错均返回 Error,并在顶层 cmd 调用中通过
PrintError
进行错误处理
后记
在使用与调用开源库以来,一直存在的痛苦:开源代码无注释/文档不清不楚,导致耗费大量时间去理解与调试。己所不欲勿施于人,所以,即使这次开发过程略显仓促,但依旧强迫着保持代码规范与 robust,保证代码可读性与维护性。希望之后能一直这么保持下去吧。
开发期间由于个人原因出去参加比赛了,导致项目进度一度拖后,十分感谢 SiskonEmilia 的包容。