zoukankan      html  css  js  c++  java
  • 最近开发总结

    背景

    开发完短信平台,开始做一个汇聚平台。现在开始大量使用设计模式来做了,其实也就是那些比较常用的。设计模式,用的合适的话,对扩展性和维护,带来了很大的便利。
    短信平台使用模板方法和观察者模式,现在汇聚平台简单使用一个工厂模式,之前做了一个生产者消费者,但是发现queue有点问题,还是舍弃了。
    既然是总结,还是多记录些代码。

    接口

    汇聚平台做数据服务,最主要的是数据接口。这里,做的时候是模仿支付宝的支付接口。
    接口处,采用工厂模式,方便扩展,不同的服务根据服务名称进行区分。
    主入口的类,只是对数据进行一些校验,并不是做业务逻辑。

     //参数验证通过,验证接口服务
                    if (!valiService(service)){
                            return getRespCode(ErrorCode.SERVICE_ERR,key);
                    }
                    //接口服务通过,验证接入商
                    Access access = getAccess(commuCode);
                    if (access == null){
                            return getRespCode(ErrorCode.VALIDATE_ERR,key);
                    }
                    key = access.getAccessKey();
                    //验证签名
                    if (!valiSign(data,key)){
                            return getRespCode(ErrorCode.SIGN_ERR,key);
                    }
                    //处理业务逻辑
                    String result ;
                    try {
                            result = doBusi(service,data);
                    } catch (ParamException e) {
                            return getRespCode(ErrorCode.PARAM_ERR,key);
                    } catch (SystemException e1){
                            return getRespCode(ErrorCode.SYS_ERR,key);
                    }
                    logger.info("Cost Time:" + (System.currentTimeMillis() - a));
                    //流量数据不需要返回具体的业务数据,对外服务需要返回特定的数据
                    return "".equals(result) ? getRespCode(ErrorCode.SUCCESS,key) : result;
    

    这里定义了两个自定义的异常,分别由处理业务的时候抛出来。这里的业务采用工厂方式,根据不同的服务来产生。

            private String doBusi(String service,String data) throws ParamException, SystemException {
                    //处理不同业务
                    setServiceMap(serviceMap);
                    Business business = ServiceFactory.produce(service);
                    return business.doProcess(serviceMap,data);
            }
    

    所有业务实现业务接口就可以:

    public interface Business {
            //返回处理数据
            String doProcess(Map<String,BaseService> services,String data) throws ParamException, SystemException;
    }
    
    

    然后配一个简单的工厂类:

    public class ServiceFactory {
            private static Logger logger = Logger.getLogger(ServiceFactory.class);
    
            public static Business produce(String type){
                    if (Services.FLOW_DATA.key.equals(type)){
                            return new FlowDataProcess();
                    }
                    else if (Services.PARK_AROUND.key.equals(type)){
                            return new ParkAroundProcess();
                    }
                    else if (Services.PARK_ALL.key.equals(type)){
                            return new ParkAllProcess();
                    }
                    else {
                            logger.error("Error Type When DoProcess in Factory");
                            return null;
                    }
            }
    }
    

    这样就将业务的耦合性降低了很多。

    数据格式

    对外服务的接口,数据格式都有一定的约束。所以,就写了一个工具包,将字符串数据转换为相应的对象,或者将对象转为字符串。不只是为自己使用,也为客户端提供。使用泛型写一个,比较通用。
    这个时候,规定两个接口Encoder和Decoder 。
    其中,有涉及到多个数据,使用list来存放,具体放的类型,也要有上界规定。这样容易统一list中的数据。不再详细描述。

    1,数据进行格式化,将对象转换为字符串

    public class DataEncoder<T, V> implements Encoder<T, V> {
    
            private StringBuilder dataEncode(T o, String pattern) throws IllegalAccessException {
                    StringBuilder sb = new StringBuilder();
                    Field[] fields = o.getClass().getDeclaredFields();
                    for (Field field : fields) {
                            field.setAccessible(true);
                                    if (field.get(o) == null) {
                                            sb.append("");
                                    } else if ("java.util.Date".equals(field.getType().getName())) {
                                            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
                                            sb.append(sdf.format(field.get(o)));
                                    } else {
                                            sb.append(field.get(o));
                                    }
                            sb.append(pattern);
                    }
                    //sb.deleteCharAt(sb.lastIndexOf(pattern));
                    return sb;
            }
    
            public String requestEncode(V o,String k) throws IllegalAccessException {
                    StringBuilder sb = new StringBuilder();
                    Field[] fields = o.getClass().getDeclaredFields();
                    for (Field field : fields) {
                                    field.setAccessible(true);
                                    if (field.get(o) == null) {
                                            sb.append("");
                                    } else if ("java.util.List".equals(field.getType().getName())) {
                                            StringBuilder sb2 = new StringBuilder();
                                            List<T> obj = (List) field.get(o);
                                            for (T o1 : obj) {
                                                    StringBuilder stringBuilder = dataEncode(o1,"|");
                                                    stringBuilder.deleteCharAt(stringBuilder.lastIndexOf("|"));
                                                    //sb2.append(dataEncode(o1, "|").toString());
                                                    sb2.append(stringBuilder.toString());
                                                    sb2.append(";");
                                            }
                                            sb2.deleteCharAt(sb2.lastIndexOf(";"));
                                            sb.append(sb2.toString());
                                    } else {
                                            sb.append(field.get(o));
                                    }
                            sb.append("&");
                    }
                    System.out.println("Pre data:"+sb.toString());
                    if (!"".equals(k) &&  k != null){
                            signSb(sb,k);
                    }
                    //sb.deleteCharAt(sb.lastIndexOf("&"));
                    return sb.toString();
            }
    
            public String responseEncode(T t,String k) throws IllegalAccessException {
                    StringBuilder sb = dataEncode(t, "&");
                    if (!"".equals(k) &&  k != null){
                            signSb(sb,k);
                    }
                    return sb.toString();
            }
    
            //为字符串增加签名
            private void signSb(StringBuilder data,String k){
                    String s = data.toString();
                    String sign = MD5.sign(s, k, "utf-8");
                    data.append(sign);
            }
    
            //参数为string的签名
            public String sign(String s,String k){
                    return MD5.sign(s+"&key="+k,k,"utf-8");
            }
    }
    
    

    2,数据转换,将字符串数据解析,转换为对象

    public class DataDecoder implements Decoder {
            public MsgDecoder deReq(String data) throws NoSuchFieldException, IllegalAccessException {
                    MsgDecoder decoder = new MsgDecoder();
                    String[] outer = data.split("&");
                    decoder.setServiceName(outer[0]);
                    decoder.setCommuCode(outer[1]);
    
                    List<MsgData> inner = new ArrayList<MsgData>();
                    String datas = outer[2];
                    String[] inners = datas.split(";");
                    for (String s : inners) {
                            MsgData msgData = new MsgData();
                            String[] sa = s.split("\|");
                            for (int i = 0; i < sa.length; i++) {
                                    Field field = msgData.getClass().getDeclaredField("arg" + i);
                                    field.setAccessible(true);
                                    field.set(msgData, sa[i]);
                            }
                            inner.add(msgData);
                    }
                    decoder.setDatas(inner);
                    decoder.setSign(outer[3]);
                    return decoder;
            }
    
            public RespDecoder deResp(String data) {
                    RespDecoder decoder = new RespDecoder();
                    String[] strings = data.split("&");
                    decoder.setCode(Integer.parseInt(strings[0]));
                    decoder.setDesc(strings[1]);
                    //异常数据中,第三个字段会为空
                    if (strings.length >2){
                            decoder.setSign(strings[2]);
                    }
                    return decoder;
            }
    }
    
    

    字符串转对象的时候,需要自建几个对象,去接收这些数据。不再详述。

  • 相关阅读:
    laravel 安装及入门
    mysql事务处理的意义
    PHP项目:如何用PHP高并发检索数据库?
    inner join、left join、right join等的区别
    百度地图引入网页中
    google地图引入网页
    thinkphp的mvc理解
    SpringBoot+Shiro入门小栗子
    Springboot+WebSocket+Kafka(写着玩的)
    Windows下安装单机Kafka
  • 原文地址:https://www.cnblogs.com/juepei/p/4606994.html
Copyright © 2011-2022 走看看