整理MVC的多层架构实例.docx
《整理MVC的多层架构实例.docx》由会员分享,可在线阅读,更多相关《整理MVC的多层架构实例.docx(15页珍藏版)》请在冰豆网上搜索。
整理MVC的多层架构实例
MVC的多层架构实例
多层架构是什么?
多层架构是开发人员在开发过程当中面对复杂且易变的需求采取的一种以隔离控制为主的应对策略,关于多层架构的标准,我认为有一句话是比较有代表性的“每一层都可以单独部署”,最传统,最简单的就是从三层开始的:
将整个项目自下而上的分为:
数据持久(数据访问)层,逻辑(业务)层,UI(展现)层。
数据访问层:
负责将数据持久化响应的数据存储设备上,如DataBase,Txt,Excel等。
业务逻辑层:
负责处理为满足软件需求而订制的一系列的逻辑与业务,如用户在前端下订单之后,整个业务流可能涉及到,获取用户信息,获取商品信息,获取购物车信息,验证商品可购买数量是否满足本次购买,针对用户身份产生不同的优惠策略,同时会验证Cookie,Session等端产生数据的有效性,最终才会产生订单,而订单产生之后会涉及到仓储物流等一系列的Erp系统业务,所有的这一套都属于“下订单”这一需求的业务逻辑。
展示层:
负责与用户交互的界面,良好的用户体验多是使用在这里。
学习过Petshop的话,对于三层都不会陌生:
但是随着业务的复杂每一层都会有自己的进化,最终有了无数附加在三层之上的框架与开发思想。
MVC与MVP:
首先我一直认为这两种事属于展现层的,“展现层MCV”,“展现层MVP”。
然后我们站在展现层的角度思考一下“Mvc”与“MVP”。
Mvc:
分为model,Controller,View,相信大家对于他已经很熟悉了,在此不再累述。
MVP:
MVP有Model-Presenter-View三个层次
业务逻辑:
从描述上可以看的很清楚,整个自上而下的结构,最复杂,最可能失控的就是业务逻辑层,因为其中包含着许多的不可控因素,每个行业领域的需求都有可能包含自身的领域知识。
于是在之后的多层架构发展构成当中,更多的变化与智慧是体现在这里。
领域驱动:
限于本人才学不能在这里分享太多,以防误导大家,想了解更多可参考园子里的其他大牛,其实没有3,5年相关经验是很难理解的,个人感觉如果你不理解的话也不会对你有什么影响,因为领域驱动是建立在良好的面相对象分析,边界划分基础之上的,在学习的过程当中已经能帮助你去学习到足够多的知识了,最终到不到山巅其实已经无所谓了。
简单的说,这个思想最重要的是以业务领域为核心进行发散,期望在变更程序的其他部分,不会影响到领域模型,也就是那句话为了“复杂的系统应用程序中业务规则行为方式(就是“领域逻辑”)是会经常变化的,我们要去拥抱这种变化”。
结构图:
CQRS:
是指命令查询职责的分离,是一个小的模式形态,该模式的关键在于:
“一个方法要么是用来改变某个对象的状态的,要么就是返回一个结果,这两者不会同时并存”。
将整个系统分拆为两个部分:
Commands(命令) -改变某一个对象或整个系统的状态(有时也叫做modifiers或者mutators)。
Queries(查询) -返回值并且不会改变对象的状态。
架构图:
不管DDD也好,CQRS也好,其实这两种都不会100%适合所有的项目架构的,这就需要架构师结合项目本身特点及需求有所选择,但是其中的思想我们可以运用在项目的任何地方。
基于消息的分布式:
其实不管使用怎样的架构,加入怎样的架构思想(soa),核心或者是开发者最想达到的就是层次,系统之间的解耦,复杂的东西没人会喜欢。
随着系统的发展,我们的程序会涉及到多台服务器,多种终端,同时为了解耦我们引入了基于消息的分布式架构。
首先,所以系统的通信基于消息,逻辑联系不会涉及到具体的业务实现,同时消息的传递更加的廉价可适配多种终端。
其次,由于所用逻辑只是基于消息实现,迭代的成本也会相对于其他耦合项目更快更方便。
展示层:
随之Web2.0的到来单一页面展示的信息也更加的丰富,Ajax,js的流行也使得Ui端的操作也愈加变重,于是大家有期望以一种工程的思想去拥抱这种变化,于是MVVM,js的Mvc框架陆续出现。
同时随着移动互联网的兴起,不同终端对于系统的对接也非常重要,于是我们考虑在Ui与Logic之间引入Application或Service层应对不同终端配置。
如:
我们在ClientPresenterLayer上加入WCF适配多种终端提交的订单,都是建立在消息基础之上的,楼主之前做电商系统是针对于来自淘宝,天猫,亚马逊订单时,为避免出现对库中订单并发,产生“超买”情况,采用了在上层Ui与logic层之间引入了OrderChannel层,将不同终端订单进行排队的解决方案。
以上是架设一个能够适配不同需求的架构过程,但是真正的真理是需要大家在实践中,错误中汲取的。
下面是楼主简单的小分层架构,不妥,不足之处希望大家指导斧正。
层次划分:
为了实现单独部署,层次解耦所以层次之间是基于接口实现的。
DataAccess层引入仓储实现统一DTO操作,实现基于Ef:
IRepository:
publicinterfaceIRepositorywhereT:
class
{
IEnumerableFindAll(Expression>exp);
voidAdd(Tentity);
voidDelete(Tentity);
voidSubmit();
}
引入RepositoryBase实现接口定义:
publicclassRepositoryBase:
IRepositorywhereT:
class
{
DbContextcontext;
publicRepositoryBase(DbContext_context)
{
context=_context;
}
publicRepositoryBase(){
this.context=newTestDBEntities();
}
publicIEnumerableFindAll(Expression>exp)
{
returncontext.Set().Where(exp);
}
publicvoidAdd(Tentity)
{
context.Set().Add(entity);
}
publicvoidDelete(Tentity)
{
context.Set().Remove(entity);
}
publicvoidSubmit()
{
context.SaveChanges();
}
}
这对于单一的某个仓储我们单独引入其自身的仓储接口:
publicinterfaceIUserRepository:
IRepository
{
IListGetAllById(intid);
boolCheckUserExist(UserTestu);
}
特定仓储实现:
publicclassUserRepository:
RepositoryBase,IUserRepository
{
publicIListGetAllById(intid)
{
using(TestDBEntitiesentities=newTestDBEntities())
{
varusers=fromuinentities.UserTests
whereu.ID==id
selectu;
returnusers.ToList();
}
}
publicboolCheckUserExist(UserTestu)
{
using(TestDBEntitiesentities=newTestDBEntities())
{
Listusers=entities.UserTests.Where(ut=>ut.UserName==u.UserName&&ut.UserPassword==u.UserPassword).ToList();
returnusers.Count==0?
false:
true;
}
}
}
在Service层同样建立相关接口适配特种服务:
IUserCore:
publicinterfaceIUserCore
{
CommandStatueEnumUserLogin(IModelmodel);
CommandStatueEnumUserRegister(IModelmodel);
ListGetUsers(Expression>expr);
}
UserCore:
publicclassUserCore:
IUserCore
{
#regionStructure
IUserRepository_repository;
publicUserCore(IUserRepositoryrepository){
this._repository=repository;
}
#endregion
publicCommandStatueEnumUserLogin(IModelmodel)
{
try
{
UserLoginu=modelasUserLogin;
UserTestuTest=newUserTest();
uTest.UserName=u.UserName;
uTest.UserPassword=u.Password;
if(_repository.CheckUserExist(uTest))
{
returnCommandStatueEnum.Succeed;
}
else
{
returnCommandStatueEnum.Fail;
}
}
catch(Exceptionex){
throwex;
}
}
publicCommandStatueEnumUserRegister(IModelmodel)
{
try
{
UserLoginu=modelasUserLogin;
UserTestuTest=newUserTest(){UserName=u.UserName,UserPassword=u.Password};
_repository.Add(uTest);
_repository.Submit();
returnCommandStatueEnum.Succeed;
}
catch(Exceptionex)
{
throwex;
}
}
publicListGetUsers(System.Linq.Expressions.Expression>expr=null)
{
return_repository.FindAll(expr).ToList();
}
}
Controller:
publicclassAccountController:
Controller
{
IUserCoreuserCore;
publicAccountController(IUserCore_userCore)
{
this.userCore=_userCore;
}
//
//GET:
/Account/
#regionview
publicActionResultHome()
{
ViewBag.Users=userCore.GetUsers(u=>u.IsUse==1);
returnView();
}
publicActionResultLogin()
{
returnView();
}
publicActionResultRegister()
{
returnView();
}
#endregion
#regionPost
[HttpPost]
publicActionResultLogin(UserLoginaccount)
{
try
{
if(userCore.UserLogin(account)==CommandStatueEnum.Succeed)
{
returnRedirectToAction("Home");
}
else
{
returnView();
}
}
catch(Exceptionex)
{
ExceptionModel.IsExcept=true;
ExceptionModel.Exception=ex.ToString();
ExceptionModel.CreateTime=DateTime.Now;
returnView();
}
}
[HttpPost]
publicActionResultRegister(UserLoginaccount)
{
try
{
if(userCore.UserRegister(account)==CommandStatueEnum.Succeed)
{
returnRedirectToAction("Home");
}
else
{
returnView();
}
}
catch(Exceptionex)
{
ExceptionModel.IsExcept=true;
ExceptionModel.Exception=ex.ToString();
ExceptionModel.CreateTime=DateTime.Now;
returnView();
}
}
#endregion
}
对于接口之间我们通过引入IOC工具解耦:
publicclassMvcApplication:
System.Web.HttpApplication
{
protectedvoidApplication_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
2.环境影响报告表的内容FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
8.编制安全预评价报告RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterAuth();
①主体是人类;#regionIOC
varbuilder=newContainerBuilder();
SetupResolveRules(builder);
builder.RegisterControllers(Assembly.GetExecutingAssembly());
市场价格在有些情况下(如对市场物品)可以近似地衡量物品的价值,但不能准确度量一个物品的价值。
三者的关系为:
varcontainer=builder.Build();
『正确答案』BDependencyResolver.SetResolver(newAutofacDependencyResolver(container));
#endregion
}
privatevoidSetupResolveRules(ContainerBuilderbuilder)
{
(3)介绍评价对象的选址、总图布置、水文情况、地质条件、工业园区规划、生产规模、工艺流程、功能分布、主要设施、设备、装置、主要原材料、产品(中间产品)、经济技术指标、公用工程及辅助设施、人流、物流等概况。
//ComponentsarewiredtoservicesusingtheAs()methodsonContainerBuilder
1.规划环境影响评价的技术依据builder.RegisterType().As();
(5)阐述划分评价单元的原则、分析过程等。
builder.RegisterType().As();
}
}
1)直接使用价值。
直接使用价值(DUV)是由环境资源对目前的生产或消费的直接贡献来决定的。
其他基础类库我们会结合具体需求进行定制,上面例子多有不妥之处只起演示之用。