Java代码重构

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;
        }
    }

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。