咱们在平常接触到的一些软件界面,每每喜欢深刻分析其实现机理,经过学习、分析,能够提升咱们对软件架构的分析能力,从而实现更加弹性、可重用的模块。在无心间,看到一个短信模块的设计,模板里面能够包含了不少变量,从而引起我对其深刻分析的兴趣,本文主要介绍我对这些实现的一些理解,介绍一个包含动态变量的短信模板的设计分析。正则表达式
以下图所示,上面包含了短信模板的列表信息,以及对具体模板的内容设计,能够在其中插入变量的处理。微信
若是是硬编码对个别的实现应该很容易,若是咱们考虑可扩展性、重用性等因素,须要进行弹性的设计,那么就须要寻找好的思路来动态处理这些变量了。架构
如它的每一个模板的变量都是能够不一样的,如其中一个模板有以下变量能够插入到模板内容里面,变量自己用左右的括弧{}进行标识,仍是颇有规律的。函数
因为模板是针对某个企业的,企业可能根据须要进行必定的调整,模板能够恢复为最初的版本,所以咱们能够考虑设计两个部分,一个部分是基础模板,一个部分是对企业的消息模板,前者不变,后者能够根据须要修改,如无修改保存的,则采用对应的基础模板,也就是模板的模板了。学习
因为模板是包含有不一样变量的,所以咱们须要在设计的时候,动态解析这些变量。咱们若是可以把传入的对象动态获取它的属性,并给对应的变量赋值,应该就能够实现这个功能。测试
那么咱们就须要经过反射方式,动态获取对应object对象的各类属性名称和值了,这个处理操做以下所示。编码
/// <summary> /// 把object对象的属性反射获取到字典列表中 /// </summary> /// <param name="data">object对象</param> /// <returns></returns> public static Dictionary<string, string> GetProperties(object data) { Dictionary<string, string> dict = new Dictionary<string, string>(); Type type = data.GetType(); string[] propertyNames = type.GetProperties().Select(p => p.Name).ToArray(); foreach (var prop in propertyNames) { object propValue = type.GetProperty(prop).GetValue(data, null); string value = (propValue != null) ? propValue.ToString() : ""; if(!dict.ContainsKey(prop)) { dict.Add(prop, value); } } return dict; }
前面介绍了,模板的内容,是包含有左右括弧{}的变量的,所以咱们能够经过正则表达式,把它们提取出来备用,这样咱们就能够把前面反射对应属性的值赋值给模板内容,从而造成新的待发送的具体消息了。spa
var regex = @"\{(?<name>.*?)\}"; List<string> itemList = GetList(template, regex, "name");
其中GetList就是一个正则表达式获取对应正则内容的函数,函数代码以下所示。设计
/// <summary> /// 多个匹配内容 /// </summary> /// <param name="sInput">输入内容</param> /// <param name="sRegex">表达式字符串</param> /// <param name="sGroupName">分组名, ""表明不分组</param> public static List<string> GetList(string sInput, string sRegex, string sGroupName) { List<string> list = new List<string>(); Regex re = new Regex(sRegex, RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline); MatchCollection mcs = re.Matches(sInput); foreach (Match mc in mcs) { if (sGroupName != "") { list.Add(mc.Groups[sGroupName].Value); } else { list.Add(mc.Value); } } return list; }
最后咱们能够把内容对应上,给模板替换为最新的属性值了。3d
private void button1_Click(object sender, EventArgs e) { //模板文本 var template = "姓名 = {姓名}, 性别 = {性别}, 卡号 = {卡号}, 公司 = {公司}"; //数据对象 var data = new { 姓名 = "伍华聪", 性别 = "男", 卡号 = "10000", 公司 = "广州爱奇迪软件科技有限公司" }; ReplaceTemplate(template, data); } private void ReplaceTemplate(string template, object data) { var regex = @"\{(?<name>.*?)\}"; List<string> itemList = GetList(template, regex, "name"); Console.WriteLine("列出模板变量对象:"); foreach(string item in itemList) { Console.WriteLine(item); } Dictionary<string, string> dict = GetProperties(data); foreach(string item in itemList) { //若是属性存在,则替换模板,并修改模板值 if(dict.ContainsKey(item)) { template = Replace(template, regex, dict.Values.ToList());//替换第一个 } } Console.WriteLine(template); }
测试上面的代码,咱们注意到咱们的对象是动态构建的,也就是使用匿名类的方式构建一个类,包含有对应的属性值,把这个给模板进行解析,从而赋值造成真正的消息内容的。
var data = new { 姓名 = "伍华聪", 性别 = "男", 卡号 = "10000", 公司 = "广州爱奇迪软件科技有限公司" };
测试案例,咱们能够获得的消息,以下所示。
咱们从上面截图能够看到,真正的消息已经正确获得,这些是替换具体的模板内容造成的,若是咱们在总体的模板设计里面,采用这个思路,就能够实现动态的模板消息发送,从而实现了比较弹性化的设计处理。
本文只是对模板变量这种场景进行了分析,咱们在实际项目中,能够更加完善,实现更增强大的模板消息处理,以及利用微信模板消息进行一块儿发送,实现短信、微信,甚至邮件的同步通知,给客户更好的体验。
以上是微信的模板消息介绍,咱们也能够结合动态变量,把对应模板消息替换为咱们要发送的消息,从而也实现了微信消息的动态发送。