学生信息管理系统
项目需求
实现对学生信息的增删改查/排序
项目分析
界面:先用控制台,后面可以使用web页面展示
1 识别对象 封装[分]
界面视图类(V Views)
逻辑控制类(C Controller)
数据模型类(M Model)
2 分配职责
界面视图类
负责界面逻辑,比如:菜单/用户输入
逻辑控制类
负责学生信息的增删改查排序的算法实现
数据模型类
负责定义数据的类型(格式)
项目框架
MVC
数据模型类 StudentModel
属性(数据): id/name/age/score/height/weight/addreess
主键(唯一性)
逻辑控制类 StudentManagerController
属性:
__list_student 存储学生对象
方法:
增加: add_student
删除: delete_student
修改: update_student
排序: sort_student
界面视图类 StudentManagerViews 与用户交互
原则: 提供必要的功能/隐藏实现的细节
数据:
self.__controller
方法:
显示菜单方法: __display_menu
选择菜单方法: __select_menu
输入方法: __input_student
显示方法: __print_student
删除方法: __remove_student
修改方法: __modify_student
排序方法:__sort_by_score
主方法: main
问题:
1 ID唯一?
ID用于修改/删除
自动生成(在调用添加方法时实现自增1 [自定义:1000])
方案1: 在类外定义一个初始id,通过调用add_student方法实现自增长
缺点: 不符合面向对象的思想
方案2: 在Controller类中定义实例变量 init_id
缺点: 如果实例化多次,id会重复
方案3: 定义init_id为类变量
2 list_student 如何避免外界修改?
类外可以添加学生的对象到list_student(实例变量)
私有
问题:类外不能直接方法
措施:提供只读方法
3 删除学生对象是使用del或remove方法?
del item 删除的是一个对象,与__list_student没有关系
self.__list_student.remove(item) (对)
4 如何实现新的学生对象更新旧的学生对象?
更新数据: name/age/score
id 唯一
对比ID:找对旧的学生对象,更新name/age/score
5 在视图类中,如何更好的调用逻辑控制类中的增删改排序的算法?
StudentManagerConctroller().add_student(stu)
以上调用方法,会产生每次实例化逻辑控制类造成__list_student为空
问题:不能重复调用
措施:
1 用户实例化视图类需要几次? 1次
意味着:只调用1次构造方法
2 调用逻辑控制类的方法都是在视图类中的方法中被调用
在视图类中的构造方法中实例化逻辑控制类
好处:为视图类实例化视图类的对象添加一个属性
6 用户修改学生的信息?
1、创建一个新的学生对象(逻辑控制器类中修改方法需要传递一个修改的学生对象)
2、用户输入学生的ID(唯一性)
3、判断用户输的学生ID是否已经存在于存储学生的列表中【列表推导式】
4、存在,则用户输入name、age、score赋值给新的学生对象对应的变量
5、调用逻辑控制器类中的修改方法修改成功与否,打印提示信息
7 用户端不能违背程序设计原则?
原则:提供必要功能,隐藏实现的细节
操作:
将一些不需要提供的方法实现私有化
'''
实现学生信息管理系统
'''
import os
class StudentManagerModel:
''' 实现学生数据模型类 '''
def __init__(self, name='', age=0, score=0, id=0):
self.id = id
self.name = name
self.age = age
self.score = score
@property
def age(self): # 读取方法
return self.__age
@age.setter
def age(self, value): # 写入(保护实例变量/数据有效性验证)
if 0 <= value <= 200:
self.__age = value
else:
raise Exception('年龄应该在[0, 200]')
@property
def score(self):
return self.__score
@score.setter
def score(self, value):
if 0 <= value <= 150:
self.__score = value
else:
raise Exception('成绩应该在[0, 150]')
# 方式1:在类外产生一个变量
# init_id = 1000 # 不可变[面向过程的思想]
class StudentManagerController:
''' 实现增删改查/排序的算法 '''
# 方法3
init_id = 1000 # 类变量
def __init__(self):
# 原因: views中是用户输入的数据,通过对象的属性传递数据
# 在逻辑算法中存储学生对象可以操作兑现实现对应的功能.避免需要传入多个参数
self.__list_student = [] # 存储所有的学生对象
# 方法2:
# self.init_id = 1000
@classmethod
def generate_id(cls, stu):
''' 通过类变量,实现id自增长 '''
stu.id = cls.init_id
cls.init_id += 1
@property
def list_student(self): # 只读
return self.__list_student
def add_student(self, stu):
'''
添加学生对象
:param stu: objetct, 添加的学生对象
:return: None
'''
# 方法1: 不符合面向对象的思想
# global init_id
# stu.id = init_id # 修改学生对象的初始id
# init_id += 1
# 方法2: 如果实例化多次,id会重复
# stu.id = self.init_id
# self.init_id += 1
# 方法3:
StudentManagerController.generate_id(stu)
self.__list_student.append(stu)
def delete_student(self, del_stu_id):
'''
删除学生对象
:param del_stu_id: int, 要删除的学生的ID
:return: bool, True:表示删除成功,False:表示删除失败
'''
for item in self.__list_student:
if item.id == del_stu_id:
# del item
self.__list_student.remove(item)
return True
return False
def update_student(self, new_stu):
'''
修改学生对象的数据
:param new_stu: object, 要修改的学生对象
:return: bool, True:表示修改成功,False:表示修改失败
'''
for item in self.__list_student:
if item.id == new_stu.id:
item.name = new_stu.name
item.age = new_stu.age
item.score = new_stu.score
return True
return False
def sort_student(self):
''' 按成绩降序排列 '''
for r in range(len(self.__list_student)-1):
for c in range(r+1, len(self.__list_student)):
if self.__list_student[r].score < self.__list_student[c].score:
self.__list_student[r], self.__list_student[c] = \
self.__list_student[c], self.__list_student[r]
# 测试
# 添加学生
# stu_col = StudentManagerController()
# s01 = StudentManagerModel('孙悟空', 90, 77)
# s02 = StudentManagerModel('八戒', 60, 86)
# s03 = StudentManagerModel('悟净', 50, 67)
# stu_col.add_student(s01)
# stu_col.add_student(s02)
# stu_col.add_student(s03)
# 删除学生
# stu_col.delete_student(1001)
# 修改学生
# stu_col.update_student(
# StudentManagerModel('沙僧', 70, 99, 1002)
# )
# 排序
# stu_col.sort_student()
# 只读
# stu_col.list_student.append(StudentManagerModel('唐僧', 22, 99))
# for stu in stu_col.list_student:
# print(stu.name, stu.age, stu.score, stu.id)
class StudentManagerViews:
''' 实现与用户交互(输入/输出数据) '''
def __init__(self):
self.controller = StudentManagerController()
def display_menu(self):
print('1 添加学生')
print('2 查看学生')
print('3 删除学生')
print('4 修改学生')
print('5 排序学生')
print('---------------')
def select_menu(self):
chioce = input('请输入您的选择')
if not chioce:
# break # 只能用于循环中(while/for)
# return # 是作为了select_menu的返回值
os._exit(0) # 程序正常结束
if chioce == '1': # 添加学生
self.input_student()
elif chioce == '2': # 查看学生
self.print_student()
elif chioce == '3': # 删除学生
pass
elif chioce == '4': # 修改学生
pass
elif chioce == '5': # 排序学生
pass
else:
print('请输入[1, 5]之间的整数')
def input_student(self):
'''
用户输入学生的信息(name/age/score)
:return: None
'''
name = input('请输入姓名:')
age = int(input('请输入年龄:'))
score = int(input('请输入成绩:'))
stu = StudentManagerModel(name, age, score)
self.controller.add_student(stu)
def print_student(self):
'''
打印学生的信息
:return: None
'''
for item in self.controller.list_student:
print(item.id, item.name, item.age, item.score)
def main(self):
''' 主方法: 实现最后逻辑的链接 '''
while True:
self.display_menu()
self.select_menu()
stu_view = StudentManagerViews()
stu_view.main()