Web应用架构分析之查询传递
创始人
2024-07-20 22:21:38
0

在Web应用开发中,最常见也容易变化的一种需求是根据不同的查询条件获取数据列表。如何传递查询条件将影响程序应对需求变化的能力,一定要在架构中重点考虑。

开始时我们使用一堆参数传递查询条件,比如:

  1. List GetMsgList(int pageIndex, int pageSize, int RecipientId); 

结果,每个不同的查询都要写一个接口,产生了一堆接口;查询条件改变,接口也随之要改。写程序最痛苦的事莫过于接口的频繁变化。

后来使用查询对像,比如:

  1. List GetMsgList(SiteMsgQuery msgQuery); 

这样,查询条件改变时,只需修改SiteMsgQuery的定义,接口保持不变。采用这个方法后,写代码比之前少了很多痛苦。

但使用这个方法有个地方不爽,完成一次查询需要进行两次实例化,一次是查询对象SiteMsgQuery的实例化,一次是领域对象SiteMsgManager(负责业务逻辑)的实例化。在博客园程序架构中,查询对象的实例化是在表现层完成的,如果是ajax调用,json会自动反序列为查询对象;领域对象的实例化在服务层完成。

为了让代码写的更爽一些,我们又进行了尝试,取消查询对象SiteMsgQuery,将它的属性放到领域对象中。这样减少了一次实例化,只需一次,如果是ajax调用,可以实现服务器端“零实例化”。

下面看一下代码示例:

领域模型的定义:

  1. [DataContract]  
  2. public class SiteMsgManager  
  3. {  
  4. public SiteMsgManager()  
  5. {  
  6. }  
  7.  
  8. #region Properies  
  9.  
  10. [DataMember]  
  11. public int PageIndex { get; set; }  
  12.  
  13. [DataMember]  
  14. public int PageSize { get; set; }  
  15.  
  16. [DataMember]  
  17. public int RecipientId { get; set; }  
  18.  
  19. public List List { get; set; }  
  20.  
  21. #endregion  
  22.  
  23. public void GetList()  
  24. {  
  25.     using (SpaceObjectContext context = new SpaceObjectContext())  
  26.     {  
  27.         this.List = context.SiteMsgs  
  28.             .Where(msg => msg.RecipientSpaceUserId == this.RecipientId)  
  29.             .OrderByDescending(msg => msg.id)  
  30.             .Skip((PageIndex - 1) * PageSize)  
  31.             .Take(this.PageSize)  
  32.             .ToList();  
  33.     }             

服务实现类(也是WCF的服务实现):

  1. public class MsgService : IMsgService  
  2. {  
  3.     public List GetMsgList(SiteMsgManager siteMsgManager)  
  4.     {  
  5.         siteMsgManager.GetList();  
  6.         return siteMsgManager.List;  
  7.     }  

UI层调用代码(WCF调用,ASP.NET MVC控制器):

  1. public class MsgController : Controller  
  2. {  
  3.     //ajax调用  
  4.     [HttpPost]      
  5.     public ActionResult List(SiteMsgManager msgManager)  
  6.     {  
  7.         return View("MsgList", GetInboxMsgList(msgManager));  
  8.     }  
  9.  
  10.     public ActionResult Inbox()  
  11.     {  
  12.         SiteMsgManager msgManager = new SiteMsgManager()  
  13.         {  
  14.             PageIndex = 1,  
  15.             PageSize = 30 
  16.         };          
  17.         return View("Inbox", GetInboxMsgList(msgManager));  
  18.     }  
  19.  
  20.     private List GetInboxMsgList(SiteMsgManager msgManager)  
  21.     {  
  22.         int spaceUserId = Util.GetCurrentUser
    (System.Web.HttpContext.Current).SpaceUserID;  
  23.         msgManager.RecipientId = spaceUserId;  
  24.         MsgServiceClient client = new MsgServiceClient();  
  25.         List siteMsgList = client.GetMsgList(msgManager).ToList();  
  26.         try { client.Close(); }  
  27.         catch { client.Abort(); }  
  28.         return siteMsgList;  
  29.     }  

看看上面供ajax调用的List方法,不需要进行SiteMsgManager的实例化,系统根据ajax客户端传递过来的json参数自动反序列化生成SiteMsgManager对象。

再来看看ajax客户端代码:

  1. function GetMsgList(pageIndex, pageSize) {  
  2.     var msgManager = {}  
  3.     msgManager.PageIndex = pageIndex;  
  4.     msgManager.PageSize = pageSize;  
  5.  
  6.     $.ajaxSettings.dataType = 'plain/text';     
  7.     $.ajaxSettings.url = '/msg/list';  
  8.     $.ajaxSettings.data = '{"msgManager":' + JSON.stringify(msgManager) + '}';  
  9.     $.ajaxSettings.success = function (data) {  
  10.         $("#msg_list").html(data);  
  11.     };  
  12.     $.ajax();  

js传递的也是一个对像。

整个ajax调用的流程是这样的:js对象(msgManager)->json->MsgController(MVC控制器)->代理领域对象SiteMsgManager(WCF客户端代理类的实例)->WCF服务接口->WCF服务实现(自动通过反序列化生成领域对象SiteMsgManager,并调用GetList()方法)->领域对象完成业务逻辑操作返回数据。

采用这种方法,感觉写代码比以前更享受了。我们在实际开发中也开始使用这种架构,并根据实际使用情况进一步改进。
 

【编辑推荐】

  1. Web开发者欣喜若狂的40个UI设计工具和资源
  2. 是什么让一个Web应用程序变得如此伟大?
  3. Web打印的在线设计
  4. 2011年Web前端技术展望:jQuery移动开发新选择
  5. 代替桌面工具 10款最给力的Web开发与设计工具

相关内容

热门资讯

如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
20个非常棒的扁平设计免费资源 Apple设备的平面图标PSD免费平板UI 平板UI套件24平图标Freen平板UI套件PSD径向平...
德国电信门户网站可实时显示全球... 德国电信周三推出一个门户网站,直观地实时提供其安装在全球各地的传感器网络检测到的网络攻击状况。该网站...
为啥国人偏爱 Mybatis,... 关于 SQL 和 ORM 的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行...
《非诚勿扰》红人闫凤娇被曝厕所... 【51CTO.com 综合消息360安全专家提醒说,“闫凤娇”、“非诚勿扰”已经被黑客盯上成为了“木...
2012年第四季度互联网状况报... [[71653]]  北京时间4月25日消息,据国外媒体报道,全球知名的云平台公司Akamai Te...