zoukankan      html  css  js  c++  java
  • 项目展示文案生成设计

    开发过程中,会涉及到文案展示的动作。这些文案可能需要从持久化或者程序处理过程中的内容来进行展示。最蛋疼的事情,由于其中文案的变动性或者设计问题,导致这些文案在程序的各个位置,通过各种stringbuffer、stringbuilder甚至直接各种 "" + "" 之类的拼接,导致程序千疮百孔,不够“优雅”不说,后面维护的成本简直不谈了。

     

    其实大部分情况下,文案如果不涉及到需要根据持久化数据活着计算的数据进行展示的话,其实是可以很简单提到一个配置中心去,数据库也罢、配置文件也罢,甚至类似zookeeper之类的中间件也都可以。但是如果需要根据某些数据实时替换里面的内容,那就显得费劲了。

     

    我们知道Java提供了一个叫做MessageFormat的类,里面直接format一些一些固定格式。比如我们定义一句话叫做:满{0}减{1}元,然后我们传入给你MessageFormat.format一个数组,数组的内容是:{100,10},于是我们可以根据MessageFormat获得文案为:满100减10元。

    其实这个是比较简单和易于理解的,我们只需要在程序中把需要动态生成的内容填充到一个数组中,然后将文案配置在另外一个位置,然后不停的调用MessageFormat去获得需要的文案,这样子也可以。然而这种做法有一个问题,就是数组的含义不明确,严重依赖填入顺序,同时在外面配置文案的时候也并不明白那个0或者1到底是个什么东西。

    既然我们知道哪些地方该填充什么内容,其实不如我们整理系统所有文案,然后抽象和公用一些关键词,通过约定的关键词填充在文案中,与此同时,程序里面将数组的结构转换为Map结构,map的key就是这些关键词,value就是刚才数组的内容了。如此我们可以摆脱对于数组顺序的要求,同时文案的配置也可以从开发同学的手中转移到PM甚至运营同学的手中。

    然而我们还需要确定这种方案的性能以及可用性,于是我们可以做一个实验:

    import com.google.common.base.Stopwatch;
    import org.apache.commons.lang3.StringUtils;
    
    import java.text.MessageFormat;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.concurrent.TimeUnit;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    /**
     * created by @author <a href="mailto:congshaogang@meituan.com">Shaogang Cong</a> on 16/5/31.
     */
    public class EffiencyTest {
        private static String aaa = "满{sum}元减{credit}元,在线支付再减{cre1},限{start}到{endtime}";
        private static String aaa1 = "满{0}元减{1}元,在线支付再减{2},限{3}到{4}";
        static Object[] aaa1Array = {100, 19, 20, "23:30", "23:45"};
        static Map<String, Object> parameterMap = new HashMap<String, Object>();
    
        static {
            parameterMap.put("sum", 100);
            parameterMap.put("credit", 19);
            parameterMap.put("cre1", 20);
            parameterMap.put("start", "23:30");
            parameterMap.put("endtime", "23:45");
        }
    
        public static void main(String[] args) {
            Stopwatch stopwatch = Stopwatch.createStarted();
            for (int i = 0; i < 100000; i++) {
                MessageFormat.format(aaa1, aaa1Array);
            }
            System.out.println("messageformat" + stopwatch.elapsed(TimeUnit.MILLISECONDS));
    
            String patternString = "\{(" + StringUtils.join(parameterMap.keySet(), "|") + ")\}";
    
            System.out.println(patternString);
            stopwatch.reset();
            stopwatch.start();
    
    
            Pattern pattern = Pattern.compile(patternString);
            for (int i = 0; i < 100000; i++) {
                Matcher matcher = pattern.matcher(aaa);
    
                StringBuffer sb = new StringBuffer();
                while (matcher.find()) {
                    matcher.appendReplacement(sb, parameterMap.get(matcher.group(1)).toString());
                }
                matcher.appendTail(sb);
                System.out.println(sb.toString());
            }
    
            System.out.println("pattern" + stopwatch.elapsed(TimeUnit.MILLISECONDS));
        }
    
    }

    执行结果:

    messageformat910
    {(endtime|start|sum|cre1|credit)}
    pattern229

    我们会发现,Map的方式不但容易理解,而且效率要远高于messageformat的方式。同时,我们完全可以做到正则表达式里面的pattern提前compile 暂存起来,如果确实有变化,还可以通过刷新缓存的方式进行更新。

    最后,我们讲Map中的key统一到一个常量类活着其他结构中,供开发、产品或者运营童鞋使用即可了。

     

  • 相关阅读:
    SVN合并时报错:Merge tracking not allowed with missing subtrees; try restoring these items
    The operation names in the portType match the method names in the SEI or Web service implementation class.
    原生java调用webservice的方法,不用生成客户端代码
    如何快速开发一个支持高效、高并发的分布式ID生成器
    分布式ID生成器解决方案
    高并发分布式系统中生成全局唯一Id汇总
    python接口自动化17-multipart/form-data表单提交
    httprunner学习25-文件上传multipart/form-data
    python测试开发django-72.删除表后如何重新生成表
    python测试开发django-71.自定义标签tag
  • 原文地址:https://www.cnblogs.com/congsg2016/p/5568357.html
Copyright © 2011-2022 走看看