最近開發總結


背景

開發完短信平台,開始做一個匯聚平台。現在開始大量使用設計模式來做了,其實也就是那些比較常用的。設計模式,用的合適的話,對擴展性和維護,帶來了很大的便利。
短信平台使用模板方法和觀察者模式,現在匯聚平台簡單使用一個工廠模式,之前做了一個生產者消費者,但是發現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;
        }
}

字符串轉對象的時候,需要自建幾個對象,去接收這些數據。不再詳述。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM