国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

利用函數(shù)式優(yōu)雅的重構(gòu)API

bergwhite / 3389人閱讀

摘要:新建字典必要的驗(yàn)證參數(shù)不能為空調(diào)用封裝數(shù)據(jù)到統(tǒng)一到結(jié)構(gòu)體異常處理包括中拋出到自定義異常和未知異常統(tǒng)一包裝到返回對(duì)象中這樣子的代碼在開(kāi)發(fā)接口的時(shí)候比比皆是。

基礎(chǔ)知識(shí)

在開(kāi)始之前 假設(shè)你從未了解過(guò)函數(shù)式編程,本文不會(huì)教你函數(shù)式里面的各種概念。而是用實(shí)際案例讓給了解到函數(shù)式編程的魅力,并且能夠在合適的場(chǎng)景中應(yīng)用。

## 重構(gòu)之前

基本代碼如下 很普通的 springboot http接口。

@RequiresRoles(roles = {RoleEnum.ADMIN_CENTER})
   @ApiOperation(value = "新建字典")
   @PostMapping("save")
   public Response saveDict(@RequestBody SaveDictVO vo) {


       Response response;
       try {
           // 1 必要的驗(yàn)證參數(shù)
           if (StringUtils.isBlank(vo.getTypeValue())) {
               response = new Response(ResponseStatus.BAD_REQUEST.getCode(), "typeValue不能為空");


           } else {
               // 2.調(diào)用service
               boolean b = dictTypeService.saveDictType(vo);

               response = new Response(ResponseStatus.OK.getCode(), ResponseStatus.OK.getMsg());
               // 3 封裝數(shù)據(jù)到統(tǒng)一到結(jié)構(gòu)體
               response.setData(b);

               return response;
           }
       } catch (Exception e) {
           // 4.異常處理  包括 service中拋出到自定義異常和未知異常統(tǒng)一包裝到 返回對(duì)象中
           response = GlobalControllerExceptionHandler.resolveExceptionCustom(e);
       }

       return response;


   }

這樣子的代碼 在開(kāi)發(fā)http接口的時(shí)候比比皆是。本身寫(xiě)的不壞,沒(méi)有拗口的地方,邏輯很嚴(yán)謹(jǐn),讀起來(lái)很流暢。
美中不足的是,不夠通用化。 大量這樣的代碼容易讓編碼的人變成一個(gè)不會(huì)思考的機(jī)器...

簡(jiǎn)單重構(gòu) 分析

對(duì)比之前寫(xiě)的每個(gè)http接口我們很容易發(fā)現(xiàn)它們有相似的特點(diǎn)

必要的驗(yàn)證參數(shù)

調(diào)用service

封裝數(shù)據(jù)到統(tǒng)一到結(jié)構(gòu)體

異常處理 包括 service中拋出到自定義異常和未知異常統(tǒng)一包裝到 返回對(duì)象中

只有第二步是不同的,其他步驟幾乎是重復(fù)的邏輯。

先做簡(jiǎn)單的

我們可以抽取一個(gè)方法把 1,3,4做統(tǒng)一處理

public Response action(Object req) {

        try {
            String vstr = ValidatorUtils.validate(req);
            if (StringUtils.isNotBlank(vstr)) {
                return new Response(ResponseStatus.BAD_REQUEST.getCode(), vstr);
            }
            Object result = null; // 調(diào)用servcie 執(zhí)行結(jié)果
            Response response = new Response(ResponseStatus.OK.getCode(), ResponseStatus.OK.getMsg());
            response.setData(result);

            return response;
        } catch (Exception e) {
            log.error("", e);
            Response response = GlobalControllerExceptionHandler.resolveExceptionCustom(e);
            return response;
        }
    }
用接口抽象service邏輯
public interface ActionCallBack {

    Object action(Object req);


}

修改上面的action方法

public Response action(Object req, ActionCallBack action) {

        try {
            String vstr = ValidatorUtils.validate(req);
            if (StringUtils.isNotBlank(vstr)) {
                return new Response(ResponseStatus.BAD_REQUEST.getCode(), vstr);
            }
            Object result = action.action(req);
            Response response = new Response(ResponseStatus.OK.getCode(), ResponseStatus.OK.getMsg());
            response.setData(result);

            return response;
        } catch (Exception e) {
            log.error("", e);
            Response response = GlobalControllerExceptionHandler.resolveExceptionCustom(e);
            return response;
        }
    }
如何使用
@RequiresRoles(roles = {RoleEnum.ADMIN_CENTER})
    @ApiOperation(value = "新建字典")
    @PostMapping("save")
    public Response saveDict(@RequestBody SaveDictVO vo) {


        return action(vo, new ActionCallBack() {
            @Override
            public Object action(Object req) {
                //業(yè)務(wù)邏輯
                return dictTypeService.saveDictType(vo);
            }
        });


    }
引入函數(shù)式

當(dāng)我們重構(gòu)完上面的代碼,并在 saveDict方法中引入使用時(shí),一切看起來(lái)都很美好。但是IDE卻給出一些善良的提示.

nonymous new ActionCallBack() can be replaced with lambda less... (?F1) 
Inspection info: Reports all anonymous classes which can be replaced with lambda expressions
Lambda syntax is not supported under Java 1.7 or earlier JVMs.

根據(jù)IDEA 提示將代碼修改成函數(shù)式風(fēng)格

@RequiresRoles(roles = {RoleEnum.ADMIN_CENTER})
    @ApiOperation(value = "新建字典")
    @PostMapping("save")
    public Response saveDict(@RequestBody SaveDictVO vo) {


        return action(vo, req -> {
            //業(yè)務(wù)邏輯
            return dictTypeService.saveDictType(vo);
        });


    }
引入原生函數(shù)式接口
public  Response action(R req, Function action) {

        try {
            String vstr = ValidatorUtils.validate(req);
            if (StringUtils.isNotBlank(vstr)) {
                return new Response(ResponseStatus.BAD_REQUEST.getCode(), vstr);
            }
            Object result = action.apply(req);
            Response response = new Response(ResponseStatus.OK.getCode(), ResponseStatus.OK.getMsg());
            response.setData(result);

            return response;
        } catch (Exception e) {
            log.error("", e);
            Response response = GlobalControllerExceptionHandler.resolveExceptionCustom(e);
            return response;
        }
    }
最終成果
@Api(value = "指標(biāo)API", description = "指標(biāo)API")
@RestController
@RequestMapping(ConfigConstants.CURRENT_API_VERSION + "/indicators")
public class IndicatorsController extends BaseController {

    @Autowired
    private IndicatorsService indicatorsService;

    @RequiresRoles(roles = {RoleEnum.ADMIN_CENTER})
    @ApiOperation(value = "新增指標(biāo)")
    @PostMapping("/save")
    public Response save(@ApiIgnore @ModelAttribute DwSalaryEmpInfo empInfo, @RequestBody AddIndicatorsVO vo) {
        return action(vo, v -> {
            Indicators model = BeanCopyUtils.copy(vo, new Indicators());
            Indicators record = indicatorsService.saveIndicators(empInfo, model);
            return BeanCopyUtils.copy(record, new IndicatorsVO());
        });
    }

    @RequiresRoles(roles = {RoleEnum.ADMIN_CENTER})
    @ApiOperation(value = "刪除指標(biāo)")
    @PostMapping("/remove")
    public Response remove(@ApiIgnore @ModelAttribute DwSalaryEmpInfo empInfo, @RequestParam String id) {
        return action(() -> indicatorsService.removeIndicators(id));
    }
}
小結(jié)

上面代碼來(lái)自我自己的實(shí)際項(xiàng)目一個(gè)縮影,實(shí)際上做一個(gè)上層的封裝要處理很多問(wèn)題,比如某些接口不需要參數(shù)驗(yàn)證,或者不需要返回值,就需要對(duì)action函數(shù)進(jìn)行重載。讓業(yè)務(wù)更方便的使用。

通過(guò)使用函數(shù)式變成對(duì)過(guò)程/對(duì)象混合代碼進(jìn)行重構(gòu),使得代碼更凝練而有表達(dá)力了。雖然函數(shù)式編程尚未廣泛推廣于大型工程中,只有一部分程序猿開(kāi)始嘗試使用,在理解上也需要一定的思維轉(zhuǎn)換,不過(guò)適度使用確實(shí)能增強(qiáng)代碼的抽象表達(dá)力。僅僅是“高階函數(shù)+泛型+惰性求值”的基本使用,就能產(chǎn)生強(qiáng)大而凝練的表達(dá)效果。 函數(shù)式編程確有一套自己獨(dú)特的編程設(shè)計(jì)理念。

現(xiàn)代軟件開(kāi)發(fā)已經(jīng)不僅僅是單純地編寫(xiě)代碼實(shí)現(xiàn)邏輯,而是含有很強(qiáng)的設(shè)計(jì)過(guò)程。需要仔細(xì)提煉概念、對(duì)象、操作,仔細(xì)設(shè)計(jì)對(duì)象之間的交互,有效地組合一系列關(guān)聯(lián)對(duì)象成為高內(nèi)聚低耦合的模塊,有效地隔離對(duì)象關(guān)聯(lián)最小化依賴關(guān)系,如此才能構(gòu)建出容易理解和擴(kuò)展、更容易演進(jìn)的長(zhǎng)久發(fā)展的軟件。編程即是設(shè)計(jì),從具象到抽象再到具象的過(guò)程。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/74753.html

相關(guān)文章

  • Python語(yǔ)言中計(jì)數(shù)方法演變

    摘要:譯文鏈接編程派有時(shí)候,利用語(yǔ)言簡(jiǎn)潔優(yōu)雅地解決問(wèn)題的方法,會(huì)隨著時(shí)間變化。隨著不斷進(jìn)化,統(tǒng)計(jì)列表元素?cái)?shù)量的方法也在改變。最后將字典中相應(yīng)鍵的值設(shè)置為新的計(jì)數(shù)。我們發(fā)現(xiàn)這種方法比之前的代碼更加簡(jiǎn)潔優(yōu)雅,所以提交了此次修改。 showImg(https://segmentfault.com/img/remote/1460000010723715); 文中如對(duì)專業(yè)術(shù)語(yǔ)的翻譯有誤,請(qǐng)Pytho...

    sunsmell 評(píng)論0 收藏0
  • Hooks + Context:狀態(tài)管理新選擇

    摘要:用戶點(diǎn)擊改變?nèi)譅顟B(tài)崔然渲染整顆組件樹(shù)有沒(méi)有解決方案呢當(dāng)然有創(chuàng)建一個(gè)只接收的新組件,并將組件中的邏輯都移到組件中。最終的示例使用全局狀態(tài)和生成全局狀態(tài)和崔然完整示例見(jiàn)結(jié)論在和出現(xiàn)之前,缺乏自帶的全局狀態(tài)管理能力。 React 16.3 版本,正式推了出官方推薦的 context API —— 一種跨層級(jí)的數(shù)據(jù)傳遞方法。React 16.8 版本,推出了全新的 hooks 功能,將原本只...

    tommego 評(píng)論0 收藏0
  • 響應(yīng)設(shè)計(jì)個(gè)人一些總結(jié)

    摘要:所以一個(gè)網(wǎng),甚至是響應(yīng)式設(shè)計(jì),在兩個(gè)平臺(tái)上都會(huì)損害您整體的。三響應(yīng)式與如果把網(wǎng)站作為一個(gè)單獨(dú)的網(wǎng)站,如果網(wǎng)站的內(nèi)容與桌面版的內(nèi)容相對(duì)缺少,導(dǎo)致用戶回到桌面端的網(wǎng)站,會(huì)記錄這種選擇,使搜索排名降低,國(guó)內(nèi)百度就不知道會(huì)怎樣。 一、為什么需要響應(yīng)式設(shè)計(jì)(responsible web design) 1. 響應(yīng)式發(fā)展背景 1、屏幕尺寸的快速變化,iphone為320x480,分辨率在未來(lái)可以...

    LeoHsiun 評(píng)論0 收藏0
  • 重構(gòu) - 改善代碼各方面問(wèn)題

    摘要:暴露接口如果是函數(shù),就擴(kuò)展,否則就是驗(yàn)證數(shù)據(jù)使用金額校驗(yàn)規(guī)則這樣運(yùn)行能正常,也有擴(kuò)展性性,但是對(duì)于代碼潔癖的來(lái)說(shuō),這樣寫(xiě)法不優(yōu)雅。 重構(gòu)不是對(duì)以前代碼的全盤否定,而是利用更好的方式,寫(xiě)出更好,更有維護(hù)性代碼。不斷的追求與學(xué)習(xí),才有更多的進(jìn)步。 1.前言 做前端開(kāi)發(fā)有一段時(shí)間了,在這段時(shí)間里面,對(duì)于自己的要求,不僅僅是項(xiàng)目能完成,功能正常使用這一層面上。還盡力的研究怎么寫(xiě)出優(yōu)雅的代碼,性...

    AlphaWallet 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<