<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          面試官:項(xiàng)目中你是如何利用設(shè)計(jì)模式,干掉if-else的

          共 12910字,需瀏覽 26分鐘

           ·

          2021-11-18 10:40

          前言

          物流行業(yè)中,通常會(huì)涉及到EDI報(bào)文(XML格式文件)傳輸和回執(zhí)接收,每發(fā)送一份EDI報(bào)文,后續(xù)都會(huì)收到與之關(guān)聯(lián)的回執(zhí)(標(biāo)識(shí)該數(shù)據(jù)在第三方系統(tǒng)中的流轉(zhuǎn)狀態(tài))。

          這里枚舉幾種回執(zhí)類型:MT1101、MT2101、MT4101、MT8104、MT8105、MT9999,系統(tǒng)在收到不同的回執(zhí)報(bào)文后,會(huì)執(zhí)行對(duì)應(yīng)的業(yè)務(wù)邏輯處理。當(dāng)然,實(shí)際業(yè)務(wù)場(chǎng)景并沒有那么籠統(tǒng),這里以回執(zhí)處理為演示案例

          模擬一個(gè)回執(zhí)類

          @Data
          public?class?Receipt?{

          ????/**
          ?????*?回執(zhí)信息
          ?????*/

          ????String?message;

          ????/**
          ?????*?回執(zhí)類型(`MT1101、MT2101、MT4101、MT8104、MT8105、MT9999`)
          ?????*/

          ????String?type;

          }

          模擬一個(gè)回執(zhí)生成器

          public?class?ReceiptBuilder?{

          ????public?static?List?generateReceiptList(){
          ????????//直接模擬一堆回執(zhí)對(duì)象
          ????????List?receiptList?=?new?ArrayList<>();
          ????????receiptList.add(new?Receipt("我是MT2101回執(zhí)喔","MT2101"));
          ????????receiptList.add(new?Receipt("我是MT1101回執(zhí)喔","MT1101"));
          ????????receiptList.add(new?Receipt("我是MT8104回執(zhí)喔","MT8104"));
          ????????receiptList.add(new?Receipt("我是MT9999回執(zhí)喔","MT9999"));
          ????????//......?
          ????????return?receiptList;
          ????}
          }

          傳統(tǒng)做法-if-else分支

          List?receiptList?=?ReceiptBuilder.generateReceiptList();
          //循環(huán)處理
          for?(Receipt?receipt?:?receiptList)?{
          ????if?(StringUtils.equals("MT2101",receipt.getType()))?{
          ????????System.out.println("接收到MT2101回執(zhí)");
          ????????System.out.println("解析回執(zhí)內(nèi)容");
          ????????System.out.println("執(zhí)行業(yè)務(wù)邏輯");
          ????}?else?if?(StringUtils.equals("MT1101",receipt.getType()))?{
          ????????System.out.println("接收到MT1101回執(zhí)");
          ????????System.out.println("解析回執(zhí)內(nèi)容");
          ????????System.out.println("執(zhí)行業(yè)務(wù)邏輯");
          ????}?else?if?(StringUtils.equals("MT8104",receipt.getType()))?{
          ????????System.out.println("接收到MT8104回執(zhí)");
          ????????System.out.println("解析回執(zhí)內(nèi)容");
          ????????System.out.println("執(zhí)行業(yè)務(wù)邏輯");
          ????}?else?if?(StringUtils.equals("MT9999",receipt.getType()))?{
          ????????System.out.println("接收到MT9999回執(zhí)");
          ????????System.out.println("解析回執(zhí)內(nèi)容");
          ????????System.out.println("執(zhí)行業(yè)務(wù)邏輯");
          ????????System.out.println("推送郵件");
          ????}
          ????//?......未來可能還有好多個(gè)else?if
          }

          在遇到if-else的分支業(yè)務(wù)邏輯比較復(fù)雜時(shí),我們都習(xí)慣于將其抽出一個(gè)方法或者封裝成一個(gè)對(duì)象去調(diào)用,這樣整個(gè)if-else結(jié)構(gòu)就不會(huì)顯得太臃腫。就上面例子,當(dāng)回執(zhí)的類型越來越多時(shí),分支else if 就會(huì)越來越多,每增加一個(gè)回執(zhí)類型,就需要修改或添加if-else分支,違反了開閉原則(對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉)

          策略模式+Map字典

          我們知道, 策略模式的目的是封裝一系列的算法,它們具有共性,可以相互替換,也就是說讓算法獨(dú)立于使用它的客戶端而獨(dú)立變化,客戶端僅僅依賴于策略接口 。在上述場(chǎng)景中,我們可以把if-else分支的業(yè)務(wù)邏輯抽取為各種策略,但是不可避免的是依然需要客戶端寫一些if-else進(jìn)行策略選擇的邏輯,我們可以將這段邏輯抽取到工廠類中去,這就是策略模式+簡(jiǎn)單工廠,代碼如下

          策略接口

          /**
          ?*?@Description:?回執(zhí)處理策略接口
          ?*?@Auther:?wuzhazha
          ?*/

          public?interface?IReceiptHandleStrategy?{

          ????void?handleReceipt(Receipt?receipt);

          }

          策略接口實(shí)現(xiàn)類,也就是具體的處理者

          public?class?Mt2101ReceiptHandleStrategy?implements?IReceiptHandleStrategy?{

          ????@Override
          ????public?void?handleReceipt(Receipt?receipt)?{
          ????????System.out.println("解析報(bào)文MT2101:"?+?receipt.getMessage());
          ????}

          }

          public?class?Mt1101ReceiptHandleStrategy?implements?IReceiptHandleStrategy?{

          ????@Override
          ????public?void?handleReceipt(Receipt?receipt)?{
          ????????System.out.println("解析報(bào)文MT1101:"?+?receipt.getMessage());
          ????}

          }

          public?class?Mt8104ReceiptHandleStrategy?implements?IReceiptHandleStrategy?{

          ????@Override
          ????public?void?handleReceipt(Receipt?receipt)?{
          ????????System.out.println("解析報(bào)文MT8104:"?+?receipt.getMessage());
          ????}

          }

          public?class?Mt9999ReceiptHandleStrategy?implements?IReceiptHandleStrategy?{

          ????@Override
          ????public?void?handleReceipt(Receipt?receipt)?{
          ????????System.out.println("解析報(bào)文MT9999:"?+?receipt.getMessage());
          ????}

          }

          策略上下文類(策略接口的持有者)

          /**
          ?*?@Description:?上下文類,持有策略接口
          ?*?@Auther:?wuzhazha
          ?*/

          public?class?ReceiptStrategyContext?{

          ????private?IReceiptHandleStrategy?receiptHandleStrategy;

          ????/**
          ?????*?設(shè)置策略接口
          ?????*?@param?receiptHandleStrategy
          ?????*/

          ????public?void?setReceiptHandleStrategy(IReceiptHandleStrategy?receiptHandleStrategy)?{
          ????????this.receiptHandleStrategy?=?receiptHandleStrategy;
          ????}

          ????public?void?handleReceipt(Receipt?receipt){
          ????????if?(receiptHandleStrategy?!=?null)?{
          ??????????receiptHandleStrategy.handleReceipt(receipt);???
          ????????}
          ????}
          }

          策略工廠

          /**
          ?*?@Description:?策略工廠
          ?*?@Auther:?wuzhazha
          ?*/

          public?class?ReceiptHandleStrategyFactory?{

          ????private?ReceiptHandleStrategyFactory(){}

          ????public?static?IReceiptHandleStrategy?getReceiptHandleStrategy(String?receiptType){
          ????????IReceiptHandleStrategy?receiptHandleStrategy?=?null;
          ????????if?(StringUtils.equals("MT2101",receiptType))?{
          ????????????receiptHandleStrategy?=?new?Mt2101ReceiptHandleStrategy();
          ????????}?else?if?(StringUtils.equals("MT8104",receiptType))?{
          ????????????receiptHandleStrategy?=?new?Mt8104ReceiptHandleStrategy();
          ????????}
          ????????return?receiptHandleStrategy;
          ????}
          }

          客戶端

          public?class?Client?{

          ????public?static?void?main(String[]?args)?{
          ????????//模擬回執(zhí)
          ????????List?receiptList?=?ReceiptBuilder.generateReceiptList();
          ????????//策略上下文
          ????????ReceiptStrategyContext?receiptStrategyContext?=?new?ReceiptStrategyContext();
          ????????for?(Receipt?receipt?:?receiptList)?{
          ????????????//獲取并設(shè)置策略
          ????????????IReceiptHandleStrategy?receiptHandleStrategy?=?ReceiptHandleStrategyFactory.getReceiptHandleStrategy(receipt.getType());
          ????????????receiptStrategyContext.setReceiptHandleStrategy(receiptHandleStrategy);
          ????????????//執(zhí)行策略
          ????????????receiptStrategyContext.handleReceipt(receipt);
          ????????}
          ????}
          }

          解析報(bào)文MT2101:我是MT2101回執(zhí)報(bào)文喔

          解析報(bào)文MT8104:我是MT8104回執(zhí)報(bào)文喔

          由于我們的目的是消除if-else,那么這里需要將ReceiptHandleStrategyFactory策略工廠進(jìn)行改造下,采用字典的方式存放我的策略,而Map具備key-value結(jié)構(gòu),采用Map是個(gè)不錯(cuò)選擇。稍微改造下,代碼如下

          /**
          ?*?@Description:?策略工廠
          ?*?@Auther:?wuzhazha
          ?*/

          public?class?ReceiptHandleStrategyFactory?{

          ????private?static?Map?receiptHandleStrategyMap;

          ????private?ReceiptHandleStrategyFactory(){
          ????????this.receiptHandleStrategyMap?=?new?HashMap<>();
          ????????this.receiptHandleStrategyMap.put("MT2101",new?Mt2101ReceiptHandleStrategy());
          ????????this.receiptHandleStrategyMap.put("MT8104",new?Mt8104ReceiptHandleStrategy());
          ????}

          ????public?static?IReceiptHandleStrategy?getReceiptHandleStrategy(String?receiptType){
          ????????return?receiptHandleStrategyMap.get(receiptType);
          ????}
          }

          經(jīng)過對(duì)策略模式+簡(jiǎn)單工廠方案的改造,我們已經(jīng)消除了if-else的結(jié)構(gòu),每當(dāng)新來了一種回執(zhí),只需要添加新的回執(zhí)處理策略,并修改ReceiptHandleStrategyFactory中的Map集合。如果要使得程序符合開閉原則,則需要調(diào)整ReceiptHandleStrategyFactory中處理策略的獲取方式,通過反射的方式,獲取指定包下的所有IReceiptHandleStrategy實(shí)現(xiàn)類,然后放到字典Map中去。學(xué)習(xí)資料:Java進(jìn)階視頻資源

          責(zé)任鏈模式

          責(zé)任鏈模式是一種對(duì)象的行為模式。在責(zé)任鏈模式里,很多對(duì)象由每一個(gè)對(duì)象對(duì)其下家的引用而連接起來形成一條鏈。請(qǐng)求在這個(gè)鏈上傳遞,直到鏈上的某一個(gè)對(duì)象決定處理此請(qǐng)求。發(fā)出這個(gè)請(qǐng)求的客戶端并不知道鏈上的哪一個(gè)對(duì)象最終處理這個(gè)請(qǐng)求,這使得系統(tǒng)可以在不影響客戶端的情況下動(dòng)態(tài)地重新組織和分配責(zé)任

          回執(zhí)處理者接口

          /**
          ?*?@Description:?抽象回執(zhí)處理者接口
          ?*?@Auther:?wuzhazha
          ?*/

          public?interface?IReceiptHandler?{

          ????void?handleReceipt(Receipt?receipt,IReceiptHandleChain?handleChain);

          }

          責(zé)任鏈接口

          /**
          ?*?@Description:?責(zé)任鏈接口
          ?*?@Auther:?wuzhazha
          ?*/

          public?interface?IReceiptHandleChain?{

          ????void?handleReceipt(Receipt?receipt);
          }

          責(zé)任鏈接口實(shí)現(xiàn)類

          /**
          ?*?@Description:?責(zé)任鏈實(shí)現(xiàn)類
          ?*?@Auther:?wuzhazha
          ?*/

          public?class?ReceiptHandleChain?implements?IReceiptHandleChain?{
          ?//記錄當(dāng)前處理者位置
          ????private?int?index?=?0;
          ????//處理者集合
          ????private?static?List?receiptHandlerList;

          ????static?{
          ????????//從容器中獲取處理器對(duì)象
          ????????receiptHandlerList?=?ReceiptHandlerContainer.getReceiptHandlerList();
          ????}

          ????@Override
          ????public?void?handleReceipt(Receipt?receipt)?{
          ????????if?(receiptHandlerList?!=null?&&?receiptHandlerList.size()?>?0)?{
          ????????????if?(index?!=?receiptHandlerList.size())?{
          ????????????????IReceiptHandler?receiptHandler?=?receiptHandlerList.get(index++);
          ????????????????receiptHandler.handleReceipt(receipt,this);
          ????????????}
          ????????}
          ????}
          }

          具體回執(zhí)處理者

          public?class?Mt2101ReceiptHandler?implements?IReceiptHandler?{

          ????@Override
          ????public?void?handleReceipt(Receipt?receipt,?IReceiptHandleChain?handleChain)?{
          ????????if?(StringUtils.equals("MT2101",receipt.getType()))?{
          ????????????System.out.println("解析報(bào)文MT2101:"?+?receipt.getMessage());
          ????????}?
          ????????//處理不了該回執(zhí)就往下傳遞
          ????????else?{??????????
          ????????????handleChain.handleReceipt(receipt);
          ????????}
          ????}
          }

          public?class?Mt8104ReceiptHandler?implements?IReceiptHandler?{

          ????@Override
          ????public?void?handleReceipt(Receipt?receipt,?IReceiptHandleChain?handleChain)?{
          ????????if?(StringUtils.equals("MT8104",receipt.getType()))?{
          ????????????System.out.println("解析報(bào)文MT8104:"?+?receipt.getMessage());
          ????????}
          ????????//處理不了該回執(zhí)就往下傳遞
          ????????else?{
          ????????????handleChain.handleReceipt(receipt);
          ????????}
          ????}
          }

          責(zé)任鏈處理者容器(如果采用spring,則可以通過依賴注入的方式獲取到IReceiptHandler的子類對(duì)象)

          /**
          ?*?@Description:?處理者容器
          ?*?@Auther:?wuzhazha
          ?*/

          public?class?ReceiptHandlerContainer?{

          ????private?ReceiptHandlerContainer(){}

          ????public?static?List?getReceiptHandlerList(){
          ????????List?receiptHandlerList?=?new?ArrayList<>();
          ????????receiptHandlerList.add(new?Mt2101ReceiptHandler());
          ????????receiptHandlerList.add(new?Mt8104ReceiptHandler());
          ????????return?receiptHandlerList;
          ????}

          }

          客戶端

          public?class?Client?{

          ????public?static?void?main(String[]?args)?{
          ????????//模擬回執(zhí)
          ????????List?receiptList?=?ReceiptBuilder.generateReceiptList();
          ????????for?(Receipt?receipt?:?receiptList)?{
          ????????????//回執(zhí)處理鏈對(duì)象
          ????????????ReceiptHandleChain?receiptHandleChain?=?new?ReceiptHandleChain();
          ????????????receiptHandleChain.handleReceipt(receipt);
          ????????}
          ????}
          }

          解析報(bào)文MT2101:我是MT2101回執(zhí)報(bào)文喔

          解析報(bào)文MT8104:我是MT8104回執(zhí)報(bào)文喔

          通過責(zé)任鏈的處理方式,if-else結(jié)構(gòu)也被我們消除了,每當(dāng)新來了一種回執(zhí),只需要添加IReceiptHandler實(shí)現(xiàn)類并修改ReceiptHandlerContainer處理者容器即可,如果要使得程序符合開閉原則,則需要調(diào)整ReceiptHandlerContainer中處理者的獲取方式,通過反射的方式,獲取指定包下的所有IReceiptHandler實(shí)現(xiàn)類。學(xué)習(xí)資料:Java進(jìn)階視頻資源

          這里使用到了一個(gè)反射工具類,用于獲取指定接口的所有實(shí)現(xiàn)類

          /**
          ?*?@Description:?反射工具類
          ?*?@Auther:?wuzhazha
          ?*/

          public?class?ReflectionUtil?{
          ????
          ????/**
          ?????*?定義類集合(用于存放所有加載的類)
          ?????*/

          ????private?static?final?Set>?CLASS_SET;

          ????static?{
          ????????//指定加載包路徑
          ????????CLASS_SET?=?getClassSet("com.yaolong");
          ????}
          ????
          ????/**
          ?????*?獲取類加載器
          ?????*?@return
          ?????*/

          ????public?static?ClassLoader?getClassLoader(){
          ????????return?Thread.currentThread().getContextClassLoader();
          ????}

          ????/**
          ?????*?加載類
          ?????*?@param?className?類全限定名稱
          ?????*?@param?isInitialized?是否在加載完成后執(zhí)行靜態(tài)代碼塊
          ?????*?@return
          ?????*/

          ????public?static?Class?loadClass(String?className,boolean?isInitialized)?{
          ????????Class?cls;
          ????????try?{
          ????????????cls?=?Class.forName(className,isInitialized,getClassLoader());
          ????????}?catch?(ClassNotFoundException?e)?{
          ????????????throw?new?RuntimeException(e);
          ????????}
          ????????return?cls;
          ????}

          ????public?static?Class?loadClass(String?className)?{
          ????????return?loadClass(className,true);
          ????}

          ????/**
          ?????*?獲取指定包下所有類
          ?????*?@param?packageName
          ?????*?@return
          ?????*/

          ????public?static?Set>?getClassSet(String?packageName)?{
          ????????Set>?classSet?=?new?HashSet<>();
          ????????try?{
          ????????????Enumeration?urls?=?getClassLoader().getResources(packageName.replace(".","/"));
          ????????????while?(urls.hasMoreElements())?{
          ????????????????URL?url?=?urls.nextElement();
          ????????????????if?(url?!=?null)?{
          ????????????????????String?protocol?=?url.getProtocol();
          ????????????????????if?(protocol.equals("file"))?{
          ????????????????????????String?packagePath?=?url.getPath().replace("%20","");
          ????????????????????????addClass(classSet,packagePath,packageName);
          ????????????????????}?else?if?(protocol.equals("jar"))?{
          ????????????????????????JarURLConnection?jarURLConnection?=?(JarURLConnection)?url.openConnection();
          ????????????????????????if?(jarURLConnection?!=?null)?{
          ????????????????????????????JarFile?jarFile?=?jarURLConnection.getJarFile();
          ????????????????????????????if?(jarFile?!=?null)?{
          ????????????????????????????????Enumeration?jarEntries?=?jarFile.entries();
          ????????????????????????????????while?(jarEntries.hasMoreElements())?{
          ????????????????????????????????????JarEntry?jarEntry?=?jarEntries.nextElement();
          ????????????????????????????????????String?jarEntryName?=?jarEntry.getName();
          ????????????????????????????????????if?(jarEntryName.endsWith(".class"))?{
          ????????????????????????????????????????String?className?=?jarEntryName.substring(0,?jarEntryName.lastIndexOf(".")).replaceAll("/",?".");
          ????????????????????????????????????????doAddClass(classSet,className);
          ????????????????????????????????????}
          ????????????????????????????????}
          ????????????????????????????}
          ????????????????????????}
          ????????????????????}
          ????????????????}
          ????????????}


          ????????}?catch?(IOException?e)?{
          ????????????throw?new?RuntimeException(e);
          ????????}
          ????????return?classSet;
          ????}

          ????private?static?void?doAddClass(Set>?classSet,?String?className)?{
          ????????Class?cls?=?loadClass(className,false);
          ????????classSet.add(cls);
          ????}

          ????private?static?void?addClass(Set>?classSet,?String?packagePath,?String?packageName)?{
          ????????final?File[]?files?=?new?File(packagePath).listFiles(new?FileFilter()?{
          ????????????@Override
          ????????????public?boolean?accept(File?file)?{
          ????????????????return?(file.isFile()?&&?file.getName().endsWith(".class"))?||?file.isDirectory();
          ????????????}
          ????????});
          ????????for?(File?file?:?files)?{
          ????????????String?fileName?=?file.getName();
          ????????????if?(file.isFile())?{
          ????????????????String?className?=?fileName.substring(0,?fileName.lastIndexOf("."));
          ????????????????if?(StringUtils.isNotEmpty(packageName))?{
          ????????????????????className?=?packageName?+?"."?+?className;
          ????????????????}
          ????????????????doAddClass(classSet,className);
          ????????????}?else?{
          ????????????????String?subPackagePath?=?fileName;
          ????????????????if?(StringUtils.isNotEmpty(packagePath))?{
          ????????????????????subPackagePath?=?packagePath?+?"/"?+?subPackagePath;
          ????????????????}
          ????????????????String?subPackageName?=?fileName;
          ????????????????if?(StringUtils.isNotEmpty(packageName))?{
          ????????????????????subPackageName?=?packageName?+?"."?+?subPackageName;
          ????????????????}
          ????????????????addClass(classSet,subPackagePath,subPackageName);
          ????????????}
          ????????}
          ????}


          ????public?static?Set>?getClassSet()?{
          ????????return?CLASS_SET;
          ????}

          ????/**
          ?????*?獲取應(yīng)用包名下某父類(或接口)的所有子類(或?qū)崿F(xiàn)類)
          ?????*?@param?superClass
          ?????*?@return
          ?????*/

          ????public?static?Set>?getClassSetBySuper(Class?superClass)?{
          ????????Set>?classSet?=?new?HashSet<>();
          ????????for?(Class?cls?:?CLASS_SET)?{
          ????????????if?(superClass.isAssignableFrom(cls)?&&?!superClass.equals(cls))?{
          ????????????????classSet.add(cls);
          ????????????}
          ????????}
          ????????return?classSet;
          ????}

          ????/**
          ?????*?獲取應(yīng)用包名下帶有某注解的類
          ?????*?@param?annotationClass
          ?????*?@return
          ?????*/

          ????public?static?Set>?getClassSetByAnnotation(Class?annotationClass)?{
          ????????Set>?classSet?=?new?HashSet<>();
          ????????for?(Class?cls?:?CLASS_SET)?{
          ????????????if?(cls.isAnnotationPresent(annotationClass))?{
          ????????????????classSet.add(cls);
          ????????????}
          ????????}
          ????????return?classSet;
          ????}

          }

          接下來改造ReceiptHandlerContainer

          public?class?ReceiptHandlerContainer?{

          ????private?ReceiptHandlerContainer(){}

          ????public?static?List?getReceiptHandlerList(){
          ????????List?receiptHandlerList?=?new?ArrayList<>();
          ????????//獲取IReceiptHandler接口的實(shí)現(xiàn)類
          ????????Set>?classList?=?ReflectionUtil.getClassSetBySuper(IReceiptHandler.class);
          ????????if?(classList?!=?null?&&?classList.size()?>?0)?{
          ????????????for?(Class?clazz?:?classList)?{
          ????????????????try?{
          ????????????????????receiptHandlerList.add((IReceiptHandler)clazz.newInstance());
          ????????????????}?catch?(?Exception?e)?{
          ????????????????????e.printStackTrace();
          ????????????????}
          ????????????}
          ????????}
          ????????return?receiptHandlerList;
          ????}

          }

          至此,該方案完美符合了開閉原則,如果新增一個(gè)回執(zhí)類型,只需要添加一個(gè)新的回執(zhí)處理器即可,無需做其它改動(dòng)。如新加了MT6666的回執(zhí),代碼如下

          public?class?Mt6666ReceiptHandler?implements?IReceiptHandler?{

          ????@Override
          ????public?void?handleReceipt(Receipt?receipt,?IReceiptHandleChain?handleChain)?{
          ????????if?(StringUtils.equals("MT6666",receipt.getType()))?{
          ????????????System.out.println("解析報(bào)文MT6666:"?+?receipt.getMessage());
          ????????}
          ????????//處理不了該回執(zhí)就往下傳遞
          ????????else?{
          ????????????handleChain.handleReceipt(receipt);
          ????????}
          ????}
          }

          策略模式+注解

          此方案其實(shí)和上述沒有太大異同,為了能符合開閉原則,通過自定義注解的方式,標(biāo)記處理者類,然后反射獲取到該類集合,放到Map容器中,這里不再贅述

          小結(jié)

          if-else或switch case 這種分支判斷的方式對(duì)于分支邏輯不多的簡(jiǎn)單業(yè)務(wù),還是直觀高效的。對(duì)于業(yè)務(wù)復(fù)雜,分支邏輯多,采用適當(dāng)?shù)哪J郊记桑瑫?huì)讓代碼更加清晰,容易維護(hù),但同時(shí)類或方法數(shù)量也是倍增的。我們需要對(duì)業(yè)務(wù)做好充分分析,避免一上來就設(shè)計(jì)模式,避免過度設(shè)計(jì)!

          來源:cnblogs.com/DiDi516/p/11787257.html

          程序汪資料鏈接

          程序汪接的7個(gè)私活都在這里,經(jīng)驗(yàn)整理

          Java項(xiàng)目分享 最新整理全集,找項(xiàng)目不累啦 06版

          堪稱神級(jí)的Spring Boot手冊(cè),從基礎(chǔ)入門到實(shí)戰(zhàn)進(jìn)階

          臥槽!字節(jié)跳動(dòng)《算法中文手冊(cè)》火了,完整版 PDF 開放下載!

          臥槽!阿里大佬總結(jié)的《圖解Java》火了,完整版PDF開放下載!

          字節(jié)跳動(dòng)總結(jié)的設(shè)計(jì)模式 PDF 火了,完整版開放下載!


          歡迎添加程序汪個(gè)人微信 itwang009? 進(jìn)粉絲群或圍觀朋友圈

          瀏覽 53
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日韩性AV| 欧美性爱豆花在线视频 | 亚洲天堂一区二区 | 亚洲中文州字幕不卡在线 | 色色婷婷五月 |