• 第3章 系统的总体设计(抽象工厂+反射解耦业务层和数据访问层)


    3.1 系统的业务流程

    根据用户需求,本系统业务流程的设计如图3-1

    3-1 系统业务流程图

    3.2系统的分层设计

    在软件体系架构设计中,分层式结构是最常见,也是最重要的一种结构。微软推荐的分层式结构一般分为三层,从下至上分别为:数据访问层、业务逻辑层、表示层。本系统也采用了这种分层的方式。下图3-2为本系统分层架构图。

    图3-2 系统架构图

    数据访问层:主要负责数据库的访问。简单的说就是实现对数据表的SelectInsertUpdate Delete的操作。在线考试考试系统的数据访问层中使用了NHbiernate作为OR映射工具。

    业务逻辑层:是整个系统的核心,它与这个系统的业务(领域)有关。在线考试的业务逻辑主要是关于考试规则的逻辑。比如考试迟到不能参加考试、不能提前交卷等。如果涉及到数据库的访问,则调用数据访问层。

    表示层:是系统的UI部分,负责使用者与整个系统的交互。在这一层中,理想的状态是不应包括系统的业务逻辑。表示层中的逻辑代码,仅与界面元素有关。在线考试中,是利用Asp.net来设计的,因此包含了许多Web控件和相关逻辑。

    3.3系统的包的设计

    包在.net中对应的术语是命名空间。在线考试系统划分了三个大的命名空间,分别是Web(包括表示层的内容)、BLL(包括业务逻辑层的内容)和DAL包括了数据访问层的内容。其中BLL包括了5个子命名空间,分别是Domain DataInterfaceServiceUtilsException。系统还使用了其他的外部类库,包括Ajax.net,Jquery,NHibernate,Log4Net等。图3-3是系统包图,展示了包之间的依赖关系。另外两个是工具类和自定义异常包,由于与核心设计关系不大图上没有说明。

    图3-3 系统包图


    下图3-4vs解决方案中对应的项目组成。其中一个项目是个程序集。Test是个单元测试项目。

     


    3-4 解决方案图

    Domain包含了所有的领域类和映射文件,比如StudentQuestion等。大部分为数据类,没有什么行为。如图3-5所示


    图3-5 领域包的文件组织图

    DataInterface包含了数据访问层的接口IDaoIDaoFactiory工厂接口和DaoManageDaoManage是用来注入具体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脚本、WebServiceCssxslt等内容。还有一些UI相关类和HttpModule 类。NhibernateSessionModule用来实现Open Session in ViewSecurityModule用来实现安全检查。

    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对象与之对应。比如IStudentDaoITeacherDao等。而IDaoFactory应该对应的工厂方法可能有GetStudentDaoGetTeacherDao等等。可以看到各个类的依赖关系不存在从业务层到数据层的依赖。当我们想要获得一个具体Dao对象时候,我们先从DaoMangager那里通过反射获得具体DaoFactory的实例。这样我们就可以通过DaoFactory来获得具体的Dao对象了。将依赖关系倒置后我们就可以动态的切换数据访问层。因为我们的业务层不依赖与具体的数据访问层,而是依赖与数据访问层接口。

    3.6 各层之间的交互

    上面介绍了各层之间的静态关系,下面介绍各层之间是如何动态交互的。用一个实例来说明,比如要显示一个领域对象信息。如图3-11所示。



    图3-11 各层交互顺序图

    从图上可以看出消息是如何在各层之间传递的首先从显示信息的。showDomainPage发送请求给DomainService服务对象,请求获得id号为1Domain对象。DomainServiceDaoMangager那里获取具体daoFactory对象。DaoManager是根据配置文件动态的加载数据访问层程序集,然后利用反射创建daoFacotry对象的。有了daoFactory,DomainService对象再从daoFactory的工厂方法里获得自己需要的dao对象。最后通过dao对象得到最终需要的id=1Domain对象。并返回给Page对象。Page对象最后在将Domain对象的内容绑定到页面上显示给用户。这里只是简单的展示了请求是如何在各层之间传递的。当然实际的请求可能更加的复杂。关于如何删除,添加,修改等操作和显示操作的交互方式是类似的这里就不多介绍了。

    3.7系统的领域模型

    上面介绍了系统各层之间的静态和动态的关系。下面介绍下和领域相关的一些内容。主要就是在线考试系统的领域概念。下图3-12是在线考试系统的领域模型。


    图3-12 领域模型图

    下面对各个领域概念一一说明

    1Subject代表科目。

    2Chapter代表章节或者知识点。

    3QuestionContent代表了题库中的一道题。

    4TianKongContent,DanXuanContentQuestionContent的子类分别代表填空题,单选题等。

    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图

  • 相关阅读:
    pscp 从win10远程传输文件到centos7,多个虚拟机之间传文件
    Spring Aop中四个重要概念,切点,切面,连接点,通知
    查看Java的汇编指令
    Spring集成GuavaCache实现本地缓存
    RocketMq消息 demo
    使用axis1.4生成webservice的客户端代码
    oracle ORA-00060死锁查询、表空间扩容
    mysql 1449 : The user specified as a definer ('usertest'@'%') does not exist 解决方法 (grant 授予权限)
    软件安装
    动态雪花飘落
  • 原文地址:https://www.cnblogs.com/xhan/p/1202514.html
Copyright © 2020-2023  润新知