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;
}
}
网友评论