美文网首页
Java代码重构

Java代码重构

作者: 索伦x | 来源:发表于2019-01-26 09:39 被阅读0次

    1、什么是重构?

    在不改变代码接口的情况下,对代码作出修改,以改进程序的内部结构。本质上说,重构就是在代码写好之后改进它的设计。

    2、重构的目的?

    重构的目的是使软件更容易被理解和修改。代码重构是软件开发过程中提高开发效率和质量的重要手段。重构不会改变软件可观察的行为,重构之后软件功能一如既往。

    • 提高代码质量(性能、可读性、可重用性)
    • 修改Bug
    • 增加新功能

    3、为什么要重构?

    随着需求的不断变更,之前的结构开始慢慢变得不适应。为了快速的完成需求,开发者可能会使用一些违背当前软件架构的方式实现功能,久而久之,这种「另类」的代码越来越多,导致软件之前的结构已经淹没在了这些杂乱无章的逻辑中,使得整个软件没有一个清晰的脉络,严重降低了代码的可读性和可维护性,一点小小的修改都有会造成不可预知的BUG产生。在这种情况下再进行大规模的需求开发,后果可能是灾难性的。重构就是在保留现有功能的基础上,重新梳理软件中的代码结构,让原本杂乱无章的代码重新具有可读性、结构性和可扩展性,增加软件的开发效率,优化程序的性能。重构的范围可大可小,大到涉及整个产品的各个模块,小到一个函数。

    重构代码-提取统一的数据访问和业务接口

    通用结果返回
    public class JsonResult<T> {
    
        private String code = ResponseCode.SUCCESS.getCode();
        private String message = ResponseCode.SUCCESS.getDesc();
        private T data;
    

    全局响应代码enum

    public enum  ResponseCode {
    
        SUCCESS("200","操作成功!"),
        FAIL("400","网络异常!")
        ;
    
        private String code;
        private String desc;
    
        private ResponseCode(String code, String desc){
            this.code = code;
            this.desc = desc;
        }
    
        public String getCode() {
            return code;
        }
    
        public void setCode(String code) {
            this.code = code;
        }
    
        public String getDesc() {
            return desc;
        }
    
        public void setDesc(String desc) {
            this.desc = desc;
        }
    }
    
    
    通用服务层
    public interface BaseService<T> {
       public List<T> list();
    }
    

    接口实现

    public class BaseServiceImpl<T> implements BaseService<T> {
    
        @Resource
        Mapper<T> mapper;
    
        public List<T> list() {
            return mapper.selectAll();
        }
    }
    
    通用Controller
    public class BaseController {
        public final Logger logger = LoggerFactory.getLogger(this.getClass());
    
        /**
         * 获取客户端真实IP地址
         *
         */
        public String getRemoteIp(HttpServletRequest request){
            return CusAccessObjectUtil.getIpAddress(request);
        }
    }
    

    Spring中Template模式与callback的结合使用浅析

    Spring不论是与ibatis,还是与Hibernate的结合中,都使用到了Template模式与callback技术,来达到简化代码实现的目的

    public interface BaseTemplate {
        public int insertRecord() throws Exception;
        /**
         *   操作数据库回调接口
         */
        public interface DatebasePoolCallback<T> {
            T doInDatabase(Connection connection);
        }
    }
    

    实现

    public class BaseTemplateImpl implements BaseTemplate {
    
        private DatabasePool pool;
    
        public BaseTemplateImpl(DatabasePool pool){
            this.pool = pool;
        }
    
        public <T> T execute(DatebasePoolCallback<T> action) throws Exception {
            T value = null;
            Connection connection = null;
            try {
                //执行数据库操作前先取出连接
                connection = pool.getConnection();
                return action.doInDatabase(connection);
            } catch (Exception e) {
                e.printStackTrace();
                throw e;
            } finally {
                //TODO 返还到连接池
                System.out.println("返还到连接池");
                //returnResource(pool, connection);
            }
        }
        public int insertRecord() throws Exception {
            return execute(new DatebasePoolCallback<Integer>() {
                public Integer doInDatabase(Connection connection) {
                    //TODO 数据库操作
                    System.out.println("数据库操作");
                    return 0;
                }
            }).intValue();
        }
    }
    

    利用Java回调机制实现短信自动重发

    /**
     * 异常重试工具类
     * @author Suoron
     */
    public class RetryUtils {
    
        private static Logger logger = LogManager.getLogger(RetryUtils.class);
    
        /**
         * 回调结果检查
         */
        public interface ResultCheck {
            boolean matching();
            
            String getJson();
    
            HashMap<String, Object> getHashMap();
        }
        
        /**
         * 在遇到异常时尝试重试
         * @param retryLimit 重试次数
         * @param retryCallable 重试回调
         * @return V
         */
        public static <V extends ResultCheck> V retryOnException(int retryLimit,
                java.util.concurrent.Callable<V> retryCallable) {
    
            V v = null;
            for (int i = 0; i < retryLimit; i++) {
                logger.info("请求第" + (i+1) + "次");
                try {
                    v = retryCallable.call();
                } catch (Exception e) {
                    e.printStackTrace();                
                }
                logger.info("结果:" + v.getJson());
                if (v.matching()) break;
                logger.info("重试第" + (i+1) + "次");
            }
            return v;
        }
        
        /**
         * 在遇到异常时尝试重试
         * @param retryLimit 重试次数
         * @param sleepMillis 每次重试之后休眠的时间
         * @param retryCallable 重试回调
         * @return V
         * @throws InterruptedException
         */
        public static <V extends ResultCheck> V retryOnException(int retryLimit, long sleepMillis,
                java.util.concurrent.Callable<V> retryCallable) throws InterruptedException {
    
            V v = null;
            for (int i = 0; i < retryLimit; i++) {
                logger.info("请求第" + (i+1) + "次");
                try {
                    v = retryCallable.call();
                } catch (Exception e) {
                    e.printStackTrace();                
                }
                logger.info("结果:" + v.getJson());
                if (v.matching()) break;
                logger.info(sleepMillis/1000 + "秒后重试第" + (i+1) + "次");
                Thread.sleep(sleepMillis);
            }
            return v;
        }
        
    }
    

    使用

       /**
         * 用于发送短信验证码
         * @param phone     需要接受验证码的手机号码
         * @param template  短信模板ID
         * @return 发送成功或失败  statusCode:错误码, statusMsg:错误信息
         * 000000   成功
         * 160042   号码格式有误
         * 160038   短信验证码发送过频繁
         * 160040   验证码超出同模板同号码天发送上限
         */
        public static HashMap<String, Object> sendSMS (final String phone, final String template, final String...params) {
    
            final CCPRestSDK restAPI = new CCPRestSDK();
    
            // 初始化服务器地址和端口,格式如下,服务器地址不需要写https://
            restAPI.init(serverAddress, serverPort);
    
            // 初始化主帐号和主帐号TOKEN
            restAPI.setAccount(acount, acountToken);
    
            // 初始化应用ID
            restAPI.setAppId(appId);
    
            long second = 3 * 1000;
    
            HashMap<String, Object> result;
    
            if ("64754".equals(template) || "64757".equals(template)) {
                // 发送(+重试)
                SmsRetry smsRetry = new SmsRetry();
                try {
                    smsRetry = RetryUtils.retryOnException(3, second, new Callable<SmsRetry>() {
    
                        @Override
                        public SmsRetry call() throws Exception {
                            // 发送
                            HashMap<String, Object> result = restAPI.sendTemplateSMS(phone,template ,params);
                            return new SmsRetry().setResult(result);
                        }
                    });
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                result = smsRetry.getHashMap();
            } else {
                // 发送
                result = restAPI.sendTemplateSMS(phone,template ,params);
            }
    
            return result;
    
    /*
            //成功代码:"000000"
            //异常返回输出错误码和错误信息
            "错误码=" + result.get("statusCode") +" 错误信息= "+result.get("statusMsg");
    */
        }
    
        // 重试
        private static class SmsRetry implements RetryUtils.ResultCheck {
    
            private HashMap<String, Object> result = null;
    
            public SmsRetry setResult(HashMap<String, Object> result) {
                this.result = result;
                return this;
            }
    
            @Override
            public boolean matching() {
                return result != null && "000000".equals(result.get("statusCode").toString());
            }
    
            @Override
            public String getJson() {
                return JsonUtil.toJson(result);
            }
    
            @Override
            public HashMap<String, Object> getHashMap() {
                return result;
            }
        }
    
    

    相关文章

      网友评论

          本文标题:Java代码重构

          本文链接:https://www.haomeiwen.com/subject/vhofjqtx.html