您好,登录后才能下订单哦!
阅读目录:
1.开篇介绍
2.Model与View的使用关系(数据上下文DataContext与View呈现)
3.Metadata元数据驱动设计(如何使用中间层元数据来驱动最终的行为)
4.ASP.NETMVC ModelMetadata(ModelMetadata元数据如何支撑Model与View之间的组合关系)
这篇文章让我们一起来学习一下有关Asp.netMvc中的Mode元数据的相关设计和围绕元数据的一些其他对象模型,他们是如何通过彼此协调来支撑起一个灵活的界面编程接口;
其实提到元数据(Metadata)大家在研究某个应用框架的时候都曾经或多或少的见到过,可能并没有引起你的注意;其实在很多应用框架中我们都能看见Matedata的影子,它是一个很不错的框架设计模式,俗称:“元数据驱动设计”,它跟目前很多设计思想很接近,如:元编程、契约式设计,这些模式目的都是为了能很好的控制耦合,产生极大的扩展灵活性;元编程让我们能基于最终的用户选择动态的产生运行软件的代码,而契约式设计能让我们将控制权设立在很远的地方,从而很大粒度的控制扩展性,根据契约设立规则,控制端再在运行时动态的生成出最终需要的规则;
通过对这些模式深入理解,基本上可以提炼出两条设计上的黄金规则:1.将变化点从编译时迁移到运行时;2.将变化点从硬编码迁移到配置化;
这里只是一个简单的介绍,由于每一个主题细化下来都会很大,都会包含该方向中的很多领域概念、术语和重要的设计思想,所以这里只是一个简单的介绍,本篇文章会重点介绍一下“元数据驱动设计”编程思想和它到底好在哪里,然后在ASP.NETMVC中它起到怎样的作用,它又是如何架起通往Model与View的高速桥梁的,让Model与View可以到做1对N的搭配关系,在大型站点中ViewModel一般只有固定的几种,但是View可能会有成千种,如何做到这种高度适配,这就是自定义模板的功能,当然一切都建立在ModelMetadata基础上;
在MVC的定义中,Model准确点讲是ViewModel而非DomainModel,ViewModel简称显示Model,主要是将要显示的数据融合在一个DataContext中,它来源于企业应用架构中的Query端的数据源;一般情况下这样的一个ViewModel不会经常变化,都是根据众多的业务场景抽象出来的一个比较Common的数据上下文;
在网站型的系统中,尤其电子商务平台,界面的变化很常见,几乎每天都有可能改变界面上的某个显示方式,同样一组数据可能在UI上的展现方式各不相同;这里就会形成一个Model与多个View的组合关系,同样一个Promotion(促销)数据上下文,需要在很多注销类别不同的UI上展现,而不同的UI组成都是由不同的View的负责生成;
图1:
可以总结出一个数据上下文实体在大部分的情况下都可能会被很多View使用,所以ASP.NETMVC 需要具备很强的自定义性,一个Model可以随意呈现出多中Ui而不会因此将ViewModel搞的一团乱;
注意:一个ViewModel数据实体可能很大,如果为了应付不同的显示场景最好将ViewModel进行切割,拉出继承体系,而不是将所有的ViewModel耦合在一个超大的ViewModel中,这样会让每一次的查询都会涉及到一些你本次不相关的属性;
元数据驱动设计模式是众多经典框架设计模式之一,它与契约式设计有点一脉相承的感觉;其实框架设计的本质是如何灵活的运用一些框架设计模式,不同的语言、平台对模式的运用各不相同,但是模式的中心思想一直不会变,不管你如何设计都必须呈现出框架模式的本质才行;
在众多的框架设计模式中 如:契约式设计、元编程、元数据驱动设计、管道模型、远程代理模式、提供程序模型;元数据驱动设计模式是使用频率比较高的,因为其复杂度也相对较低所以比较容易上手;其实在很多现有的.NET框架中,如:WCF、ASP.NET、Remoting、Winform中都会看见Metadata的影子,但是不一定非得要在命名的时候加上Metadata,有很多的时候也会使用Description来代替;
元数据通常作为支持数据,它是描述数据的数据,是真正被解析处理的数据;既然是描述数据的数据,那么就存在它在那个方向上的描述,描述的角度是什么,描述的层面又是是什么;
我们就拿ModelMetadata来讲,在ASP.NETMVC中,Model的使用方向基本上被限定在三个操作集合中,第一:请求的数据绑定,第二:数据绑定时的验证,第三:Model的最终呈现;那么ModelMetadata要包含这三个操作集合所需要的全部数据,当然也可以通过切割成三组元数据对象模型,通过继承体系包含起来;那么ModelMetadata需要描述三个方向上的所需要的数据集合,Model本身就是一中数据,而通过使用ModelMetadata来抽象的描述第二个层面上的数据,从三个操作集合角度中包含使用的数据,也就是说三个角度,两个层面;如果你的框架需要具备多个层面,那就需要进一步细化抽象;
图2:
标准数据经过一个中间的环节转换成元数据,然后交给最终的处理程序去使用;可以很清晰的了解到元数据起到的一个核心作用,它可以很好的将处理程序与标准数据之间解耦,让中间的元数据提供更大的灵活性,通过这个中间层元数据,我们可以很轻松的做到对元数据进行配置;
我们假设没有中间层元数据,操作程序不管如何设计都会和标准数据实体有耦合,而且要保证标准数据的纯洁度,不可能总是对它使用继承、特性等重度污染性的侵入,保证完全的POCO(Plain Old Csharp Objects)对象很难,如果没有IDE的编译时支持,很难提取出可以在运行时使用的数据;这个时候我们如果需要修改标准元数据的类型或者修改操作程序的逻辑都会或多或少的对两者有影响;
如果使用元数据我们完全可以将表数据对元数据的定义部分迁移到配置文件中去,然后再在元数据提供程序中扩展读取元数据的源头,可以做到将标准数据放在任何地方甚至遥远的云平台上,对于操作程序来说,我们可以将获取元数据的接口提取成Service方式,从任何一个地方读取元数据;
这些种种方案你可能决定永远都不会用到,但是谁又能把某个框架的所有功能都用一边呢,系统需求各异,都有可能需要这些扩展点;
未完待续,敬请关注......
作者:王清培
出处:http://wangqingpei557.blog.51cto.com/
本文版权归作者和51CTO共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。