接http://www.itdecent.cn/p/2aec07816bbd
之前方案存在的問題
1.無法處理多個requestCode對應(yīng)一個ResultHandler,例如A業(yè)務(wù)包含增加、刪除、修改三個子業(yè)務(wù) ;
2.ResultHandler 功能不內(nèi)聚,理應(yīng)由自己決定是否處理該requestCode業(yè)務(wù),而不是是由ResultDispatcher 分發(fā)器決定;
3.dispatch的參數(shù)沒有封裝,一旦入?yún)⑦^多,閱讀性就比較差。
先從簡單的開始解決。
針對問題3,面向?qū)ο蠓庋bdispatch的參數(shù)
密封類封裝參數(shù),這里只列舉了常用的參數(shù),可以根據(jù)業(yè)務(wù)情況進行調(diào)整。
傳遞對象,對業(yè)務(wù)變化是很有好處,因為不至于因為參數(shù)增減,而改變函數(shù)的定義。
//密封類
data class Result(val requestCode: Int, val data: Intent?)
//ResultHandler onResult函數(shù)變化
abstract fun onResult(result:Result)
//ResultDispatcher dispatch函數(shù)的變化
fun dispatch(result:Result)
針對問題2,由ResultHandler 決定是否處理該requestCode;
interface ResultHandler {
val requestCodes: MutableList<Int>//1
fun isHandle(requestCode: Int): Boolean {//2
return requestCodes.contains(requestCode)
}
fun onResult(result:Result)
}
注釋1:集合維護該ResultHandler需要處理的requestCode,可以是多個;
注釋2:isHandle判斷是否處理該requestCode;
針對問題1,map代替list來處理多對一的關(guān)系;
interface ResultHandler {
abstract val requestCodeMap: MutableMap<Int,XXX>
......
}
大家可能注意到了,requestCodeMap的value是XXX(待定),因為value的類型是值得考慮。
業(yè)務(wù)場景:圖片業(yè)務(wù),可以劃分增加圖片、刪除圖片、修改圖片三種,他們分別對應(yīng)一個requestCode,那么第一反應(yīng)XXX是類,分別是增加圖片子類、刪除圖片子類、修改圖片子類。這樣的設(shè)計也沒有太大的問題。
但這里我們可以用函數(shù)式編程,XXX是函數(shù)類型,增加、刪除、修改,分別對應(yīng)不同的函數(shù)。ResultHandler 負責(zé)圖片業(yè)務(wù)處理,具有處理增加、刪除、修改的能力,也很符合單一設(shè)計原則。
不適用類還有一個好處,減少接口、類的定義。
最后優(yōu)化代碼,大家可以看下注釋,我就不一一解讀了,因為也不是很復(fù)雜。
業(yè)務(wù)處理接口
/***
* 業(yè)務(wù)處理接口,
*/
interface ResultHandler {
/***
* 子類必須實現(xiàn),注冊需要處理的requestCode 以及函數(shù)
* requestCode 與 高階函數(shù)對應(yīng)關(guān)系
*/
val map: MutableMap<Int, ((Result) -> Unit)>
/**
* 分發(fā)器判斷requestCode是否由該處理器處理
*/
fun isHandle(requestCode: Int) = map.contains(requestCode)
/**
* 調(diào)用對應(yīng)的高階函數(shù)進行處理
*/
fun onResult(result: Result) {
map[result.requestCode]?.invoke(result)
}
}
Result的定義
data class Result(val requestCode: Int, val data: Intent?)
ResultHandler的實現(xiàn)
/***
* 圖片業(yè)務(wù)處理
*/
class PhotoResultHandler : ResultHandler {
/***
* 注冊需要處理的requestCode以及高階函數(shù)
* 這里需要處理增加圖片、刪除圖片、修改圖片
*/
override val map: MutableMap<Int, (Result) -> Unit> =
mutableMapOf<Int, (Result) -> Unit>().apply {
put(ResultDispatcher.CODE_ADD_PHOTO, ::addPhoto)
put(ResultDispatcher.CODE_DEL_PHOTO, ::delPhoto)
put(ResultDispatcher.CODE_MODIFY_PHOTO, ::modifyPhoto)
}
/***
* 增加圖片
*/
private fun addPhoto(result: Result) {}
/***
* 刪除圖片
*/
private fun delPhoto(result: Result) {}
/***
* 修改圖片
*/
private fun modifyPhoto(result: Result) {}
}
/***
* 視頻業(yè)務(wù)處理
*/
class VideoResultHandler : ResultHandler {
override val map: MutableMap<Int, (Result) -> Unit> =
mutableMapOf<Int, (Result) -> Unit>().apply {
put(ResultDispatcher.CODE_VIDEO, ::handleVideo)
}
private fun handleVideo(result: Result) {}
}
ResultDispatcher的實現(xiàn)
object ResultDispatcher {
const val CODE_ADD_PHOTO = 1//增加圖片
const val CODE_DEL_PHOTO = 2//刪除圖片
const val CODE_MODIFY_PHOTO = 3//修改圖片
const val CODE_VIDEO = 4//視頻
/***
* 維護ResultHandler
*/
private val handlers = mutableListOf<ResultHandler>().apply {
add(PhotoResultHandler())
add(VideoResultHandler())
}
/***
* 查找對應(yīng)的處理器進行分發(fā)
*/
fun dispatch(requestCode: Int, intentData: Intent?) {
handlers.firstOrNull { it.isHandle(requestCode) }?.onResult(Result(requestCode, intentData))
}
}
調(diào)用處
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
ResultDispatcher.dispatch(requestCode, data)
}
以上分析有不對的地方,請指出,互相學(xué)習(xí),謝謝哦!