前言
在常见业务开发中,我们经常会遇到客户需要这样的需求:将几个属性拼接起来显示在页面上。比如一些显示通知类的内容
代码中的对象属性如下:
Student student = new Student();
student.setName("张三");
student.setIdentity("匪徒");
student.setDate(new Date());
Schoolbag bag = new Schoolbag();
bag.setColor("黄色");
bag.setPencilCase(new PencilCase("中性笔", 2));
student.setBag(bag);
需求就是显示这样的文本:各单位请注意:匪徒张三于2021-07-18 11:35:09背着黄色的包,里面装了2支中性笔
想法
代码中写死并拼接,这个工作无论是后端还是前端做,都不灵活,增加或修改该文本都需要发包;
用过String.format方法的同学应该知道根据特定符号替换里面的值,所以我就在想,bean对象可不可以也这样,根据对象的属性名取值拼接。
比如我预先把对象的属性名放在字符串中,然后利用反射取到对象里的值,然后替换该属性名。这一串含有属性名的文本我可以放在项目的配置中心,这样无论是开发、前端、测试、客户都可以进行文本的修改,当然属性名你不能修改,不然反射取不到值。
做法
首先可以写一个可以根据属性名利用反射获取对象值的工具类,如上Student对象,而且还要满足根据层级对象取值。当你看到这个博客的时候,恭喜你,不用写了,我在好多年前已经写了。也正因为之前写过这个工具类,我现在遇到这个需求也才会想到这个方案。利用反射对层级对象取其某层对象的某个值,可忽略层对象不存在
然后再写一个方法取出字符串中的属性名,为了方便取属性名,我们可以定义一个特殊符号来取,比如{%name%},完整如下
String format = "各单位请注意:{%identity%}{%name%}于{%date%}背着{%bag.color%}的包," + "里面装了{%bag.pencilCase.num%}支{%bag.pencilCase.name%}";
方法名beanFormatStr(Student, format),将bean根据定义的字符串格式化为所需要的文本。
/** * 通过对format与source对象反射匹配拼接值 * 需要匹配的值可在format中写为 * * @param source * @param format String format = "{%name%}在{%date%}背着{%bag.color%}的书包," + * "但是只装了{%bag.pencilCase.num%}支{%bag.pencilCase.name%},因为他是装笔!"; * @return */ public static String beanFormatStr(Object source, String format) { String[] str = format.split("\\{%"); StringBuilder sb = new StringBuilder(); for (String s : str) { int a = s.indexOf("%}"); if (a != -1) { String key = s.substring(0, a); sb.append(MyOptional.getVStrByField(source, key)); sb.append(s.substring(a + 2)); }else { sb.append(s); } } return sb.toString(); }
总结
当你看完这个代码,其实会觉得很简单,很好实现,只是要有这个想法很难。
要时刻怀着致力于写出思路更加清晰,逻辑性更强,冗余度更低,可维护性和可重用性更高的代码,这是我一直为之奋斗的目标。
简单一个字就是要“懒”:
咦~~,这个方法我之前写过类似的我懒得再写,我可不可以再把它抽象封装一下让这里也能用;
我天!!,这个业务写起来这么多行,我都懒得看/写下去,这样就会想着把他精简或封装;
客户变得真tm快!这个功能还没上线他就变了,我真是懒得改了,这个功能客户可不可以通过后台去维护,让他自己去玩。一定要想办法把客户易变的东西,交给他自己去维护;
代码
以下面这两个代码为准,上面这个博客里的代码我也懒得去更新了;上面这个也能用,只是我有新增的一些方法没有
就这些了,有问题再联系吧,都12:19了,该吃饭了:v:
本文由博客群发一文多发等运营工具平台 OpenWrite 发布