java 重构函数_包会,教你用Java函数式编程重构烂代码
Java8 由Oracle在2014年發布,是繼Java5之后最具革命性的版本。
Java8吸收其他語言的精髓帶來了函數式編程,lambda表達式,Stream流等一系列新特性,學會了這些新特性,可以讓你實現高效編碼優雅編碼。
爛代碼登場
首先引入一個實際的例子,我們常常會寫一個dao類來操作數據庫,比如查詢記錄,插入記錄等。
下面的代碼中實現了查詢和插入功能(引入Mybatis三方件):public?class?StudentDao{
/**
*?根據學生id查詢記錄
*?@param?id?學生id
*?@return?返回學生對象
*/
public?Student?queryOne(int?id){
SqlSessionFactory?sqlSessionFactory?=?getSqlSessionFactory();
SqlSession?session?=?null;
try?{
session?=?sqlSessionFactory.openSession();
//?根據id查詢指定的student對象
return?session.selectOne("com.coderspace.mapper.student.queryOne",?id);
}?finally?{
if?(session?!=?null)?{
session.close();
}
}
}
/**
*?插入一條學生記錄
*?@param?student?待插入對象
*?@return?true?if?success,?else?return?false
*/
public?boolean?insert(Student?student){
SqlSessionFactory?sqlSessionFactory?=?getSqlSessionFactory();
SqlSession?session?=?null;
try?{
session?=?sqlSessionFactory.openSession();
//?向數據庫插入student對象
int?rows?=?session.insert("com.coderspace.mapper.student.insert",?student);
return?rows?>?0;
}?finally?{
if?(session?!=?null)?{
session.close();
}
}
}
}
睜大眼睛觀察上面的代碼可以發現,這兩個方法有很多重復的代碼。
除了下面這兩行,其他的代碼都是一樣的,都是先獲取session,然后執行核心操作,最后關閉session。//?方法1中核心代碼
return?session.selectOne("com.coderspace.mapper.student.queryOne",?id);//?方法2中核心代碼
int?rows?=?session.insert("com.coderspace.mapper.student.insert",?student);
作為一個有追求的程序員,不,應該叫代碼藝術家,是不是應該考慮重構一下。
獲取session和關閉session這段代碼圍繞著具體的核心操作代碼,我們可以稱這段代碼為模板代碼。
假如又來了一個需求,需要實現刪除student方法,那么你肯定會copy上面的獲取session和關閉session代碼,這樣做有太多重復的代碼,作為一名優秀的工程師肯定不會容忍這種事情的發生。
開始重構爛代碼
怎么重構呢?現在請出我們的主角登場:環繞執行模式使行為參數化。
名字是不是很高大上,啥叫行為參數化?上面例子中我們已經觀察到了,除了核心操作代碼其他代碼都是一模一樣,那我們是不是可以將核心操作代碼作為入參傳入模板方法中,根據不同的行為分別執行。
變量對象很容易作為參數傳入,行為可以作為參數傳入嗎?
答案是:當然可以,可以采用lambda表達式傳入。
下面開始重構之前的例子,主要可以分為三步:
(1)定義函數式接口;
(2)定義模板方法;
(3)傳遞lambda表達式
所有的環繞執行模式都可以套用上面這三步公式。
第一步:定義函數式接口@FunctionalInterface
public?interface?DbOperation{
/**
*?通用操作數據庫接口
*?@param?session?數據庫連接session
*?@param?mapperId?關聯mapper文件id操作
*?@param?params?操作參數
*?@return?返回值,R泛型
*/
R?operate(SqlSession?session,?String?mapperId,?Object?params);
}
定義了一個operate抽象方法,接收三個參數,返回泛型R。
第二步:定義模板方法
DbOperation是一個函數式接口,作為入參傳入:public?class?CommonDao{
public?R?proccess(DbOperation?dbOperation,?String?mappperId,?Object?params){
SqlSessionFactory?sqlSessionFactory?=?getSqlSessionFactory();
SqlSession?session?=?null;
try?{
session?=?sqlSessionFactory.openSession();
//?核心操作
return?dbOperation.operate(session,?mappperId,?params);
}?finally?{
if?(session?!=?null)?{
session.close();
}
}
}
}
第三步:傳遞lambda表達式//?根據id查詢學生
String?mapperId?=?"com.coderspace.mapper.student.queryOne";
int?studentNo?=?123;
CommonDao?commonDao?=?new?CommonDao<>();
//?使用lambda傳遞具體的行為
Student?studentObj?=?commonDao.proccess(
(session,?mappperId,?params)?->?session.selectOne(mappperId,?params),
mapperId,?studentNo);
//?插入學生記錄
String?mapperId2?=?"com.coderspace.mapper.student.insert";
Student?student?=?new?Student("coderspace",?1,?100);
CommonDao?commonDao2?=?new?CommonDao<>();
//?使用lambda傳遞具體的行為
Boolean?successInsert?=?commonDao2.proccess(
(session,?mappperId,?params)?->?session.selectOne(mappperId,?params),
mapperId2,?student);
實現了上面三步,假如要實現刪除方法,CommonDao里面一行代碼都不用改,只用在調用方傳入不同的參數即可實現。
總結
環繞執行模式在項目實戰中大有用途,如果你發現幾行易變的代碼外面圍繞著一堆固定的代碼,這個時候你應該考慮使用lambda環繞執行模式了。
環繞執行模式固有套路請跟我一起大聲讀三遍:
第一步:定義函數式接口
第二步:定義模板方法
第三步:傳遞lambda表達式
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的java 重构函数_包会,教你用Java函数式编程重构烂代码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 双汇股价最近为什么老是跌 与这些原因不无
- 下一篇: 新款雷克萨斯lx570有什么新功能,带你