选课系统项目分析
项目源代码下载
本项目对于初学者来说是了解面向对象非常好的一个项目!强烈建议多敲几遍学习思路。其实整个需求看起来还是挺杂乱的,需要一点一点捋出来。具体需求如下:
角色:学习、学员、课程、讲师
要求:
1.创建北京、上海2所学校
2.创建Linux,Python,Go 3个课程
3.课程包含 [周期、价格] 通过学校创建课程
4.通过学校创建讲师
5.创建学员时,选择学校,关联班级
6.提供两个角色接口
6.1 学员视图,可以注册,选择课程(等同于选择班级)
6.2 讲师视图,讲师可以管理自己的班级,上课时选择班级,查看班级学员列表,修改所管理的学员
6.3 管理视图,创建讲师,创建班级,创建课程
7.上面的操作产生的数据都通过pickle序列化保存到文件里
关于本项目源代码已上传至Github
,感兴趣的朋友可以点击此处 点我下载源代码 进行下载。
如果下载过程中出现异常,如下图,点我,我是解决办法,如果解决办法目录中没有hosts
文件,那么请将lmhosts.sam
中的内容另存为hosts
文件即可:
项目架构设计
该项目与ATM项目一样,采用三层架构设计:
其他详细细节如下:
项目目录功能一览
这里以原版为例:
知识回顾与亮点解析
有参装饰器
由于视图有三个视图,所以这里也分为了管理员,学生,讲师三个py文件,他们每个用户在登录后执行操作时都会通过auth
装饰器,该装饰器是个有参装饰器。用来区分到底是哪一个视图中的功能请求:
面向对象的应用
其实该项目最大的亮点就在于面向对象的应用。也让初学者体会到面向对象设计的复杂程度,具体可参照源码这里一时间说不清楚。
关于存取数据也非常简单,在db_handler.py
中定义了两个方法:
save_data()
---> 执行保存实例化的对象
select_data()
---> 执行将保存的实例化对象进行反序列化
让我影响最深刻的还是,在需求分析中。每一个角色对应的功能都应该是类中的一个方法,并且严格按照需求分析来进行执行。比如:
对管理员而言这三个功能都是实际的动作化功能,那么就应该在其类下定义出这三个方法:
在这其中大量的类的组合操作使用让我联想到Django
的models
,通过.
可以不断的拿到关联表的数据。这里设计跟Django
的models
设计确实很像。
总之,这个项目学习好了后面学习Django
的时候会有似曾相似的感觉,初学者应该好好消化一下。
类方法的使用
这里有一个继承的应用,让所有的类都具有save()
方法与select()
方法,这两个方法对接 db_handler.py
中的save_data()
和select_data()
。
关于存储数据也很讨巧,以类名作为文件夹名,以实例中的name
作为存储的文件名, 因此在save_data()
和select_data()
中这两个方法你会发现通过 __name__
获取对象的名字操作有两处.
当我们需要取数据时,类通过继承方法select()
与select_data()
对接,可以看到select()
被设置成了类方法,同时还有一个username
,那么cls
就对应文件夹名,username
就对应文件名。
公共登录接口
由于3个视图都有相同的登录功能,故这里设置了公共登录接口,但是没有设置公共注册接口。这一点让我很诧异,于是在自优化版本中也新增了公共注册接口,公共登录接口如下:
自优化版本
静态方法与类封装
这个自优化版本的代码行数少了300行,因为我用了很多的类的封装与静态方法。故很多重复代码都能进行整合统一。
对于接口层来说,我也是采用相同的方法。唯一不同点是我将接口层所有的接口全部做成了静态方法,即添加了@staticmethod
装饰器。
装饰器与实例绑定方法
我将有参装饰器改成了无参装饰器,因为原版的有参装饰器初衷就是为了区分功能函数来自于哪一个视图以及拿到该视图下的登录用户,来方便执行不同视图下的登录功能。但是我通过类的整合将全局变量的登录用户做成了self
,所以我直接将整个函数体传进去再拿到self
即可。
新增公共注册接口
由于有2个视图需要用到注册接口,故我将它做成了公共注册接口。本来teacher
是没有注册的,但是我还是将它加了上去。在实际开发中还是由留好程序的可扩展性,万一哪一天需求一变,讲师也能注册呢?
缺点
该优化版最大的缺点在于:管理员视图登录后,再去登录学生视图,会造成管理员已登录的状态下线。也就是说!不能多用户登录!原版是可以做到的,问题的原因就在于我的func_dict
,每一次选择一项功能会实例化出一个新类。所以这算是一个不小的瑕疵!