实用型系统软件架构的简易设计.doc_第1页
实用型系统软件架构的简易设计.doc_第2页
实用型系统软件架构的简易设计.doc_第3页
实用型系统软件架构的简易设计.doc_第4页
实用型系统软件架构的简易设计.doc_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

实用型系统软件架构的简易设计与实现摘 要:文章阐述了简易实用型web浏览企业应用网络系统软件框架模型的创建和层次结构,分析了它的主要科技含量,指出了它的巨大优势和市场潜力,说明了编程实现的重要技术环节,并列举了具体的实践应用。这种软件框架建模与实现:高效,简便,实用,易行。关键词:领域驱动设计ddd;对象关系映射orm;控制反转ioc;依赖注入di;面向方面编程aop;工作单元unitofwork;实体框架;窗口通信基础wcf;窗口展现基础wpf【abstract】the paper expoundsthe creation and layer-structure about a simple and practicable net-system- software-frameworkmodule of web-browser-enterprise-application. it analyzes main science-technology content. it point out thegreat advantage and marketpotential. it illustrates important programing links and lists a detailed example. the module feature: high performance, practicable, simple and easy to use.【key words】domain drive design; object relational mapping; inversion of control; dependence injection; aspect oriented programming; unit of work; entity framework; windows communication foundation; windows presentation foundation 0 引 言一般的web浏览器企业应用网络软件系统,常常采用业务数据库与b/s(brower/server)三层软件架构的形式,虽然易于软件设计和编程实现,但是维护和升级起来十分麻烦,很多时候不得不重新做起,更别提系统扩展了。这种体系,概念混淆,术语混乱,框架与模式僵化,设计与代码很难理解,sql(structured query language)运用繁琐,编程工作量大,软件制作效率低下,对于小中型企业系统还勉强凑合,对于中大型企业系统就根本行不通了。现代web浏览器企业网络软件系统设计,迫切需要高效、实用、架构简单、易于实现、编程自动化程序高、无关数据库设计的多层次通用性系统软件体系。可以灵活运用“领域驱动设计ddd(domain drive design)”的编程思想,结合新出现的现代软件设计工具,达到这些目的,使项目软件设计集中到具体的“业务行为逻辑实现”和“前端页面丰富”方面,通过软件自动架构的方式,保证系统软件设计的极大简化高效和运行的最大稳定可靠,同时最低化维护成本并最强化系统的可扩展性。 1 总体规划设计思想根据领域驱动设计的思想,结合新出现的现代软件设计工具插件,采用分层架构的做法,围绕具体的业务逻辑,面向对象进行分析与设计,可以建立如图1所示的以业务领域为中心的四层基本典型web浏览器企业应用网络软件系统框架模型。四层基本系统软件层次从上到下依次是:表现层、服务层、领域模型层和基础框架层。表现层主要通过用户界面向用户展示必要的数据信息,同时接收用户的反馈。服务层提供对“领域模型层”业务的封装,通过网络或接口向表现层暴露粗粒度的业务服务。领域模型层主要是展现业务领域的行为逻辑、业务处理状态以及实现业务的规则,同时也包含了领域对象的状态信息。该层是整个应用程序的核心部分,它可以包含的概念和内容有:实体(entities)、“值”对象(value objects)、领域服务(domain services)、仓储契约/接口(repository contracts/interfaces)等。基础结构层为应用程序的数据存取提供服务,它可以是应用程序本身的持久化机制,也可以是外部系统提供数据访问的web service等。它提供了能被其它各层访问的通用技术框架,比如异常捕获与处理、日志、认证、授权、验证、跟踪、监视、缓存等。这些操作通常会横向散布在应用程序的各个层面,面向方面编程aop(aspect oriented programming)关注的就是如何在不影响对象本身处理逻辑的基础上来实现这些横切的却又必不可少的功能点。实践中通过使用一些流行的拦截(interception)框架(如microsoft unity、castle dynamicproxy等)可以方便地实现aop。按照领域驱动设计的思想,领域模型建立在服务层中,能够更好地应对复杂与不断扩展的大型企业软件应用需求,而实际应用中更多的是繁琐并不特别复杂的业务领域行为逻辑,把“领域模型”独立一层,即保持了领域驱动设计的复杂应对与业务扩展的优势,又可以加速软件体系的运行效率。对于中小企业应用,这四个层次就足够了,对于业务领域的拓展和中大企业的应用,还可以把“领域模型层”展开为若干个层次,将基本的四层框架扩展n层框架。整个软件框架模型,能大能小,适应性更强大了。还可以在基础结构层采用依赖注入ioc(称“控制反转”)、工作单元、缓冲操作等技术,在“领域模型层”所在orm框架中使用实体框架(entity framework)、hibernate等技术,在服务层选用窗口通信基础wcf(windows communication foundation)、spring等技术,在应用层窗口展现基础wpf(windows presentation foundation)、struts ii等技术,规范编程,实现软件的大部分自动架构,提高软件的执行效率,做到即用数据库又与数据库无关。选用这种web浏览器企业应用网络系统软件模型,项目软件设计就可以集中到具体的“业务行为逻辑实现”和“前端页面丰富”上面了。 2 新软件体系科技分析2.1 框架模型的技术应用架构的新软件体系,采用的主要新技术如下:2.1.1 数据库动态生成技术和orm框架对于应用,采用新版的entity framework 4.1实体框架,进行code-first/model-first编程,实现数据库从代码生成,大大提升开发阶段数据库应对业务的变化能力;对于j2ee应用,可以采用类似的hiberate技术。同时采用orm框架,隐藏数据访问的细节,使数据库交互变得简单易行,并且完全不用考虑具体的sql语句应用,从而实现快速开发,避免因sql操作而引发的各种人为问题。2.1.2 一致的网络通信服务应用对于应用,服务层采用wcf,实现业务功能在网络传输的能力,为多客户端应用场合提供统一的服务接口,避免了重复开发,使移动或固定简易终端、个人计算机终端等能够连网的客户端都可以访问统一的服务地址,实现系统服务的一致性;对于j2ee应用,可以采用功能强大的spring。2.1.3 面向方面编程aop应用对于应用,采用微软企业库的policyinjection模块来实现aop。对于j2ee应用,采用集成有aop的spring。aop和ioc是进行逻辑分离和降低耦合度最主要的方式。aop技术,剖解封装的对象内部,将影响多个类的公共行为封装为一个可重用模块,并将其名为“方面(aspect)”。它把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点,经常发生在核心关注点的多处,而各处都基本相似。通过aop技术,实现了诸如日志、事务管理、权限控制等横切关注点的通用逻辑,可以专注于核心关注点,将精力投入到解决企业的商业逻辑上来。同时这些封装好了的横切关注点提供的功能可以最大限度地复用于业务逻辑的各个部分,既不需开发人员作特殊的编码,也不因修改横切关注点的功能而影响具体的业务功能。2.1.4 依赖注入及其实现分层架构的设计,层与层之间是松散耦合的,上层不会具体依赖于下层,只依赖于它的一个接口。这样,上层不能直接实例化下层中的类,而只持有接口;接口所指变量最终究竟是哪个类,则由依赖注入机制决定。对于应用,采用微软的unity2.0实现依赖注入,它包括控制反转ioc、di(dependence injection)和拦截技术。对于j2ee应用,可以采用含有ioc等功能的spring。2.1.5 前端页面的丰富绚丽为使前端网页界面丰富绚丽,可以采用通用的js(java script)、jquery、ajax、div(division) + css(cascading style sheet)、as(actionscript)-flash等技术实现导航、布局、感觉、视觉、动画、立体及其人机操作的简便和快捷。对于应用,还可以采用功能强大的ria(rich internet applications)-wpf或silverlight;对于j2ee应用,还可以采用功能强大的struts ii。2.2 可能的技术应用与替代数据库访问部分,采用了orm框架有更多的选择:如应用的nhibernate、simple.data等,j2ee应用的ibatis等;中小型企业软件的开发,应用也可以使用传统的,j2ee应也可以使用传统的jdbc(java data base connectivity)。网络访问部分,应用,除了采用较多的规范wcf技术,还可以根据系统的规模采用web service等其它替代方案;j2ee应用也可以使用传统的url(uniform resoure locator)定位、socket套接。可重用模块部分,如日志、异常及验证等,应用,除了采用“微软企业库”提供的一致功能,也可以为每一模块采用一些技术框架,如log4net日志模块等,甚至自己开发。ioc/aop部分也有较多替代方案,应用,除了微软企业库unity和policyinjection,也可以使用castle windsor、、autofac等技术。j2ee应用的选项就更多了。新软件体系架构,还有很强的预留和伸缩空间,可以轻易更换或加入将来出现的众多的简便自动工具软件,实现自身的丰富完善和功能扩展。 3 新软件体系优势分析新软件体系架构,降低了系统开发的复杂度,在设计、开发、测试、部署及维护等各个环节为应用系统带来了高可用性、高延展性等正面效应,其巨大优势概括如下:1)提高了系统的可测试性:多层架构,层与层之间是低耦合的,增加了各层的独立性,也提高了可测试性,这样开发出来的系统更加健壮。2)简单化了解决方案的维护和管理:层内高内聚、层间低耦合的结构,使得系统实现与分层组织方式变得非常灵活方便,维护和管理的直接、高效,显而易见。3)增加了系统的可移植性:企业软件开发中,许多模块都是可通用的,如日志、异常、缓存、验证模块等。通过分层,很容易分离出通用模块,便于迅速应用到其它的项目,展现了模板化的组织架构。4)数据库由编码自动生成:软件框架采用最新的数据库自动操作技术,并融入orm机制,实现了从代码生成数据库的强大功能,即使开发测试阶段的数据库也可以很容易地应对业务的变化,大大提高了开发效率。5)能够对多种类型客户端提供一致功能服务:具体业务应用领域中有多种终端,如手持移动操控仪、立/挂式操控台以及个人计算机。软件架构设计中通过网络边界分离服务层和表现层,就可以轻易的使这些不同类型终端,获取统一的系统功能服务。6)增强系统的可伸缩性:借助于分层的优势以及架构中各部分设计的高内聚性,各层自成模块体系,互相独立;增删各个独立的模块,不会影响到其它模块或层的功能,系统的可伸缩性强大。7)实现了编码自动化,避免人为因素影响:软件框架采用了众多的网络编程新技术,实现了数据库访问的封装,日志、异常捕获以及aop拦截等常用功能,减少了重复模块编码量,同时也避免了因人为因素导致的性能问题。可以看到,这种软件体系框架也存在不足,它需要非常熟悉业务领域。熟悉了具体的业务领域,才能正确完整的实现系统的行为逻辑,否则,容易偏离软件架构的核心-领域模型,导致项目重构甚至失败。这种软件架构是为应对复杂性而提出的,简单项目采用传统的易于实现的b/s三层框架就可以了,没有必要采用这种灵活的领域驱动设计的开发思想。 4 新软件体系编程实现编程实现这种软件体系框架,即可以采用j2ee规范的ec lipse+strutsii+spring+hiberate/ibatis的常用开发环境以java语言完成,也可以选用架构的visualstudio + entityframework / nhiberate的常用开发环境以c#语言完成。这里就后面一种常规开发,以图书馆的图书管理、读者借书/还书为业务背景,举例说明其具体应用。4.1 开发环境的建立与配置需要的最少软件开发工具有:.net4.0、visualstudio2010sp1、 entity framework4.1、unity 2.0/microsoftenterpriselibrary5.0、sqlserver2008、 mvc3。visualstudio也可以是低版本,visualstudio2008以上版本集成有 entity framework。数据库也可以是oracle、mysql等。其它是插件软件工具。安装visualstudio及其它插件工具和数据库,对visualstudio、插件工具、数据库做关联配置。4.2 软件框架体系的实例化打开visualstudio集成开发环境,创建新项目libsys,在其解决方案中建立以下子项: libsys.design项目的一些设计图稿,包括图1所示的基本架构结构。 rastructure主要是处理数据访问和交叉剪切(cross-cutting)的基础结构层组件。前者主要包含仓储与工作单元的具体实现;后者主要包含ioc容器等。 libsys.domain包括了项目的领域模型与业务逻辑,是系统的核心所在。 libsys.repository是仓储的具体实现项目,它引用libsys.domain项目。本项目包含了仓储实现,同时也一并实现了repository transaction context对象。 libsys.service用于表现层交互。交互采用dto(data transferring object)。dto与entity/aggregateroot(实体/聚合根)并非一一对应。虽然项目,看上去是一个entity/aggregateroot对应一个data object,但深入分析可以发现,这些data objects中包含的数据,与对应的entity/ aggregateroot中包含的对象状态是有出入的。这是由应用程序的需求决定的。 web应用程序,以asp. net mvc框架为基础,提供用户界面交互接口。这里以仓储和应用服务层的实现为例,具体说明框架体系的实例化过程。1)仓储的实现仓储保存领域模型的实体对象。业务处理需要把正在参与处理过程的对象保存到仓储中,或者从仓储中读取需要的实体对象,或将对象直接从仓储中删除。依据ddd理论,对reader和book分别设计对应的仓储readerrepository和bookrepository。而首先需要设计的是仓储基类repositorybase,它继承于接口irepository类,主要任务是封装entity framework中的database context,以统一的方式获取;另外还实现了几个抽象方法,如图2所示,这样方便了子类的实现,减少了开发的重复代码编写。2)应用服务层的实现应用服务层采用wcf实现。示例系统由libsys.service项为整个系统提供该服务。libsys.service项位于领域模型层上面、用户界面层下面,用于用户界面与领域的交互。它不负责处理任何业务逻辑,是从更高的层面,为业务逻辑的正确执行提供适当的运行环境,同时起到任务协调的作用,如事务处理和基础结构层服务调用。wcf service中“还书”操作的具体实现如下:public void return(string readername, intbookid) readerreader = readerrepository.find(specification.eval(r = r. name.equals(readerusername);book book = bookrepository.getbykey(bookid);reader.return(book);4.3 业务行为逻辑的简易实现图书管理的业务逻辑简化如下:普通用户可以添加图书并查看图书的详细信息;注册用户也就是读者,可以借书、还书、查看借过的图书列表和借书信息。4.3.1 实体与聚合根首先分析实体,不难看出,读者和图书是实体;每个读者都将有自己的借书信息(如何时借的哪本书,是否已经归还,或者是否已经过期),与之对应每本书也可以有被借历史(如,特定书何时借给哪个读者),因此借书信息也是实体。再来分析聚合。借书信息是与读者和图书关联的,没有读者,借书信息没有存在的意义,同样,没有图书,借书信息也同样不存在。每个读者可以没有任何借书信息(或借书记录),也可以有多条借书信息;每本书同样可以没有任何被借信息(或被借记录),也可以有多条被借记录。因此存在两个聚合:读者-借书信息聚合(1.0.*)以及图书-借书信息聚合(1.0.*)。读者和图书分别为聚合根,借书信息为实体。于是可以得出结论:读者:reader,聚合根;图书:book,聚合根;借书信息:registration,实体。从而可以确定需要针对读者(reader)和图书(book)实现的仓储以及相应的规约。4.3.2 基于entity framework建立领域模型目前entity framework支持三种建模方式:model first、database first以及code first。对于领域驱动设计,宜采用code first。创建entities文件夹,编写实体代码如下:public class reader /*代码省略 */ public class book / book聚合根 /*代码省略 */ public class registration /registration实体 /* 代码省略 */ 创建mappings文件夹,编写o-r映射规则。读者实体映射代码如下:public class readermap : entitytypeconfiguration publicreadermap() haskey(r =r.id); / 主键/ propertiesproperty(f = f.id).hasdatabasegeneratedoption(databasegeneratedopti on.identity);/ 代码省略totable(“reader”); / 表与字段映射形成的最终关系模型如图3。4.3.3 添加业务逻辑根据ddd,实体处理业务逻辑,应该尽量将业务体现在实体上;如果某些业务牵涉到多个实体,无法将其归结到某个实体,则引入领域服务(domain service)。本案例业务不复杂,不涉及领域服务,业务逻辑都是在实体上处理的。以“读者(reader)为例,它有借书和还书的行为,其行为实现如下:public class reader public void borrow(book book) / 借出行为 if (book.lent)throw new invalidoperationexception(“the book has been lent.”);registration reg = new registration();reg.registrationstatus = registrationstatus.normal; reg.book = book;reg.date = datetime.now;reg.duedate = reg.date.adddays(90); reg.returndate = datetime.maxvalue; book.registrations.add(reg); book.lent = true;this.registrations.add(reg);public void return(book book) / 归还行为 if (!book.lent)throw new invalidoperationexception(“the book has not been lent.”);var q = from r in this.registrations wherer.book.id.equals(book.id) &r.registrationstatus = registrationstatus.normal select r;if (q.count() 0) varreg = q.first(); if (reg.expired)/ todo: 读者需期满付费reg.returndate = datetime.now;reg.registrationstatus = registrationstatus.returned;book.lent = false;elsethrow new invalidoperationexception(string.format(“reader 0 didntborrow this book.”,);4.4 应用软件系统的自动构造建立起了软件框架体系并实现了业务行为逻辑,就可以自动构造应用软件系统了。这得益于ddd思想与orm、ioc、di、aop、unitofwork观念及其相应插件等软件工具的采用。自动构造应用软件系统最大的体现是从代码生成数据库,即实现领域模型与数据库关系模型的自动创建,步骤如下:1)在基础结构层(rastructure)添加继承自dbcontext的类libcontext,关键代码如下:public class libcontext: dbcontext privatereadonly static string connection_string =“name=libsys”;publicdbsetreader s get; set; publicdbsetregistrations get; set; publicdbsetbooks get; set; public libcontext () : base(connection_string) / 传入数据库连接字符串 /*代码省略 */ protected override void onmodelcreating(dbmodelbuildermodelbuilder) base.onmodelcreating(modelbuilder); modelbuilder.conventions.remove();/移除复数表名契约modelbuilder.conventions.remove();modelbuilder.configurations.add(new readermap() /添加映射配置文件.add(new registrationmap().add(new bookmap();2)建立数据库初始化类,代码如下:public class libinitializer: dropcreatedatabaseifmodelchanges protected override void seed(schoolcontext context) base.seed(context);/ 代码省略3)在libsys.web项目的global.asax下的application_ start()中添加如下代码来实现系统运行时自动数据库创建并初始化:database.setinitializer(newlibraryi nitializer();通过以上配置,系统在第一次运行时会根据映射配置文件的关系模型,自动创建数据库表及其主键、外键等约束。以后进行了修改,也会对数据库表自动进行调整和更新。4.5 增加网页界面的丰富渲染这里采用 mvc框架实现了基于浏览器的用户界面。用户界面层通过wcf services与系统交互。不同于传统的软件开发,不将domain model带到用户界面层,使其中的实体作用于mvc中的m(presentation model)。只将mvc中的m用于界面数据绑定。 mvc 3使用unity.mvc3轻松实现ioc。ioc框架unity的引入实现了面向接口编程。首先安装nuget,通过nuget在线搜索unity.mvc3并安装,该项目自动添加了bootstrapper.cs文件,在该文件中定义unitycontainer,最后在global.asax文件中初始化bootstrapper即可实现ioc。bootstrapper文件中关键代码代码:public static void initialise()var container = buildunitycontainer();dependencyresolver.setresolver(new unitydependencyresol ver(container);private static iunitycontainerbuildunitycontainer() var container = new unitycontainer().registertype(new hierarchicallifetimemanager().registertype().registertype()/ 代码省略.registertype, reader repository();container.registercontrollers();return container;global.asax文件关键代码只有一句:protected void application_start() / 代码省略bootstrapper.initialise();从上述架构,可以看出,用户界面可以不局限于web应用程序,还可以是winform应用程序,或者pda,手机应用程序等,从而实现了界面与领域核心功能开发的分离。实现了基本的用户网页界面,就可以在此基础上,采用通用的js、jquery、ajax、div+css、as-flash等技术实现导航、布局、感觉、视觉、动画、立体及其人机操作的简便和快捷了,从而使前端网页界面丰富绚丽。限于篇幅,这里不再详细举例。 5 结束语简易实用型web浏览企业应用网络系统软件框架模型,层次结构清晰,切合实际需要,软件设计规范,新技术科技含量与代码自动架构程度高,直接无关数据库,可以把网络编程项目软件设计有力地集中到具体的“业务行为逻辑实现”和“前端页面丰富”上,能够随着实践应用和编程技术的发展不断丰富完善,是一条高效、简便、实用、易行的捷径。参考文献1 (美)eric evans著.陈大峰等译.领域驱动设计-软件核心复杂性应对之道m .北京:清华大学出版社,2006.3 written by eric

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论