精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

干掉if...else,這幾種寫法更優雅!

開發 前端
最近在做代碼重構,發現了很多代碼的爛味道。其他的不多說,今天主要說說那些又臭又長的if...else要如何重構。在介紹更更優雅的編程之前,讓我們一起回顧一下,不好的if...else代碼。

前言

最近在做代碼重構,發現了很多代碼的爛味道。其他的不多說,今天主要說說那些又臭又長的if...else要如何重構。

在介紹更更優雅的編程之前,讓我們一起回顧一下,不好的if...else代碼

一、又臭又長的if...else

廢話不多說,先看看下面的代碼。

public interface IPay {  
    void pay();  
}  

@Service
publicclass AliaPay implements IPay {  
     @Override
     public void pay() {  
        System.out.println("===發起支付寶支付===");  
     }  
}  

@Service
publicclass WeixinPay implements IPay {  
     @Override
     public void pay() {  
         System.out.println("===發起微信支付===");  
     }  
}  

@Service
publicclass JingDongPay implements IPay {  
     @Override
     public void pay() {  
        System.out.println("===發起京東支付===");  
     }  
}  

@Service
publicclass PayService {  
     @Autowired
     private AliaPay aliaPay;  
     @Autowired
     private WeixinPay weixinPay;  
     @Autowired
     private JingDongPay jingDongPay;  
    
   
     public void toPay(String code) {  
         if ("alia".equals(code)) {  
             aliaPay.pay();  
         } elseif ("weixin".equals(code)) {  
              weixinPay.pay();  
         } elseif ("jingdong".equals(code)) {  
              jingDongPay.pay();  
         } else {  
              System.out.println("找不到支付方式");  
         }  
     }  
}

PayService類的toPay方法主要是為了發起支付,根據不同的code,決定調用用不同的支付類(比如:aliaPay)的pay方法進行支付。

這段代碼有什么問題呢?也許有些人就是這么干的。

試想一下,如果支付方式越來越多,比如:又加了百度支付、美團支付、銀聯支付等等,就需要改toPay方法的代碼,增加新的else...if判斷,判斷多了就會導致邏輯越來越多?

很明顯,這里違法了設計模式六大原則的:開閉原則 和 單一職責原則。

開閉原則:對擴展開放,對修改關閉。就是說增加新功能要盡量少改動已有代碼。


單一職責原則:顧名思義,要求邏輯盡量單一,不要太復雜,便于復用。

那有什么辦法可以解決這個問題呢?

二、消除if...else的錦囊妙計

1、使用注解

代碼中之所以要用code判斷使用哪個支付類,是因為code和支付類沒有一個綁定關系,如果綁定關系存在了,就可以不用判斷了。

我們先定義一個注解。

@Retention(RetentionPolicy.RUNTIME)  
@Target(ElementType.TYPE)  
public @interface PayCode {  

     String value();    
     String name();  
}

在所有的支付類上都加上該注解:

@PayCode(value = "alia", name = "支付寶支付")  
@Service
publicclass AliaPay implements IPay {  

     @Override
     public void pay() {  
         System.out.println("===發起支付寶支付===");  
     }  
}  


@PayCode(value = "weixin", name = "微信支付")  
@Service
publicclass WeixinPay implements IPay {  

     @Override
     public void pay() {  
         System.out.println("===發起微信支付===");  
     }  
} 


@PayCode(value = "jingdong", name = "京東支付")  
@Service
publicclass JingDongPay implements IPay {  

     @Override
     public void pay() {  
        System.out.println("===發起京東支付===");  
     }  
}

然后增加最關鍵的類:

@Service
publicclass PayService2 implements ApplicationListener<ContextRefreshedEvent> {  

     privatestatic Map<String, IPay> payMap = null;  
     
     @Override
     public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {  
         ApplicationContext applicationContext = contextRefreshedEvent.getApplicationContext();  
         Map<String, Object> beansWithAnnotation = applicationContext.getBeansWithAnnotation(PayCode.class);  
        
         if (beansWithAnnotation != null) {  
             payMap = new HashMap<>();  
             beansWithAnnotation.forEach((key, value) ->{  
                 String bizType = value.getClass().getAnnotation(PayCode.class).value();  
                 payMap.put(bizType, (IPay) value);  
             });  
         }  
     }  
    
     public void pay(String code) {  
        payMap.get(code).pay();  
     }  
}

PayService2類實現了ApplicationListener接口,這樣在onApplicationEvent方法中,就可以拿到ApplicationContext的實例。

我們再獲取打了PayCode注解的類,放到一個map中,map中的key就是PayCode注解中定義的value,跟code參數一致,value是支付類的實例。

這樣,每次就可以每次直接通過code獲取支付類實例,而不用if...else判斷了。

如果要加新的支付方法,只需在支付類上面打上PayCode注解定義一個新的code即可。

注意:這種方式的code可以沒有業務含義,可以是純數字,只有不重復就行。

2、動態拼接名稱

該方法主要針對code是有業務含義的場景。

@Service
publicclass PayService3 implements ApplicationContextAware {   
     private ApplicationContext applicationContext;  
     privatestaticfinal String SUFFIX = "Pay";  

     @Override
     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {  
        this.applicationContext = applicationContext;  
     }  

     public void toPay(String payCode) {  
         ((IPay) applicationContext.getBean(getBeanName(payCode))).pay();  
     }  

     public String getBeanName(String payCode) {  
         return payCode + SUFFIX;  
     }  
}

我們可以看到,支付類bean的名稱是由code和后綴拼接而成,比如:aliaPay、weixinPay和jingDongPay。

這就要求支付類取名的時候要特別注意,前面的一段要和code保持一致。

調用的支付類的實例是直接從ApplicationContext實例中獲取的,默認情況下bean是單例的,放在內存的一個map中,所以不會有性能問題。

特別說明一下,這種方法實現了ApplicationContextAware接口跟上面的ApplicationListener接口不一樣,是想告訴大家獲取ApplicationContext實例的方法不只一種。

3、模板方法判斷

當然除了上面介紹的兩種方法之外,spring的源碼實現中也告訴我們另外一種思路,解決if...else問題。

我們先一起看看spring AOP的部分源碼,看一下DefaultAdvisorAdapterRegistry的wrap方法:

public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {  
     if (adviceObject instanceof Advisor) {  
        return (Advisor) adviceObject;  
     }  
     if (!(adviceObject instanceof Advice)) {  
        thrownew UnknownAdviceTypeException(adviceObject);  
     }  
     Advice advice = (Advice) adviceObject;  
     if (advice instanceof MethodInterceptor) {    
        returnnew DefaultPointcutAdvisor(advice);  
     }  
     for (AdvisorAdapter adapter : this.adapters) {  
         if (adapter.supportsAdvice(advice)) {  
             returnnew DefaultPointcutAdvisor(advice);  
         }  
     }  
     thrownew UnknownAdviceTypeException(advice);  
 }

重點看看supportAdvice方法,有三個類實現了這個方法。我們隨便抽一個類看看

class AfterReturningAdviceAdapter implements AdvisorAdapter, Serializable {  

     @Override
     public boolean supportsAdvice(Advice advice) {  
        return (advice instanceof AfterReturningAdvice);  
     }  

     @Override
     public MethodInterceptor getInterceptor(Advisor advisor) {  
        AfterReturningAdvice advice = (AfterReturningAdvice) advisor.getAdvice();  
        returnnew AfterReturningAdviceInterceptor(advice);  
     }   
}

該類的supportsAdvice方法非常簡單,只是判斷了一下advice的類型是不是AfterReturningAdvice。

我們看到這里應該有所啟發。

其實,我們可以這樣做,定義一個接口或者抽象類,里面有個support方法判斷參數傳的code是否自己可以處理,如果可以處理則走支付邏輯。

public interface IPay {  
     boolean support(String code);   
     void pay();  
}  

@Service
publicclass AliaPay implements IPay {   
     @Override
     public boolean support(String code) {  
        return"alia".equals(code);  
     }  

     @Override
     public void pay() {  
        System.out.println("===發起支付寶支付===");  
     }  
}  

@Service
publicclass WeixinPay implements IPay {  

     @Override
     public boolean support(String code) {  
        return"weixin".equals(code);  
     }  

     @Override
     public void pay() {  
        System.out.println("===發起微信支付===");  
     }  
}  

@Service
publicclass JingDongPay implements IPay {  
     @Override
     public boolean support(String code) {  
        return"jingdong".equals(code);  
     }  

     @Override
     public void pay() {  
        System.out.println("===發起京東支付===");  
     }  
}

每個支付類都有一個support方法,判斷傳過來的code是否和自己定義的相等。

@Service
publicclass PayService4 implements ApplicationContextAware, InitializingBean {  

     private ApplicationContext applicationContext;  
     private List<IPay> payList = null;  

     @Override
     public void afterPropertiesSet() throws Exception {  
         if (payList == null) {  
             payList = new ArrayList<>();  
             Map<String, IPay> beansOfType = applicationContext.getBeansOfType(IPay.class);  
             beansOfType.forEach((key, value) -> payList.add(value));  
         }  
     }  

     @Override
     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {  
        this.applicationContext = applicationContext;  
     }  

     public void toPay(String code) {  
         for (IPay iPay : payList) {  
             if (iPay.support(code)) {  
                iPay.pay();  
             }  
         }  
     }  
}

這段代碼中先把實現了IPay接口的支付類實例初始化到一個list集合中,返回在調用支付接口時循環遍歷這個list集合,如果code跟自己定義的一樣,則調用當前的支付類實例的pay方法。

4.策略+工廠模式

這種方式也是用于code是有業務含義的場景。

策略模式定義了一組算法,把它們一個個封裝起來, 并且使它們可相互替換。

工廠模式用于封裝和管理對象的創建,是一種創建型模式。

public interface IPay {
    void pay();
}

@Service
publicclass AliaPay implements IPay {

    @PostConstruct
    public void init() {
        PayStrategyFactory.register("aliaPay", this);
    }


    @Override
    public void pay() {
        System.out.println("===發起支付寶支付===");
    }

}

@Service
publicclass WeixinPay implements IPay {

    @PostConstruct
    public void init() {
        PayStrategyFactory.register("weixinPay", this);
    }

    @Override
    public void pay() {
        System.out.println("===發起微信支付===");
    }
}

@Service
publicclass JingDongPay implements IPay {

    @PostConstruct
    public void init() {
        PayStrategyFactory.register("jingDongPay", this);
    }

    @Override
    public void pay() {
        System.out.println("===發起京東支付===");
    }
}

publicclass PayStrategyFactory {

    privatestatic Map<String, IPay> PAY_REGISTERS = new HashMap<>();


    public static void register(String code, IPay iPay) {
        if (null != code && !"".equals(code)) {
            PAY_REGISTERS.put(code, iPay);
        }
    }


    public static IPay get(String code) {
        return PAY_REGISTERS.get(code);
    }
}

@Service
publicclass PayService3 {

    public void toPay(String code) {
        PayStrategyFactory.get(code).pay();
    }
}

這段代碼的關鍵是PayStrategyFactory類,它是一個策略工廠,里面定義了一個全局的map,在所有IPay的實現類中注冊當前實例到map中,然后在調用的地方通過PayStrategyFactory類根據code從map獲取支付類實例即可。

5.責任鏈模式

這種方式在代碼重構時用來消除if...else非常有效。

責任鏈模式:將請求的處理對象像一條長鏈一般組合起來,形成一條對象鏈。請求并不知道具體執行請求的對象是哪一個,這樣就實現了請求與處理對象之間的解耦。

常用的filter、spring aop就是使用了責任鏈模式,這里我稍微改良了一下,具體代碼如下:

public abstractclass PayHandler {

    @Getter
    @Setter
    protected PayHandler next;

    public abstract void pay(String pay);

}

@Service
publicclass AliaPayHandler extends PayHandler {


    @Override
    public void pay(String code) {
        if ("alia".equals(code)) {
            System.out.println("===發起支付寶支付===");
        } else {
            getNext().pay(code);
        }
    }

}

@Service
publicclass WeixinPayHandler extends PayHandler {

    @Override
    public void pay(String code) {
        if ("weixin".equals(code)) {
            System.out.println("===發起微信支付===");
        } else {
            getNext().pay(code);
        }
    }
}

@Service
publicclass JingDongPayHandler extends PayHandler {


    @Override
    public void pay(String code) {
        if ("jingdong".equals(code)) {
            System.out.println("===發起京東支付===");
        } else {
            getNext().pay(code);
        }
    }
}

@Service
publicclass PayHandlerChain implements ApplicationContextAware, InitializingBean {

    private ApplicationContext applicationContext;
    private PayHandler header;


    public void handlePay(String code) {
        header.pay(code);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        Map<String, PayHandler> beansOfTypeMap = applicationContext.getBeansOfType(PayHandler.class);
        if (beansOfTypeMap == null || beansOfTypeMap.size() == 0) {
            return;
        }
        List<PayHandler> handlers = beansOfTypeMap.values().stream().collect(Collectors.toList());
        for (int i = 0; i < handlers.size(); i++) {
            PayHandler payHandler = handlers.get(i);
            if (i != handlers.size() - 1) {
                payHandler.setNext(handlers.get(i + 1));
            }
        }
        header = handlers.get(0);
    }
}

這段代碼的關鍵是每個PayHandler的子類,都定義了下一個需要執行的PayHandler子類,構成一個鏈式調用,通過PayHandlerChain把這種鏈式結構組裝起來。

三. 其他的消除if...else的方法

當然實際項目開發中使用if...else判斷的場景非常多,上面只是其中幾種場景。

下面再列舉一下,其他常見的場景。

1.根據不同的數字返回不同的字符串

public String getMessage(int code) {  
     if (code == 1) {  
        return"成功";  
     } elseif (code == -1) {  
        return"失敗";  
     } elseif (code == -2) {  
        return"網絡超時";  
     } elseif (code == -3) {  
        return"參數錯誤";  
     }  
     thrownew RuntimeException("code錯誤");  
}

其實,這種判斷沒有必要,用一個枚舉就可以搞定。

public enum MessageEnum {  
     SUCCESS(1, "成功"),  
     FAIL(-1, "失敗"),  
     TIME_OUT(-2, "網絡超時"),  
     PARAM_ERROR(-3, "參數錯誤");  

     privateint code;  
     private String message;  

     MessageEnum(int code, String message) {  
         this.code = code;  
         this.message = message;  
     }  
   
     public int getCode() {  
        returnthis.code;  
     }  

     public String getMessage() {  
        returnthis.message;  
     }  

     public static MessageEnum getMessageEnum(int code) {  
        return Arrays.stream(MessageEnum.values()).filter(x -> x.code == code).findFirst().orElse(null);  
     }  
}

再把調用方法稍微調整一下

public String getMessage(int code) {  
     MessageEnum messageEnum = MessageEnum.getMessageEnum(code);  
     return messageEnum.getMessage();  
}

完美。

2.集合中的判斷

上面的枚舉MessageEnum中的getMessageEnum方法,如果不用java8的語法的話,可能要這樣寫

public static MessageEnum getMessageEnum(int code) {  
     for (MessageEnum messageEnum : MessageEnum.values()) {  
         if (code == messageEnum.code) {  
            return messageEnum;  
         }  
     }  
     return null;  
}

對于集合中過濾數據,或者查找方法,java8有更簡單的方法消除if...else判斷。

public static MessageEnum getMessageEnum(int code) {  
     return Arrays.stream(MessageEnum.values()).filter(x -> x.code == code).findFirst().orElse(null);  
}

3.簡單的判斷

其實有些簡單的if...else完全沒有必要寫,可以用三目運算符代替,比如這種情況:

public String getMessage2(int code) {  
     if(code == 1) {  
        return "成功";  
     }  
     return "失敗";  
}

改成三目運算符:

public String getMessage2(int code) {  
    return code == 1 ? "成功" : "失敗";  
}

修改之后代碼更簡潔一些。

4.Spring中的判斷

對于參數的異常,越早被發現越好,在Spring中提供了Assert類,用來幫助我們檢測參數是否有效。

以前我們的參數判斷一般是下面這樣的:

public void save(Integer code,String name) {  
     if(code == null) {
       throw Exception("code不能為空");     
     } else {
         if(name == null) {
             throw Exception("name不能為空");     
         } else {
             System.out.println("doSave");
         }
     }
 }

如果參數非常多的話,if...else語句會很長。

這時如果改成使用Assert類判斷,代碼會簡化很多:

public String save2(Integer code,String name) {      
     Assert.notNull(code,"code不能為空"); 
     Assert.notNull(name,"name不能為空"); 
     System.out.println("doSave");
 }

當然,還有很多其他的場景可以優化if...else,我再這里就不一一介紹了。

責任編輯:武曉燕 來源: 蘇三說技術
相關推薦

2021-01-04 05:46:08

代碼編程重構

2021-04-20 08:02:08

業務數據用戶

2021-11-22 11:50:16

JavaFunctionif...else

2019-12-17 08:45:30

ifelseJava

2020-10-22 09:20:22

SQLNoSQL 數據庫

2022-01-13 10:45:59

if-else代碼Java

2022-05-13 08:48:50

React組件TypeScrip

2023-12-21 10:26:30

??Prettier

2020-07-09 08:59:52

if else模板Service

2021-12-29 17:24:16

Kubernetes集群事件

2012-02-29 13:39:18

AndroidGoogle

2022-03-11 12:14:43

CSS代碼前端

2021-06-25 15:53:25

Kubernetes程序技巧

2020-04-09 08:29:50

編程語言事件驅動

2025-06-26 01:10:00

服務定位解析器Spring

2021-01-29 07:45:27

if-else代碼數據

2024-02-23 08:57:42

Python設計模式編程語言

2020-04-03 14:55:39

Python 代碼編程

2022-03-08 06:41:35

css代碼

2018-07-12 14:20:33

SQLSQL查詢編寫
點贊
收藏

51CTO技術棧公眾號

日韩av中文字幕在线播放| 一区二区国产视频| 成人精品一区二区三区| 91视频免费在线看| 清纯唯美亚洲经典中文字幕| 色94色欧美sute亚洲线路一ni| 亚洲一区二区精品在线观看| 亚洲第一天堂网| 久久午夜电影| 色综合久综合久久综合久鬼88| 男男做爰猛烈叫床爽爽小说| 久久久久久久性潮| 亚洲高清久久久| 亚洲国产精品日韩| 全部免费毛片在线播放一个| 青青草国产成人99久久| 欧美激情第1页| 国产熟女一区二区| 国产乱人伦精品一区| 欧洲一区在线电影| 国产av人人夜夜澡人人爽麻豆| 国产三级在线免费| 懂色av噜噜一区二区三区av| 国产精品美女免费视频| 亚洲免费激情视频| 91精品国产91久久久久久密臀| 亚洲精品美女视频| 少妇欧美激情一区二区三区| 日韩中文视频| 欧美日韩国产精品一区二区不卡中文| 自拍偷拍一区二区三区| 蜜桃成人在线视频| 99精品欧美一区二区三区综合在线| 国产免费亚洲高清| 中文字幕在线日本| 国产伦理一区| 国内精品久久久久久影视8| 少妇高潮在线观看| 欧美一二区在线观看| 亚洲精品美女久久| 欧美做受高潮中文字幕| 精品国产一区二区三区性色av| 在线观看国产一区二区| 97成人在线观看视频| 俄罗斯一级**毛片在线播放| 亚洲欧美日韩一区| 一级一片免费播放| 日本黄色片在线观看| 久久精品综合网| 欧美不卡三区| 久草视频视频在线播放| 97精品久久久午夜一区二区三区| 成人av电影免费| www天堂在线| 国产精一品亚洲二区在线视频| 国产精品网站大全| 在线观看日批视频| 久久精品72免费观看| 国产精品美乳一区二区免费| 国产一卡二卡三卡| 日本女人一区二区三区| 国产精品成人av在线| 波多野结衣高清在线| 日韩制服丝袜av| 国产精品视频地址| 99久久精品国产一区二区成人| 久久久久黄色| 在线播放欧美女士性生活| 在线免费观看av的网站| 成人网ww555视频免费看| 在线观看日产精品| 日本在线播放一区二区| 成人国产精品久久| 精品美女一区二区| 亚洲国产欧美视频| 成人嫩草影院| 久久国产精品99国产精| 久久久99精品| 一区二区三区国产在线| 国产97色在线|日韩| 在线观看国产小视频| 久久99精品久久久久久| 99porn视频在线| 午夜av免费观看| 国产农村妇女精品| 免费看黄色a级片| 国产高清视频色在线www| 日韩欧美成人免费视频| 在线黄色免费看| 白白在线精品| 亚洲天堂色网站| 国内偷拍精品视频| 老鸭窝毛片一区二区三区| 国产精品中文字幕在线观看| 亚洲免费一级片| 久久影视一区二区| 熟女视频一区二区三区| 97天天综合网| 欧美日韩亚洲国产综合| 欧美双性人妖o0| 成人vr资源| 久久人人爽人人| 探花国产精品一区二区| 国产成人精品一区二区三区网站观看| 久久一区二区精品| a级片国产精品自在拍在线播放| 激情久久av一区av二区av三区| 青青草精品视频在线观看| 国产伦乱精品| 久久久国产精品免费| 欧美性猛交bbbbb精品| 狠狠色丁香婷婷综合久久片| 精品欧美日韩在线| 黄色免费在线网站| 日本韩国欧美三级| 色婷婷精品久久二区二区密| 国产精品久久观看| 欧美在线激情网| 国产黄a三级三级三级| 国产情人综合久久777777| 六月婷婷激情综合| 成人污污www网站免费丝瓜| 亚洲色图欧美制服丝袜另类第一页| 99视频只有精品| 日本成人超碰在线观看| 精品欧美日韩| 2020av在线| 欧美videossexotv100| 久久久久人妻一区精品色| 国产精品尤物| 精品日本一区二区三区| 欧美男男video| 日韩视频免费直播| 亚洲一二三在线观看| 日日摸夜夜添夜夜添亚洲女人| 国产精品免费一区二区三区观看 | 韩国v欧美v日本v亚洲v| 日韩国产一区久久| japanese23hdxxxx日韩| 国产丝袜一区视频在线观看 | 日韩精品91亚洲二区在线观看| 国产日韩一区二区三区| 另类视频在线| 337p日本欧洲亚洲大胆精品| 精品在线视频免费| 成人激情视频网站| 亚洲国产精品成人天堂| www.豆豆成人网.com| 欧美激情亚洲视频| 免费观看黄色一级视频| 亚洲国产精品久久久久秋霞影院| 无码人妻一区二区三区精品视频| 欧美 日韩 国产一区二区在线视频 | 欧美精品一区二区三区蜜桃| 日韩免费一二三区| 99久久免费国产| 精品人妻一区二区三区四区在线| 啪啪激情综合网| 日本免费在线精品| porn视频在线观看| 欧美片网站yy| 欧美三级小视频| 成人av网址在线| 久久精品免费一区二区| 免费欧美一区| 国产精品视频永久免费播放| 午夜看片在线免费| 欧美一区二区三区免费在线看| 四虎免费在线视频| www.在线欧美| 99免费视频观看| 欧美成人自拍| 国产成人女人毛片视频在线| 日韩大片免费观看| 在线丨暗呦小u女国产精品| 国产精品久久久久久在线| 亚洲最新视频在线观看| av电影在线播放| 日韩精品视频网站| 免费国产成人看片在线| 美女呻吟一区| 国产精品自产拍在线观看| 在线观看男女av免费网址| 亚洲高清av在线| 在线观看毛片视频| 亚洲一区二区三区美女| 久久亚洲AV无码专区成人国产| 麻豆国产欧美日韩综合精品二区| 隔壁人妻偷人bd中字| 国产精品嫩模av在线| 91久久精品国产91性色| 久久久男人天堂| 中文字幕在线观看日韩| 秋霞视频一区二区| 欧美精品色综合| 全部毛片永久免费看| 国产精品拍天天在线| 国产人成视频在线观看| 裸体在线国模精品偷拍| 亚洲 欧美 日韩 国产综合 在线| 成人羞羞视频播放网站| 国产美女在线精品免费观看| 欧洲亚洲精品| 欧美亚洲视频在线观看| 性直播体位视频在线观看| 亚洲图片在线综合| 好男人www在线视频| 欧美日韩一区中文字幕| 圆产精品久久久久久久久久久| 中文字幕一区二区日韩精品绯色| 国产麻豆剧传媒精品国产av| 久久99在线观看| 116极品美女午夜一级| 欧美黄在线观看| 午夜精品福利一区二区| 国产图片一区| 亚洲一区二区三区乱码aⅴ| 国产综合色区在线观看| 高清一区二区三区四区五区| 日本不卡不卡| 在线电影中文日韩| 亚洲人妻一区二区三区| 欧美mv和日韩mv国产网站| 亚洲专区在线播放| 在线观看中文字幕不卡| 在线观看黄网站| 亚洲成人资源在线| 黄色一级视频免费| 亚洲婷婷综合色高清在线| 超薄肉色丝袜一二三| 国产午夜精品在线观看| 亚洲av成人片色在线观看高潮 | 免费人成网站在线观看欧美高清| 免费国产黄色网址| 欧美午夜在线| 国产911在线观看| 久久久久午夜电影| 中日韩在线视频| 97精品视频在线看| 一本一道久久久a久久久精品91| 国产一区网站| 日本一区免费在线观看| 在线成人动漫av| 欧洲在线视频一区| 久久av资源| 日韩免费av一区二区三区| 蜜臀久久99精品久久一区二区| 久久99精品久久久久子伦| 卡通动漫国产精品| 久久99精品久久久久久三级| 日韩在线影视| 久久精品国产第一区二区三区最新章节 | 欧美图片第一页| 久久色在线观看| 性猛交娇小69hd| 国产精品美女久久久久久| 日韩精品久久久久久久的张开腿让| 国产精品嫩草99a| 免费黄色激情视频| 亚洲视频在线一区观看| 久久综合成人网| 天天av天天翘天天综合网色鬼国产| 日产精品久久久久| 欧美日韩中文字幕日韩欧美| 久久青青草原亚洲av无码麻豆| 色婷婷av一区二区| 正在播放亚洲精品| 欧美精品精品一区| 国产黄a三级三级看三级| 日韩精品在线免费播放| 韩国精品视频| www.久久久久久.com| 天堂av最新在线| 欧美在线视频网| 日本免费一区二区三区等视频| 91香蕉视频在线下载| 另类尿喷潮videofree| 欧美少妇一区| 婷婷亚洲最大| 成人一对一视频| 免费xxxx性欧美18vr| 好吊操视频这里只有精品| 97aⅴ精品视频一二三区| 成年人在线免费看片| 亚洲同性gay激情无套| www成人在线| 欧美日韩国产综合久久| 成人毛片视频免费看| 亚洲欧洲xxxx| 菠萝菠萝蜜在线视频免费观看 | 日韩欧美在线观看免费| 欧美片网站yy| 视频一区二区三区在线看免费看| 日韩中文在线中文网在线观看| 日本精品600av| 国产精品第1页| 在线播放一区二区精品视频| 日本一区免费在线观看| 1024精品一区二区三区| 伊人影院综合在线| 91在线国内视频| 加勒比婷婷色综合久久| 日本乱码高清不卡字幕| 草草视频在线播放| 日韩在线免费视频| 中日韩脚交footjobhd| 亚洲va久久久噜噜噜久久天堂| 久久综合色占| 亚洲不卡中文字幕无码| 国产成人亚洲精品狼色在线| 中字幕一区二区三区乱码| 午夜视频一区二区三区| 国产又粗又黄又爽| 国产一区二区三区精品久久久| 96av在线| julia一区二区中文久久94| 成人a'v在线播放| 亚洲国产精品久久久久爰色欲| 国产精品自产自拍| 女同久久另类69精品国产| 色偷偷久久一区二区三区| 亚洲乱码在线观看| 久久国产精品久久久| 国产精品天堂蜜av在线播放| 久久综合福利| 亚洲一区二区动漫| 国产一级二级在线观看| 亚洲国产日韩综合久久精品| 国产精品伊人久久 | 乱h高h女3p含苞待放| 欧美午夜理伦三级在线观看| 飘雪影视在线观看免费观看| 久久久免费在线观看| 日韩精品视频中文字幕| 天堂av免费看| 国产一区二区三区av电影| www.黄色com| 在线不卡a资源高清| aⅴ在线视频男人的天堂 | 欧美视频在线播放一区| 99热精品一区二区| 日本一区二区欧美| 亚洲国产精品电影| 1区2区3区在线| 国产精品视频免费一区| 好看的亚洲午夜视频在线| 人妻少妇偷人精品久久久任期| 亚洲啪啪综合av一区二区三区| 一级片aaaa| 久久精品国产99国产精品澳门| 狂野欧美性猛交xxxx| 亚洲精品影院| 精品一区二区三区在线播放视频 | 欧美日韩国内| 丰满少妇中文字幕| 亚洲一区日韩精品中文字幕| 99在线精品视频免费观看20| 欧美成人精品影院| 澳门成人av| 黄色动漫在线免费看| 久久久久国产精品厨房| 伊人网中文字幕| 色婷婷综合成人av| 国产麻豆一区二区三区| 男人天堂av片| 91亚洲大成网污www| 高清乱码免费看污| 中文字幕国内精品| 精品国产三级| 亚洲熟妇无码一区二区三区| 91丨porny丨中文| 中文字幕一区二区在线视频 | 天堂精品一区二区三区| 久久福利视频一区二区| 538精品在线观看| 日韩电影在线观看永久视频免费网站| 91av亚洲| 致1999电视剧免费观看策驰影院| 国产成人精品1024| 国产精品100| 久久精品国产免费观看| 国偷自产视频一区二区久| 毛葺葺老太做受视频| 亚洲日本va午夜在线影院| 日本美女一级视频| 国产精品久久久久久久久久久久久久| 亚洲91中文字幕无线码三区| 国产调教打屁股xxxx网站| 欧美日韩亚洲精品内裤| 欧美成人高清在线| 久久精品magnetxturnbtih| 久久99蜜桃精品| 日韩不卡视频在线| 久久精品久久久久久| 欧美偷窥清纯综合图区| 中文字幕22页| 欧美性猛交xxxx富婆弯腰| 国产不卡在线| 欧美亚洲免费在线| 国产999精品久久久久久绿帽|