Web应用架构分析之查询传递

发布于 2022-09-01 22:03:01 字数 5943 浏览 15 评论 0

Web应用架构分析之查询传递

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

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

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

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

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

  1. List<SiteMsg> GetMsgList(SiteMsgQuery msgQuery);

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

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

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

下面看一下代码示例:

领域模型的定义:

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

复制代码服务实现类(也是WCF的服务实现):

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

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

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

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

再来看看ajax客户端代码:

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

复制代码js传递的也是一个对像。

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文