1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        來吧,用設(shè)計(jì)模式來干掉 if-else 啊~

        共 15189字,需瀏覽 31分鐘

         ·

        2020-11-18 21:51

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

        • 前言
        • 傳統(tǒng)做法-if-else分支
        • 策略模式+Map字典
        • 責(zé)任鏈模式
        • 策略模式+注解
        • 小結(jié)

        前言

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

        這里枚舉幾種回執(zhí)類型:MT1101、MT2101、MT4101、MT8104、MT8105、MT9999,系統(tǒng)在收到不同的回執(zhí)報(bào)文后,會執(zhí)行對應(yīng)的業(yè)務(wù)邏輯處理。當(dāng)然,實(shí)際業(yè)務(wù)場景并沒有那么籠統(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í)對象
        ????????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è)對象去調(diào)用,這樣整個(gè)if-else結(jié)構(gòu)就不會顯得太臃腫。

        就上面例子,當(dāng)回執(zhí)的類型越來越多時(shí),分支else if 就會越來越多,每增加一個(gè)回執(zhí)類型,就需要修改或添加if-else分支,違反了開閉原則(對擴(kuò)展開放,對修改關(guān)閉)

        策略模式+Map字典

        我們知道, 策略模式的目的是封裝一系列的算法,它們具有共性,可以相互替換,也就是說讓算法獨(dú)立于使用它的客戶端而獨(dú)立變化,客戶端僅僅依賴于策略接口 。

        在上述場景中,我們可以把if-else分支的業(yè)務(wù)邏輯抽取為各種策略,但是不可避免的是依然需要客戶端寫一些if-else進(jì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)過對策略模式+簡單工廠方案的改造,我們已經(jīng)消除了if-else的結(jié)構(gòu),每當(dāng)新來了一種回執(zhí),只需要添加新的回執(zhí)處理策略,并修改ReceiptHandleStrategyFactory中的Map集合。

        如果要使得程序符合開閉原則,則需要調(diào)整ReceiptHandleStrategyFactory中處理策略的獲取方式,通過反射的方式,獲取指定包下的所有IReceiptHandleStrategy實(shí)現(xiàn)類,然后放到字典Map中去。

        責(zé)任鏈模式

        責(zé)任鏈模式是一種對象的行為模式。在責(zé)任鏈模式里,很多對象由每一個(gè)對象對其下家的引用而連接起來形成一條鏈。請求在這個(gè)鏈上傳遞,直到鏈上的某一個(gè)對象決定處理此請求。

        發(fā)出這個(gè)請求的客戶端并不知道鏈上的哪一個(gè)對象最終處理這個(gè)請求,這使得系統(tǒ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?{
        ????????//從容器中獲取處理器對象
        ????????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的子類對象)

        /**
        ?*?@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í)處理鏈對象
        ????????????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)類。

        這里使用到了一個(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í)處理器即可,無需做其它改動。如新加了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 這種分支判斷的方式對于分支邏輯不多的簡單業(yè)務(wù),還是直觀高效的。對于業(yè)務(wù)復(fù)雜,分支邏輯多,采用適當(dāng)?shù)哪J郊记?,會讓代碼更加清晰,容易維護(hù),但同時(shí)類或方法數(shù)量也是倍增的。我們需要對業(yè)務(wù)做好充分分析,避免一上來就設(shè)計(jì)模式,避免過度設(shè)計(jì)!

        瀏覽 38
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

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

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            欧美日韩在线视频观看 | 天天撸成人AV一级电影 | 啊~我是sao货快cao我 三上悠亚精品二区 | 富婆一级婬片A片AAA毛片91 | 国产人妻无码一区二区三区不卡 | 色呦色呦色精品 | 欧美粉嫩metart69hd 毛片无遮挡高清免费观看 欧美激情一级片 | 人人摸人人操人人干 | 国产乡下妇女做爰电影院 | 天海翼毛片 |