[软件管理系统类精品]基于面向对象的在线考试系统.doc
摘要目前大多数在线考试系统都是采用结构化的分析和设计实现的,这样不免在代码的复用性和可读性方面有不足,而且全部的功能都是在服务器端实现的,在性能和用户体验方面也有欠缺。本系统采用了面向对象的分析和设计,整体上采用了三层架构的设计方式,并结合了Ajax技术在客户端实现部分逻辑,使用了NHibernate作为数据访问层,大大改善了代码的重用性和可读性并改善了用户体验和系统性能,而且简化了系统的开发。本系统实现了试题管理、根据知识点制定出题策略、根据出题策略随机抽题、考试计时、自动交卷、客观题自动阅卷、在线阅卷、查看分数等功能。关键字:三层架构;面向对象;NHibernate;Ajax;XSLTAbstractRecently, most of Examination Systems are implemented with structural style design and analyse which is unavoidable to cause lack in codes reusability and readability. And their functions are implemented in server side. So they are also lack in the Users experience and performance. This system applied Object-Oriented analysis and design, and applied three layer architecture on the whole, and combines Ajax to realize some logic in the client side, and use NHibernate as data access layer. All above improves the codes reusability and readability, the users experience and the performance of system. Also simplified the development of system. This system implemented question manage, making selecting strategy according knowledge, randomly selecting question according to selecting strategy, examination timing, automatic submitting paper, auto scoring for objective question, score online, check score and other functions.Keywords:three layer architecture;OO;NHibernate;Ajax;XSLT目 录第1章 绪论11.1 系统的研究目的和意义11.2 系统的开发背景11.2.1开发工具和平台介绍11.2.2 NHibernate介绍11.2.3 XML,XSLT 生成xhtml介绍21.2.4 A和Jquery2第2章 需求分析32.1 需求说明32.2 用例说明32.3用例图4第3章 系统的总体设计53.1 系统的业务流程53.2系统的分层设计53.3系统的包的设计63.4 各层之间的依赖关系93.5 抽象工厂和反射实现对数据访问层的依赖注入103.6 各层之间的交互103.7系统的领域模型113.8系统的数据库设计13第4章 在线考试系统详细设计和实现144.1信息管理的设计和实现144.2用户登陆和安全验证204.3 试题库的设计和实现254.4 试卷的设计和实现304.5 出题策略的设计和实现354.6 考试的设计和实现394.7 学生在线考试表示层的设计和实现434.8 改卷的设计和实现494.9 用户界面的设计和实现544.9.1 Div+Css布局544.9.2 可编辑的树形控件56第5章 总结61参考文献61致谢61第1章 绪论1.1 系统的研究目的和意义随着标准化考试的日益普及,在各种考试中越来越多地采用了计算机考试的方式。相对于传统的卷面考试而言,由于传统的卷面考试从出题印刷到下发试卷等环节需要较长的时间,接触的人员相对较多,因而在保密方面具有一定的困难。而计算机考试系统采用试题库方式提供试题来源,考前无任何成套试卷,考试时考卷由计算机现场随机生成,各考生试卷不完全相同,从而避免了互相参看等作弊现象或不公平成绩的出现。目前国内在线考试系统多数都是基于asp、jsp等服务器端技术实现的。这就不免在保存答案时候要刷新考试页面和重新生成试卷。这种方式的考试系统使用起来给用户的体验非常的糟糕,而且效率不高。另外大多数的考试系统都是结构化的方式分析设计的。结构化的代码组织方式在代码复用和代码可维护性方面显然不如面向对象的方式。所以本系统在考试模块的实现上利用了Ajax方式来保存答案。并在系统分析和设计上采用了面向对象的方式。 1.2 系统的开发背景1.2.1开发工具和平台介绍本系统采用了基于.net平台的A 2.0框架。使用到了A和 Jquery作为javascript类库。使用了基于XML和xslt的转换视图来显示html考试页面。使用了NHibernate作为数据访问层框架。开发工具主要是Visual Studio 2005。使用了Visual Source Safe 2005作为源代码和版本控制工具。数据库使用的是Sql Server 2005 Express。单元测试工具使用的是NUnit。1.2.2 NHibernate介绍在企业应用开发中使用面向对象和关系数据库可能是一件非常笨重耗时的事情。NHibernate是一个针对.net平台的对象关系映射工具。NHibernate不仅可以映射.net 类到数据库表中。也提供了灵活的数据查询取回的功能。与使用sql和手工处理数据相比,有了NHibernate可以大大的减少开发时间。本系统的使用NHibernate做为数据访问层的框架,而不是直接使用ADO.NET。有NHibernate只需要编写映射文件。当使用NHibernate来做数据操作的时候NHibernate会自动生成sql语句来操作数据库的内容。映射文件会告诉NHibernate将类保存到那个表,将那个属性保存到那个字段中。NHibernate处理了所有的数据持久化工作。我们就可以专注于对象的业务逻辑。这正是面向方面编程(AOP)所提倡的把系统的职责(方面)划分到不同的模块中。NHibernate就是封装了数据持久化的这方面的任务。这样在编写核心的业务逻辑类的时候就不用关心持久化的任务了。这让代码更加的清晰容易理解。也容易修改。1.2.3 XML,XSLT 生成xhtml介绍在表示层的经典架构MVC中 ,强调Model(模型)、View(视图)、Controller(控制器)三个角色的分离。这一框架已经得到了A的默认的支持。其中aspx文件就是View,aspx.cs就是Controller ,领域类则是Model。按照Martin Flower的定义aspx算是模板视图,aspx.cs则是页面控制器。在开始设计试卷显示问题的时候,开始考虑的也是使用A 控件来生成试卷。但是试验发现由于多个试卷对象间嵌套比较复杂,将试卷绑定到控件上代码比较复杂和混乱。于是采用了另一种视图。转换视图。就是将试卷对象表示成 XML,然后用xslt将XML转换成xhtml再呈现给浏览器。这种视图使用起来比较直观。试卷对象先用XML 表示。然后通过xslt换成xhtml表示。这种方法还可以将试卷格式化成其它不同的表示,只要有不同的xslt转换就行了。1.2.4 A和JqueryAjax是一种的改善web应用程序用户体验的技术。就是在浏览器中能够向后台向服务器发出异步请求,并根据返回内容不刷新页面而更新页面的技术。它是几个老技术的综合应用。包括Javascript、XML、XMLHttpRequest对象、DOM和CSS。Javascript则是将这几种技术粘合在一起的胶水。但是浏览器之间对Javascript、DOM、CSS的支持不一致。给Ajax编程带来了很大的难度。A和Jquery正是一个提供了跨浏览器的Javascript库。它们对Ajax的支持都差不多。但是A由于是微软自己的产品,所以它可以很好的和服务器端的技术集成。比如A提供了客户端访问web服务的内置支持。Jquery 则是一个非常流行的Javascript库。它提供了非常简练操作DOM的功能。提供了非常方便获取DOM节点引用的选择器。选择器类似CSS中的选择器。链式表达式的应用也让代码更加简洁优雅。所以在系统中同时使用了这两个库。A主要用于和服务器端的通信。Jquery用来操作修改界面。相互取长补短。1.3 可行性分析 本系统属于数据信息管理系统类。用户对功能上的要求不是很复杂。加上有这么强大工具可框架支持。所以本系统十分可行。第2章 需求分析2.1 需求说明本系统统是一个基于bs结构的考试系统,它用来给学校提供无纸化考试的平台,利用本系统管理员可以管理建设各个科目的试题库,并通过章节难度来组织试题。教师可以根据题库来指定考试策略。然后根据考试策略随机的生成试卷供学生考试。试卷的题型可以包括单选题,多选题,判断题,填空题,简答题5中基本题型。也可以是这五种题的组合题型。学生参加考试应包括基本的考场规则,比如,迟到多少分钟不能进入考场,不能提前交卷。每次考试可以允许多个班级参加,不属于参加班级的学生不能参加考试。每次考试指定一个考试策略,并根据考试策略为参加考试的学生生成试卷。考试时间到后不再允许交卷。考试结束后老师可以在线的批改试卷。客观题允许自动阅卷。学生可以在线查看自己的考试成绩!2.2 用例说明1. 管理班级:管理员登陆后可以添加,删除班级。考试将要指定允许参加的班级,只要属于参加班级的学生才能参加考试。班级信息包括班级名称等信息。2. 管理教师信息:管理员登陆后可以添加修改教师信息。教师信息包括登陆名,密码等信息。将作为教师登陆验证的依据。3. 管理学生:管理员登陆后可以给班级添加学生信息,学生信息包括学号,姓名,密码等信息。密码初始为学号。学生登陆后可以修改自己信息。4. 管理题库:教师登陆后可以添加,修改,删除科目、章节、题目等信息。其中科目可以包括若干章节。科目章节是用来组织题库的。章节可以包括多个试题。试题有难度,内容,答案等信息。5. 制定出题策略:教师登陆后可以添加,删除,修改考试策略、考试题型、策略项等信息。考试策略包括若干考试题型,考试题型包括多个策略项。策略项包括题目出题范围和分值,出题数等信息用来从指定题中随机抽取一定的题目。6. 建立考试:教师登陆后可以建立一次考试,考试信息包括考试的名称,开始时间,结束时间,参加班级,迟到时间,交卷时间,和一个考试策略等信息,在线考试时候将根据考试信息模拟真实的考场规则。7. 该卷子:教师登陆后选择学生的考卷,根据学生输入的答案和标准答案给学生的每个题打分。系统允许自动给客观题打分和合计总分。8. 参加考试:学生登陆后选择参加的考试。考试根据考试规则判断是否允许学生参加。如果允许将根据指定的考试策略为学生随机生成试卷。学生考试时候可以随时保存自己的试卷。如何学生掉线重新登陆参加考试可以从上次保存后的试卷状态继续答卷。学生做完试卷可以交卷。如果交卷时间不到不允许交卷。如果考试结束也不允许交卷。9. 查看分数:学生输入学号和密码选择查看分数,系统显示所有学生所有考试的成绩单。10. 修改密码:所有用户登陆后都可以修改自己的登陆密码。2.3用例图图2-1 系统用例图第3章 系统的总体设计3.1 系统的业务流程根据用户需求,本系统业务流程的设计如图3-1。登陆管理员页面教师页面管理管理员管理学生管理教师管理班级添加考试制定出题策略管理题库管理科目学生页面批改试卷页面参加考试修改密码查看成绩单图3-1 系统业务流程图3.2系统的分层设计在软件体系架构设计中,分层式结构是最常见,也是最重要的一种结构。微软推荐的分层式结构一般分为三层,从下至上分别为:数据访问层、业务逻辑层、表示层。本系统也采用了这种分层的方式。下图3-2为本系统分层架构图。图3-2 系统架构图数据访问层:主要负责数据库的访问。简单的说就是实现对数据表的Select,Insert,Update, Delete的操作。在线考试考试系统的数据访问层中使用了NHbiernate作为OR映射工具。业务逻辑层:是整个系统的核心,它与这个系统的业务(领域)有关。在线考试的业务逻辑主要是关于考试规则的逻辑。比如考试迟到不能参加考试、不能提前交卷等。如果涉及到数据库的访问,则调用数据访问层。表示层:是系统的UI部分,负责使用者与整个系统的交互。在这一层中,理想的状态是不应包括系统的业务逻辑。表示层中的逻辑代码,仅与界面元素有关。在线考试中,是利用A来设计的,因此包含了许多Web控件和相关逻辑。3.3系统的包的设计包在.net中对应的术语是命名空间。在线考试系统划分了三个大的命名空间,分别是Web(包括表示层的内容)、BLL(包括业务逻辑层的内容)和DAL包括了数据访问层的内容。其中BLL包括了5个子命名空间,分别是Domain、 DataInterface、Service、Utils和Exception。系统还使用了其他的外部类库,包括A,Jquery,NHibernate,Log4Net等。图3-3是系统包图,展示了包之间的依赖关系。另外两个是工具类和自定义异常包,由于与核心设计关系不大图上没有说明。图3-3 系统包图下图3-4是vs解决方案中对应的项目组成。其中一个项目是个程序集。Test是个单元测试项目。图3-4 解决方案图Domain包含了所有的领域类和映射文件,比如Student、Question等。大部分为数据类,没有什么行为。如图3-5所示图3-5 领域包的文件组织图DataInterface包含了数据访问层的接口IDao、IDaoFactiory工厂接口和DaoManage。DaoManage是用来注入具体Dao工厂的简单工厂类,该类同时是访问Dao对象的门面类。如图3-6图3-6 DataInterface包的文件组织图Service 包含的是对一个对业务层的简单封装的外观类,Service类本身没有任何业务逻辑。它总是将数据访问的职责委托给Dao对象。将业务逻辑委托给Domain对象。如图3-7。图3-7 Service包的文件组织图DAL包含了具体的数据Dao实现类和使用到的几个NHiernate帮助类。该包的Dao对象利用NHibernate实现了ExaminationSystem.BLL.DataInterface中定义的数据访问接口和Dao工厂接口.如图3-8所示。图3-8 DAL包文件组织图Web包含了表示层用到的Web页面和js脚本、WebService、Css、xslt等内容。还有一些UI相关类和HttpModule 类。NhibernateSessionModule用来实现Open Session in View。SecurityModule用来实现安全检查。3.4 各层之间的依赖关系由于BLL层是整个系统的核心部分,所以表示层和数据访问层都应该依赖与BLL层。就是说要实现数据访问层对业务层的依赖倒置,这需要使用分离接口来实现。如图3-9所示,左图为业务层依赖数据访问层。右图为分离接口后倒置的依赖关系。图3-9 各层依赖图业务层和表示层的关系和以前的一样这里就不多介绍了。3.5 抽象工厂和反射实现对数据访问层的依赖注入业务逻辑层是不依赖数据访问层的,但是业务层还得使用数据访问层来操作数据。既要使用又不能依赖,这就引出了抽象工厂模式。因为不能new关键字来创建数据访问层的具体Dao对象,所以我们只能从工厂里获得Dao对象,然后通过IDao接口来使用数据访问层的Dao对象。 下面给出具体的类图来说明.如图3-10所示图3-10 抽象工厂类图为了简单,该图的IDao接口只有一个数据操作方法GetById当然还可以有Save,Update,Delete等方法。IDaoFactory里也只有一个工厂方法GetDao具体实践时候应该是每一个领域类都有一个Dao对象与之对应。比如IStudentDao、ITeacherDao等。而IDaoFactory应该对应的工厂方法可能有GetStudentDao、GetTeacherDao等等。可以看到各个类的依赖关系不存在从业务层到数据层的依赖。当我们想要获得一个具体Dao对象时候,我们先从DaoMangager那里通过反射获得具体DaoFactory的实例。这样我们就可以通过DaoFactory来获得具体的Dao对象了。将依赖关系倒置后我们就可以动态的切换数据访问层。因为我们的业务层不依赖与具体的数据访问层,而是依赖与数据访问层接口。3.6 各层之间的交互上面介绍了各层之间的静态关系,下面介绍各层之间是如何动态交互的。用一个实例来说明,比如要显示一个领域对象信息。如图3-11所示。图3-11 各层交互顺序图从图上可以看出消息是如何在各层之间传递的首先从显示信息的。showDomainPage发送请求给DomainService服务对象,请求获得id号为1的Domain对象。DomainService从DaoMangager那里获取具体daoFactory对象。DaoManager是根据配置文件动态的加载数据访问层程序集,然后利用反射创建daoFacotry对象的。有了daoFactory,DomainService对象再从daoFactory的工厂方法里获得自己需要的dao对象。最后通过dao对象得到最终需要的id=1的Domain对象。并返回给Page对象。Page对象最后在将Domain对象的内容绑定到页面上显示给用户。这里只是简单的展示了请求是如何在各层之间传递的。当然实际的请求可能更加的复杂。关于如何删除,添加,修改等操作和显示操作的交互方式是类似的这里就不多介绍了。3.7系统的领域模型上面介绍了系统各层之间的静态和动态的关系。下面介绍下和领域相关的一些内容。主要就是在线考试系统的领域概念。下图3-12是在线考试系统的领域模型。图3-12 领域模型图下面对各个领域概念一一说明1Subject代表科目。2Chapter代表章节或者知识点。3QuestionContent代表了题库中的一道题。4TianKongContent,DanXuanContent是QuestionContent的子类分别代表填空题,单选题等。5Question代表的是学生考卷上的题。注意是和QuestionContent是有区别的。Question包含学生答案和分值,QuestionContent只是包含一道题的基本信息。Question会引用QuestionContent这样可以减小数据冗余。6QuestionContainer代表的是一个大题它可以包含多个Question。比如单选题。7Paper表示一张试卷。试卷可以包含多个QuestionContainer。8Student表示学生。9Class表示班级。10Examination表示一次考试。每次考试对应一个考试策略(PaperStrategy)。12PaperStrategy是一个用来随机生成试卷的模板。13StrategyContainer是用来随机生成大题(QuestionContainer)的模板。14StrategyItem策略项:策略项包括一个试题的集合。出题的题数(题数必需小于等于试题集合的数量),分值。用来随机的从试题集合中抽取若干试题并给试题附上指定分值!每个StrategyContainer都包含多个策略项。不同的策略项区分同一题型,不同分值的题目。上面的领域模型中没有提到Admin, 和Teacher 类。因为这两个领域类与核心模型关系不大为了简洁没有将这两个列出。3.8系统的数据库设计数据库的设计和领域模型基本上一一对象。即一个领域类对应一个表。但是处于同一继承结构的领域类只有一个表与之对应。这种方法虽然浪费了些数据库存储空间但是使用起来比较方便。另外多了几个表是用来存储对象之间的关联的关联表。QuestionContent表存储了QuestionContent类的所有子类。Student表则存储了User的所有子类。为了方便Student,Teacher,Admin都继承自User。表StrategyItemQuestionContent,和ExaminationClass则是两个关联表。下图3-13是在线考试系统的ER图图3-13 数据库ER图第4章 在线考试系统详细设计和实现4.1信息管理的设计和实现对领域类的添加、删除、修改是每个系统的主要任务。下面介绍系统是如何在实现这些操作,以及如何利用泛型来减少重复代码。根据前面说到的业务层和数据访问层的关系。要添加,删除,修改信息,必需先在业务层定义业务层用到的数据访问层接口。比如要操作Student、Teacher对象,应该在业务层定义两个Dao接口。IStudentDao、ITeacherDao.下图4-1说明了这两个Dao接口的部分持久化操作的方法。图4-1 IStudentDao,ITeacherDao类图我们发现这些Dao接口都有类似的方法。只是参数和返回值不一样。如果要定义所有领域类的Dao接口。不得不到处的粘贴复制然后在修改每个方法的参数。为了减少代码的重复我们要充分利用.net 2.0的泛型机制。利用泛型我们首先定义一个泛型的接口。参数和返回值都现用泛型参数。然后在让具体的Dao接口继承泛型接口并给出类型参数就可以了。下图4-2是泛型接口的定义。图4-2 IDao泛型接口类图这样我们就不用到处粘贴修改Dao接口代码了。所有的具体Dao接口只要继承泛型的IDao并给出类型就自动有了基本的持久化操作方法定义。定义完业务层所需要的接口。接下来要在数据访问层实现这些接口。下面给出StudentDao和TeacherDao的代码。其中用两个持久化方法的代码来说明数据访问层是如何利用NHibernate来实现对Student、Teacher的持久化操作的。1.StudentDaonamespace ExaminationSystem.DAL public class StudentDao:IStudentDao private static ISessionFactory sessionFactory = new Configuration().Configure().BuildSessionFactory(); public Student GetById(long id) ISession session = sessionFactory.OpenSession(); return session.Get<Student>(id); session.Close(); public void Save(Student student) ISession session = sessionFactory.OpenSession(); ITransaction transation = session.BeginTransaction(); session.Save(student); transation.Commit(); session.Close(); 2.TeacherDaonamespace ExaminationSystem.DAL public class TeacherDao:IStudentDao private static ISessionFactory sessionFactory = new Configuration().Configure().BuildSessionFactory(); public Teacher GetById(long id) ISession session = sessionFactory.OpenSession(); return session.Get<Teacher>(id); session.Close(); public void Save(Teacher teacher) ISession session = sessionFactory.OpenSession(); ITransaction transation = session.BeginTransaction(); session.Save(teacher); transation.Commit(); session.Close(); 以上两个Dao实现方法只是为了简单的说明不是真实代码。我们发现两个Dao的具体实现也是如此的相似以至于很轻易就想到粘贴复制就可以写其他的Dao实现代码。但是一旦我们到处粘贴复制我们的代码时候我们就应该意识到我们应该来抽象。用抽象来消除重复。这里依然用泛型来解决问题。先定义一个抽象类来实现上面提到的泛型接口。并在抽象类中给出泛型版的Dao实现。最后具体的Dao继承抽象的Dao实现类并继承具体的Dao接口就可以自动实现所有的数据库操作了。下面分别用类图4-3和代码来说明是如何来实现的。图4-3 数据库接口类图下面是AbstractDao类实现。namespace ExaminationSystem.DAL public abstract class AbstractDao<T>:IDao<T> private static ISessionFactory sessionFactory = new Configuration().Configure().BuildSessionFactory(); public T GetById(long id) ISession session = sessionFactory.OpenSession(); return session.Get<T>(id); session.Close(); public void Save(T obj) ISession session = sessionFactory.OpenSession(); ITransaction transation = session.BeginTransaction(); session.Save(obj); transation.Commit(); session.Close(); 下面是更改后的StudentDao和TeacherDaopublic class StudentDao : AbstractDao<Student>, IStudentDao public class TeacherDao : AbstractDao<Teacher>, ITeacherDao 这样数据访问层常见的逻辑全部都可以由AbstractDao一个类来实现。这样大大简化了测试和开发速度。下面简要的说明系统的80%逻辑CRUD。为什么说80%的逻辑呢?我们知道对于一个信息系统来说最多的操作就是对系统信息的添加,删除,修改,和查找。为了避免重复的介绍系统这方面的功能。我们这里就用学生用户信息的添加,删除,修改,查找来概括说明系统中其他的信息的CRUD。系统中每一个领域类都有一个Dao对象。和一个Service对象。领域类负责业务逻辑。Dao对象的职责就是对领域类对象的数据库操作。而Service对象则是对业务层的封装。三者之间的关系如下图4-4所示。图4-4 各层主要类的类图 为什么要多出来一个Service那?因为Domain是系统最核心的东西。是业务逻辑的所在。所以Domain不应该依赖与其他的系统对象。但是有时候调用过Domain的业务逻辑后希望信息能够更新到数据库,所以必需要使用Dao来保存Domain,但是Domain不能依赖Dao所以就有了Service。我们可以在Service里包含与Domain相同的业务逻辑方法。然后将真正的业务逻辑委托给Domain。最后Service再调用Dao来更新数据库。又因为我们不想让表示层的UI直接依赖我们的数据访问层。Service的另一个作用就是包装Dao的方法。总之Service是业务层的外观类。它自己没有任何实现。它将业务逻辑委托给Domain,将数据操作委托给Dao.并协调所有的操作。下面是伪码说明1、Domainpublic class Domainpublic void DoSomething()/执行业务逻辑2、Daopublic class Dao:IDaopublic void Update(Domain obj)/更新Domain对象到数据库public Domain GetById(long id)/查询数据库返回Domain对象3、Servicepublic class ServiceIDao dao=new Dao();public void DoSomething(Domain obj)obj.DoSomething();dao.Update(obj);public Domain GetById(long id)return dao.GetById(id);非常遗憾的事情是系统绝大多数的逻辑就是对Domain的CRUD操作。因为大部分Domain几乎都是数据类没有什么有趣的逻辑。所以本系统的Service类多数都是简单的对Dao对象的调用。下面用伪码说明系统是如何操作Student对象的。StudentService service=new StudentService();/获取指定id学生Student student=service.GetById(id);/获取姓名是hanjie的学生Student exmple=new Student();example.Name=”hanjie”;Student student=service.GetUniqueByExample (example);/获得所有学生IList<Student> students=service.GetAll();/更新学生service.Update(student);/删除学生service.Delete(student);其他领域对象的操作和Student类的操作类似。4.2用户登陆和安全验证在线考试系统总共包括三种用户(学生、教师、管理员)。他们分别有自己的操作权限。而这些操作分别包含在不同的页面中。为了简单的划分。系统将三种用户的操作页面分别放到了不同的路径下。下图4-5是三个用户各自的文件夹内容。图4-5 不同用户的文件组织类图因为每个用户都不能访问其他用户的页面。所以我们除了要检查用户的登陆还要检查用户的权限,看是否允许用户访问特定的页面。首先介绍下用户登陆的设计和实现。下图4-6是用户登陆和权限管理涉及的领域类图4-6 用户管理模块类图 因为验证用户的职责和领域类无关,所以我们将用户验证的职责分配给了UserService对象。UserService对象除了具有CRUD用户领域类的操作外。还有一个CheckLogin的方法。该方法根据用户的输入的登录名和密码。判断是否为合法用户。如果合法将返回该用户的一个对象,否则返回空。下面是CheckLogin方法的实现。namespace ExaminationSystem.BLL.Service public class UserService:AbstractService<User,IUserDao> public User CheckLogin(string loginName, string password) /从数据库获取相同登陆名对象 User example = new User(); example.LoginName = loginName; User user = Dao.GetUniqueByExample(example); if (user.Password = password) return user;/密码正确返回该用户 return null;/否则返回空 上面代码展示的是真实的代码实现。我们可以看到用面向对象的方式编写代码代码的易读性得到大大的提