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

資訊專欄INFORMATION COLUMN

利用函數式優雅的重構API

bergwhite / 3396人閱讀

摘要:新建字典必要的驗證參數不能為空調用封裝數據到統一到結構體異常處理包括中拋出到自定義異常和未知異常統一包裝到返回對象中這樣子的代碼在開發接口的時候比比皆是。

基礎知識

在開始之前 假設你從未了解過函數式編程,本文不會教你函數式里面的各種概念。而是用實際案例讓給了解到函數式編程的魅力,并且能夠在合適的場景中應用。

## 重構之前

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

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


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


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

               response = new Response(ResponseStatus.OK.getCode(), ResponseStatus.OK.getMsg());
               // 3 封裝數據到統一到結構體
               response.setData(b);

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

       return response;


   }

這樣子的代碼 在開發http接口的時候比比皆是。本身寫的不壞,沒有拗口的地方,邏輯很嚴謹,讀起來很流暢。
美中不足的是,不夠通用化。 大量這樣的代碼容易讓編碼的人變成一個不會思考的機器...

簡單重構 分析

對比之前寫的每個http接口我們很容易發現它們有相似的特點

必要的驗證參數

調用service

封裝數據到統一到結構體

異常處理 包括 service中拋出到自定義異常和未知異常統一包裝到 返回對象中

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

先做簡單的

我們可以抽取一個方法把 1,3,4做統一處理

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; // 調用servcie 執行結果
            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) {
                //業務邏輯
                return dictTypeService.saveDictType(vo);
            }
        });


    }
引入函數式

當我們重構完上面的代碼,并在 saveDict方法中引入使用時,一切看起來都很美好。但是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.

根據IDEA 提示將代碼修改成函數式風格

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


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


    }
引入原生函數式接口
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 = "指標API", description = "指標API")
@RestController
@RequestMapping(ConfigConstants.CURRENT_API_VERSION + "/indicators")
public class IndicatorsController extends BaseController {

    @Autowired
    private IndicatorsService indicatorsService;

    @RequiresRoles(roles = {RoleEnum.ADMIN_CENTER})
    @ApiOperation(value = "新增指標")
    @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 = "刪除指標")
    @PostMapping("/remove")
    public Response remove(@ApiIgnore @ModelAttribute DwSalaryEmpInfo empInfo, @RequestParam String id) {
        return action(() -> indicatorsService.removeIndicators(id));
    }
}
小結

上面代碼來自我自己的實際項目一個縮影,實際上做一個上層的封裝要處理很多問題,比如某些接口不需要參數驗證,或者不需要返回值,就需要對action函數進行重載。讓業務更方便的使用。

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

現代軟件開發已經不僅僅是單純地編寫代碼實現邏輯,而是含有很強的設計過程。需要仔細提煉概念、對象、操作,仔細設計對象之間的交互,有效地組合一系列關聯對象成為高內聚低耦合的模塊,有效地隔離對象關聯最小化依賴關系,如此才能構建出容易理解和擴展、更容易演進的長久發展的軟件。編程即是設計,從具象到抽象再到具象的過程。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/74753.html

相關文章

  • Python語言中計數方法演變

    摘要:譯文鏈接編程派有時候,利用語言簡潔優雅地解決問題的方法,會隨著時間變化。隨著不斷進化,統計列表元素數量的方法也在改變。最后將字典中相應鍵的值設置為新的計數。我們發現這種方法比之前的代碼更加簡潔優雅,所以提交了此次修改。 showImg(https://segmentfault.com/img/remote/1460000010723715); 文中如對專業術語的翻譯有誤,請Pytho...

    sunsmell 評論0 收藏0
  • Hooks + Context:狀態管理新選擇

    摘要:用戶點擊改變全局狀態崔然渲染整顆組件樹有沒有解決方案呢當然有創建一個只接收的新組件,并將組件中的邏輯都移到組件中。最終的示例使用全局狀態和生成全局狀態和崔然完整示例見結論在和出現之前,缺乏自帶的全局狀態管理能力。 React 16.3 版本,正式推了出官方推薦的 context API —— 一種跨層級的數據傳遞方法。React 16.8 版本,推出了全新的 hooks 功能,將原本只...

    tommego 評論0 收藏0
  • 響應設計個人一些總結

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

    LeoHsiun 評論0 收藏0
  • 重構 - 改善代碼各方面問題

    摘要:暴露接口如果是函數,就擴展,否則就是驗證數據使用金額校驗規則這樣運行能正常,也有擴展性性,但是對于代碼潔癖的來說,這樣寫法不優雅。 重構不是對以前代碼的全盤否定,而是利用更好的方式,寫出更好,更有維護性代碼。不斷的追求與學習,才有更多的進步。 1.前言 做前端開發有一段時間了,在這段時間里面,對于自己的要求,不僅僅是項目能完成,功能正常使用這一層面上。還盡力的研究怎么寫出優雅的代碼,性...

    AlphaWallet 評論0 收藏0

發表評論

0條評論

bergwhite

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<