阅读目录:

  • 1.背景介绍
  • 2.对业务功能点进行逻辑划分(如:A、B、C分别三个业务点)
    • 2.1.配置映射关系,对业务点配置查询契约(构造VS插件方便生成查询契约)
    • 2.2.将配置好的映射策略文件放在调用端,与服务不耦合
  • 3.Dynamic、Dom动态构造服务端对象(Dynamic、DOM实现动态DOM)

1.背景介绍

现在越来越多的公司都在尝试SOA架构的实践,本人最近也在尝试学习这方面的技术,但是在实践过程中遇到一个问题,我想这个问题也是我们普遍实践者都应该会遇到的问题,问题描述如下:

我们有一个SOA商品(Item)查询接口,这个接口很通用,主要用来支撑日常很多其他系统的大量关于Item的查询,尤其是在高峰期间该服务的压力是很大的;我们站在SOA的角度看这个接口,这个通用的接口解决了众多的查询业务,确实不错,但是我们切换一下角度,站在每一个调用接口的访问端看似乎并不是很满意或者说牺牲了部分性能上的代价,因为我们无法干净利落的只获取当前这个业务点需要的数据项;这个Item服务接口所返回的数据项必须同时满足所有调用它的业务点,哪怕这次调用我只需要用到Item的三分之一的数据字段都不行,每次都会把不需要的字段都查询出来,不管是返回的性能、查询的性能,其实都是可以通过调整设计来避免的;

(查看大图)

以往我们的思路都是集中在服务端,常规做法都是提供了一个能够容纳所有查询客户端需求的数据实体,客户端可选择的余地很有限,无法只获取自己所需要的几个数据项,甚至各个业务点在不同的情况下都有可能需要两到三个数据返回实体;总而言之,面向数据查询的服务接口如果要向着SOA方向发展那就必须包含SOA设计上的相关原则,如这里的面向查询为主的服务设计其实就是缺少SOA原则中的”服务应具有策略性“一原则;

为什么以往一直没有暴露出这个问题呢,是因为以往都是在本地直接调用“查询引擎”,如:SQLSERVER,在“查询引擎”的最后一层就是应用程序,而应用程序中可以编写很多彼此类似的查询方法,每个方法可能只有一两个字段的差异性,或者通过“企业应用架构模式—查询对象模式”来将不同的方法合在一起通过一个可以调整查询字段的对象来配置本次需要的查询字段;由于现在我们已将查询服务化,就不太可能再去为了所有客户端在去适应性的去扩充类似没有太大价值的接口,但是客户端又需要将自己所需要的查询字段让服务知道,所以这里的解决方案可以称为面向SOA的”企业应用架构模式—查询对象模式“

本文将通过运用”关注点分离“通用设计思想来对查询服务在服务端的强耦合进行分解,将强耦合从服务端迁移出来通过策略性的配置将关注点放入各自的客户端,从而有效的解决服务不再臃肿的问题,如果理解上有困难可以尝试使用面向SOA的”企业应用架构模式—查询对象模式“概念来理解;

2.对业务功能点进行逻辑划分(如:A、B、C分别三个业务点)

首先我们需要将相对于服务来说的客户端中所有业务点进行逻辑划分,将原本一个高耦合的庞大数据实体分解成各自所需要的一个精简的数据实体;业务点的划分目地在于可以将数据实体能与之对应起来,这个数据实体是针对于查询服务而言的,对于客户端来说没有任何的依赖和约束,也就是说本次业务点发起的查询将把这个数据实体转化成一组查询策略中的设置带到服务端中,然后服务端在根据这组策略信息进行组合最终的查询语句;

注:这里的数据实体并不是服务端定义的DTO,也不是客户端定义的DTO,而是一个只跟本次业务查询相关的数据查询实体,该实体不是一个定义的类,而是一个策略,类似:

A.Business{Query field{ItemNumber、Description、PromationPrice}}

这样一组配置信息;客户端用来反序列化的DTO可以是一个庞大的共用的数据实体,也可以是跟业务点绑定的精简实体,对于查询没有任何影响,我们要解决的是“只查询我所需要的数据项,只返回我所需要的数据项”,而跟你在服务端、客户端定义的用来辅助序列化的实体没有任何关系;

 (查看大图)

将查询的字段、返回的字段通过查询策略带入到服务端,我们就能够知道本次业务点查询的是需要什么样的字段,然后就可以在构造查询引擎参数时将返回的字段直接加上或者过滤不需要的;

2.1.配置映射关系,对业务点配置查询契约(构造VS插件方便生成查询契约)

将系统中需要调用服务接口的所有功能点进行业务点逻辑划分设计后,每个业务点都需要在自己发起调用服务的时候能够带上在之前某个时间点设计好的查询契约,这个用来生成查询契约的工具最好是集成在VisualStudio中的自定义插件,在设计时用来动态构造一个对应的契约配置文件,如果可以的话可以采用动态代码方案,将配置文件的静态文件通过动态生成代码的方式嵌入到生成的代码中去,减少不需要的配置文件,也减少查询框架的性能开销,一次生成后就可以直接使用;

2.2.将配置好的映射策略文件放在调用端,与服务不耦合

本篇文章的解决方案最大的突破点就是将关注点从服务端转移到所有客户端上,将原本都集中在服务上的所有客户端的需求分离出去,每个需要调用服务的客户端维护好自己的一份查询契约,在每次调用服务的时候带上那份契约;如果处于性能考虑每次带上契约会增加开销,那么可以在第一次身份验证的时候在服务上确认,以后调用都忽略;

这样一来服务将精简很多,通过同样的设计方法可以用来设计很多类似的服务接口,将关注点从服务上转移到客户端上,会是一个很好的设计思路;

3.Dynamic、Dom动态构造服务端对象(Dynamic、DOM实现动态DOM)

借助C#新特性Dynamic,我们可以在.NET平台上进行动态编程,这里可以解决我们预先定义服务端实体的好处;以往我们需要在服务上定义一个至少能容纳所有客户端查询契约中的所有数据项的实体,但是当我们运用动态编程时,我们无需事先定义一个类,而可以在运行时动态获取对象属性,当然这得益于.NETDLR的实现;再适当的结合DOM思想,我们就可以实现一个动态DOM效果,对于DOM的某个Element的访问也无需定义映射实体然后在通过属性获取,中间既增加了序列化的开销还增加了开发工作量;

 using System;
using System.Collections.Generic; namespace ConsoleApplication1.DynamicDom
{
public class ItemEntity : System.Dynamic.DynamicObject
{
/// <summary>
/// 可以使用LINQ TO XML或者将XML数据构造在一个指定的容器中,用来判断是否存在
/// </summary>
private static Dictionary<string, object> itemPropery = new Dictionary<string, object>();
static ItemEntity()
{
itemPropery.Add("ItemNumber", );
itemPropery.Add("PromationPrice", );
}
public override bool TryGetMember(System.Dynamic.GetMemberBinder binder, out object result)
{
if (itemPropery.ContainsKey(binder.Name))
{
result = itemPropery[binder.Name];
return true;
}
result = null;
return false;
}
}
}
 dynamic itemEntity = new DynamicDom.ItemEntity();
Console.WriteLine("ItemNumber:" + itemEntity.ItemNumber);
Console.WriteLine("PromationPrice:" + itemEntity.PromationPrice);
Console.ReadLine();

这里只是一个简单的示例,目的是想让并不太了解Dynamic的朋友有了直观上的认识;通过使用Dynamic、Dom可以在服务端上无需定义任何的实体,根据各个客户端传过来的配置直接进行动态访问,可以借助LIQN TO XML;

全文仅仅是一个设计上的介绍,要想完全实现上面这些效果需要还是需要开发些东西的,这里只是抛砖引玉,希望对正在设计相关内容的朋友提供一个思路;

作者:王清培

出处:http://www.cnblogs.com/wangiqngpei557/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面

.NET应用架构设计—面向查询服务的参数化查询设计(分解业务点,单独配置各自的数据查询契约)的更多相关文章

  1. App架构设计经验谈:服务端接口的设计

    App与服务器的通信接口如何设计得好,需要考虑的地方挺多的,在此根据我的一些经验做一些总结分享,旨在抛砖引玉. 安全机制的设计 现在,大部分App的接口都采用RESTful架构,RESTFul最重要的 ...

  2. .NET应用架构设计—用户端的防腐层作用及设计

    阅读目录: 1.背景介绍 2.SOA架构下的显示端架构腐化 3.有效使用防腐层来隔离碎片服务导致显示端逻辑腐烂 4.剥离服务调用的技术组件让其依赖接口 5.将服务的DTO与显示端的ViewModel之 ...

  3. MVC实用架构设计(三)——EF-Code First(4):数据查询

    前言 首先对大家表示抱歉,这个系列已经将近一个月没有更新了,相信大家等本篇更新都等得快失望了.实在没办法,由于本人水平有限,写篇博客基本上要大半天的时间,最近实在是抽不出这么长段的空闲时间来写.另外也 ...

  4. 面向微服务的体系结构评审中需要问的三个问题-咖啡杂谈:Java、新闻、故事和观点

    面向微服务的体系结构如今风靡全球.这是因为更快的部署节奏和更低的成本是面向微服务的体系结构的基本承诺. 然而,对于大多数试水的公司来说,开发活动更多的是将现有的单块应用程序转换为面向微服务的体系结构, ...

  5. MongoDB源码分析——mongod数据查询操作

    源码版本为MongoDB 2.6分支 Edit mongod数据查询操作 在mongod的初始化过程中说过,服务端接收到客户端消息后调用MyMessageHandler::process函数处理消息. ...

  6. SharePoint服务器端对象模型 之 使用CAML进展数据查询

    SharePoint服务器端对象模型 之 使用CAML进行数据查询 一.概述 在SharePoint的开发应用中,查询是非常常用的一种手段,根据某些筛选.排序条件,获得某个列表或者某一些列表中相应的列 ...

  7. 关系数据标准语言SQL之数据查询

    数据查询是数据库的核心操作.SQL提供了SELECT语句进行数据查询,该语句具有灵活的使用方式和丰富的功能. 其一般格式为 select [all | distinct]<目标表达式>[, ...

  8. SQL - 数据查询

    数据查询是数据库的核心操作.SQL 提供了 select 语句进行数据查询,该语句的一般格式为: select  [ ALL | distinct ] <目标列表达式>  [ ,<目 ...

  9. SQL数据查询之——单表查询

    一.SQL数据查询的一般格式 数据查询是数据库的核心操作.SQL提供了SELECT语句进行数据查询,其一般格式为: SELECT [ALL | DISTINCT]<目标列表达式>[,< ...

随机推荐

  1. Service组件简介

    Service是一个应用程序组件,没有图形化界面,通常用来处理一些耗时较长的操作,可以用Service更新ContentProvider,发送Intent以及启动系统的通知等等.Service并不是一 ...

  2. JS几种排序算法

    一.冒泡排序 var bubble = function(arr){ ;i<;i++){ ;j<-i;j++){ ]){ temp = arr[j]; arr[j] = arr[j+]; ...

  3. 4.羽翼sqlmap学习笔记之Post登录框注入

    4.Sqlmap系列教程——post登录框注入注入点: http://xxx.xxx.com/Login.asp 注入方式一: 1.对着注入点使用burp抓包,保存txt格式文件. 2.输入命令: . ...

  4. Linux process vs thread

    Linux process vs thread Question I have a query related to the implementation of threads in Linux. L ...

  5. js修改不了input的值

    奇怪的input 今天想做一个通过点击按钮,修改input值的控件,但是点击按钮后,input值变成修改的值后又变回了原来的值,百思不得其解,代码如下 <form> <div cla ...

  6. 那些年我们用过的Python代码

    根据正则表达式选择性解压文件 from zipfile import ZipFile import re def is_match(expression, filename): pattern = r ...

  7. 解决eclipse中logcat不显示log的问题

    调试程序需要打印一些消息出来,logcat不好用的话就很麻烦了.这个问题折腾了好久,为啥就是不出来呢? 上网找了很多解决办法: 重启eclipse 重启adb 重启logcat ......等等好多 ...

  8. 背水一战 Windows 10 (25) - MVVM: 通过 x:Bind 实现 MVVM(不用 Command)

    [源码下载] 背水一战 Windows 10 (25) - MVVM: 通过 x:Bind 实现 MVVM(不用 Command) 作者:webabcd 介绍背水一战 Windows 10 之 MVV ...

  9. mybatis 中的where标签

    mybatis中的where标签可以去除 开头的 and 或者 or 但是放在后面的不行 失败的: <select id="countNotesByParam" parame ...

  10. 华硕笔记本U盘启动系统/WinPE报错。Windows failed to start. A Recent hardware or software change might be the cause.

    最近在整一台华硕笔记本,大概有5年寿命了吧,质量还行,由于系统出了问题,打算用自制U盘WinPE进去修复一下.按照个人经验,在主板设置里启用了USB启动选项,并且设置USB启动顺序为第一个,可是进系统 ...