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

滿屏的if-else,怎么消滅它們?

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

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

[[392707]]

圖片來自 Pexels

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

又臭又長的 if...else

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

  1. public interface IPay {   
  2.     void pay();   
  3. }   
  4.  
  5. @Service   
  6. public class AliaPay implements IPay {   
  7.      @Override   
  8.      public void pay() {   
  9.         System.out.println("===發起支付寶支付===");   
  10.      }   
  11. }   
  12.  
  13. @Service   
  14. public class WeixinPay implements IPay {   
  15.      @Override   
  16.      public void pay() {   
  17.          System.out.println("===發起微信支付===");   
  18.      }   
  19. }   
  20.  
  21. @Service   
  22. public class JingDongPay implements IPay {   
  23.      @Override   
  24.      public void pay() {   
  25.         System.out.println("===發起京東支付===");   
  26.      }   
  27. }   
  28.  
  29. @Service   
  30. public class PayService {   
  31.      @Autowired   
  32.      private AliaPay aliaPay;   
  33.      @Autowired   
  34.      private WeixinPay weixinPay;   
  35.      @Autowired   
  36.      private JingDongPay jingDongPay;   
  37.  
  38.  
  39.      public void toPay(String code) {   
  40.          if ("alia".equals(code)) {   
  41.              aliaPay.pay();   
  42.          } else if ("weixin".equals(code)) {   
  43.               weixinPay.pay();   
  44.          } else if ("jingdong".equals(code)) {   
  45.               jingDongPay.pay();   
  46.          } else {   
  47.               System.out.println("找不到支付方式");   
  48.          }   
  49.      }   

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

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

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

很明顯,這里違反了設計模式六大原則的:

  • 開閉原則:對擴展開放,對修改關閉。就是說增加新功能要盡量少改動已有代碼。
  • 單一職責原則:顧名思義,要求邏輯盡量單一,不要太復雜,便于復用。

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

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

使用注解

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

我們先定義一個注解:

  1. @Retention(RetentionPolicy.RUNTIME)   
  2. @Target(ElementType.TYPE)   
  3. public @interface PayCode {   
  4.  
  5.      String value();     
  6.      String name();   

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

  1. @PayCode(value = "alia"name = "支付寶支付")   
  2. @Service   
  3. public class AliaPay implements IPay {   
  4.  
  5.      @Override   
  6.      public void pay() {   
  7.          System.out.println("===發起支付寶支付===");   
  8.      }   
  9. }   
  10.  
  11.  
  12. @PayCode(value = "weixin"name = "微信支付")   
  13. @Service   
  14. public class WeixinPay implements IPay {   
  15.  
  16.      @Override   
  17.      public void pay() {   
  18.          System.out.println("===發起微信支付===");   
  19.      }   
  20. }  
  21.  
  22.  
  23. @PayCode(value = "jingdong"name = "京東支付")   
  24. @Service   
  25. public class JingDongPay implements IPay {   
  26.  
  27.      @Override   
  28.      public void pay() {   
  29.         System.out.println("===發起京東支付===");   
  30.      }   

然后增加最關鍵的類:

  1. @Service   
  2. public class PayService2 implements ApplicationListener<ContextRefreshedEvent> {   
  3.  
  4.      private static Map<String, IPay> payMap = null;   
  5.  
  6.      @Override   
  7.      public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {   
  8.          ApplicationContext applicationContext = contextRefreshedEvent.getApplicationContext();   
  9.          Map<String, Object> beansWithAnnotation = applicationContext.getBeansWithAnnotation(PayCode.class);   
  10.  
  11.          if (beansWithAnnotation != null) {   
  12.              payMap = new HashMap<>();   
  13.              beansWithAnnotation.forEach((key, value) ->{   
  14.                  String bizType = value.getClass().getAnnotation(PayCode.class).value();   
  15.                  payMap.put(bizType, (IPay) value);   
  16.              });   
  17.          }   
  18.      }   
  19.  
  20.      public void pay(String code) {   
  21.         payMap.get(code).pay();   
  22.      }   

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

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

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

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

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

動態拼接名稱

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

  1. @Service   
  2. public class PayService3 implements ApplicationContextAware {    
  3.      private ApplicationContext applicationContext;   
  4.      private static final String SUFFIX = "Pay";   
  5.  
  6.      @Override   
  7.      public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {   
  8.         this.applicationContext = applicationContext;   
  9.      }   
  10.  
  11.      public void toPay(String payCode) {   
  12.          ((IPay) applicationContext.getBean(getBeanName(payCode))).pay();   
  13.      }   
  14.  
  15.      public String getBeanName(String payCode) {   
  16.          return payCode + SUFFIX;   
  17.      }   

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

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

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

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

模板方法判斷

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

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

  1. public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {   
  2.      if (adviceObject instanceof Advisor) {   
  3.         return (Advisor) adviceObject;   
  4.      }   
  5.      if (!(adviceObject instanceof Advice)) {   
  6.         throw new UnknownAdviceTypeException(adviceObject);   
  7.      }   
  8.      Advice advice = (Advice) adviceObject;   
  9.      if (advice instanceof MethodInterceptor) {     
  10.         return new DefaultPointcutAdvisor(advice);   
  11.      }   
  12.      for (AdvisorAdapter adapter : this.adapters) {   
  13.          if (adapter.supportsAdvice(advice)) {   
  14.              return new DefaultPointcutAdvisor(advice);   
  15.          }   
  16.      }   
  17.      throw new UnknownAdviceTypeException(advice);   
  18.  } 

重點看看 supportAdvice 方法,有三個類實現了這個方法。

我們隨便抽一個類看看:

  1. class AfterReturningAdviceAdapter implements AdvisorAdapter, Serializable {   
  2.  
  3.      @Override   
  4.      public boolean supportsAdvice(Advice advice) {   
  5.         return (advice instanceof AfterReturningAdvice);   
  6.      }   
  7.  
  8.      @Override   
  9.      public MethodInterceptor getInterceptor(Advisor advisor) {   
  10.         AfterReturningAdvice advice = (AfterReturningAdvice) advisor.getAdvice();   
  11.         return new AfterReturningAdviceInterceptor(advice);   
  12.      }    

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

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

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

  1. public interface IPay {   
  2.      boolean support(String code);    
  3.      void pay();   
  4. }   
  5.  
  6. @Service   
  7. public class AliaPay implements IPay {    
  8.      @Override   
  9.      public boolean support(String code) {   
  10.         return "alia".equals(code);   
  11.      }   
  12.  
  13.      @Override   
  14.      public void pay() {   
  15.         System.out.println("===發起支付寶支付===");   
  16.      }   
  17. }   
  18.  
  19. @Service   
  20. public class WeixinPay implements IPay {   
  21.  
  22.      @Override   
  23.      public boolean support(String code) {   
  24.         return "weixin".equals(code);   
  25.      }   
  26.  
  27.      @Override   
  28.      public void pay() {   
  29.         System.out.println("===發起微信支付===");   
  30.      }   
  31. }   
  32.  
  33. @Service   
  34. public class JingDongPay implements IPay {   
  35.      @Override   
  36.      public boolean support(String code) {   
  37.         return "jingdong".equals(code);   
  38.      }   
  39.  
  40.      @Override   
  41.      public void pay() {   
  42.         System.out.println("===發起京東支付===");   
  43.      }   

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

  1. @Service   
  2. public class PayService4 implements ApplicationContextAware, InitializingBean {   
  3.  
  4.      private ApplicationContext applicationContext;   
  5.      private List<IPay> payList = null;   
  6.  
  7.      @Override   
  8.      public void afterPropertiesSet() throws Exception {   
  9.          if (payList == null) {   
  10.              payList = new ArrayList<>();   
  11.              Map<String, IPay> beansOfType = applicationContext.getBeansOfType(IPay.class);   
  12.  
  13.              beansOfType.forEach((key, value) -> payList.add(value));   
  14.          }   
  15.      }   
  16.  
  17.      @Override   
  18.      public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {   
  19.         this.applicationContext = applicationContext;   
  20.      }   
  21.  
  22.      public void toPay(String code) {   
  23.          for (IPay iPay : payList) {   
  24.              if (iPay.support(code)) {   
  25.                 iPay.pay();   
  26.              }   
  27.          }   
  28.      }   

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

策略+工廠模式

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

  • 策略模式定義了一組算法,把它們一個個封裝起來, 并且使它們可相互替換。
  • 工廠模式用于封裝和管理對象的創建,是一種創建型模式。
  1. public interface IPay { 
  2.     void pay(); 
  3.  
  4. @Service 
  5. public class AliaPay implements IPay { 
  6.  
  7.     @PostConstruct 
  8.     public void init() { 
  9.         PayStrategyFactory.register("aliaPay", this); 
  10.     } 
  11.  
  12.  
  13.     @Override 
  14.     public void pay() { 
  15.         System.out.println("===發起支付寶支付==="); 
  16.     } 
  17.  
  18.  
  19. @Service 
  20. public class WeixinPay implements IPay { 
  21.  
  22.     @PostConstruct 
  23.     public void init() { 
  24.         PayStrategyFactory.register("weixinPay", this); 
  25.     } 
  26.  
  27.     @Override 
  28.     public void pay() { 
  29.         System.out.println("===發起微信支付==="); 
  30.     } 
  31.  
  32. @Service 
  33. public class JingDongPay implements IPay { 
  34.  
  35.     @PostConstruct 
  36.     public void init() { 
  37.         PayStrategyFactory.register("jingDongPay", this); 
  38.     } 
  39.  
  40.     @Override 
  41.     public void pay() { 
  42.         System.out.println("===發起京東支付==="); 
  43.     } 
  44.  
  45. public class PayStrategyFactory { 
  46.  
  47.     private static Map<String, IPay> PAY_REGISTERS = new HashMap<>(); 
  48.  
  49.  
  50.     public static void register(String code, IPay iPay) { 
  51.         if (null != code && !"".equals(code)) { 
  52.             PAY_REGISTERS.put(code, iPay); 
  53.         } 
  54.     } 
  55.  
  56.  
  57.     public static IPay get(String code) { 
  58.         return PAY_REGISTERS.get(code); 
  59.     } 
  60.  
  61. @Service 
  62. public class PayService3 { 
  63.  
  64.     public void toPay(String code) { 
  65.         PayStrategyFactory.get(code).pay(); 
  66.     } 

這段代碼的關鍵是 PayStrategyFactory 類,它是一個策略工廠,里面定義了一個全局的 map,在所有 IPay 的實現類中注冊當前實例到 map 中。

然后在調用的地方通過 PayStrategyFactory 類根據 code 從 map 獲取支付類實例即可。

責任鏈模式

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

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

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

  1. public abstract class PayHandler { 
  2.  
  3.     @Getter 
  4.     @Setter 
  5.     protected PayHandler next
  6.  
  7.     public abstract void pay(String pay); 
  8.  
  9.  
  10. @Service 
  11. public class AliaPayHandler extends PayHandler { 
  12.  
  13.  
  14.     @Override 
  15.     public void pay(String code) { 
  16.         if ("alia".equals(code)) { 
  17.             System.out.println("===發起支付寶支付==="); 
  18.         } else { 
  19.             getNext().pay(code); 
  20.         } 
  21.     } 
  22.  
  23.  
  24. @Service 
  25. public class WeixinPayHandler extends PayHandler { 
  26.  
  27.     @Override 
  28.     public void pay(String code) { 
  29.         if ("weixin".equals(code)) { 
  30.             System.out.println("===發起微信支付==="); 
  31.         } else { 
  32.             getNext().pay(code); 
  33.         } 
  34.     } 
  35.  
  36. @Service 
  37. public class JingDongPayHandler extends PayHandler { 
  38.  
  39.  
  40.     @Override 
  41.     public void pay(String code) { 
  42.         if ("jingdong".equals(code)) { 
  43.             System.out.println("===發起京東支付==="); 
  44.         } else { 
  45.             getNext().pay(code); 
  46.         } 
  47.     } 
  48.  
  49. @Service 
  50. public class PayHandlerChain implements ApplicationContextAware, InitializingBean { 
  51.  
  52.     private ApplicationContext applicationContext; 
  53.     private PayHandler header; 
  54.  
  55.  
  56.     public void handlePay(String code) { 
  57.         header.pay(code); 
  58.     } 
  59.  
  60.     @Override 
  61.     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 
  62.         this.applicationContext = applicationContext; 
  63.     } 
  64.  
  65.     @Override 
  66.     public void afterPropertiesSet() throws Exception { 
  67.         Map<String, PayHandler> beansOfTypeMap = applicationContext.getBeansOfType(PayHandler.class); 
  68.         if (beansOfTypeMap == null || beansOfTypeMap.size() == 0) { 
  69.             return
  70.         } 
  71.         List<PayHandler> handlers = beansOfTypeMap.values().stream().collect(Collectors.toList()); 
  72.         for (int i = 0; i < handlers.size(); i++) { 
  73.             PayHandler payHandler = handlers.get(i); 
  74.             if (i != handlers.size() - 1) { 
  75.                 payHandler.setNext(handlers.get(i + 1)); 
  76.             } 
  77.         } 
  78.         header = handlers.get(0); 
  79.     } 

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

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

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

①根據不同的數字返回不同的字符串

代碼如下:

  1. public String getMessage(int code) {   
  2.      if (code == 1) {   
  3.         return "成功";   
  4.      } else if (code == -1) {   
  5.         return "失敗";   
  6.      } else if (code == -2) {   
  7.         return "網絡超時";   
  8.      } else if (code == -3) {   
  9.         return "參數錯誤";   
  10.      }   
  11.      throw new RuntimeException("code錯誤");   

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

  1. public enum MessageEnum {   
  2.      SUCCESS(1, "成功"),   
  3.      FAIL(-1, "失敗"),   
  4.      TIME_OUT(-2, "網絡超時"),   
  5.      PARAM_ERROR(-3, "參數錯誤");   
  6.  
  7.      private int code;   
  8.      private String message;   
  9.  
  10.      MessageEnum(int code, String message) {   
  11.          this.code = code;   
  12.          this.message = message;   
  13.      }   
  14.  
  15.      public int getCode() {   
  16.         return this.code;   
  17.      }   
  18.  
  19.      public String getMessage() {   
  20.         return this.message;   
  21.      }   
  22.  
  23.      public static MessageEnum getMessageEnum(int code) {   
  24.         return Arrays.stream(MessageEnum.values()).filter(x -> x.code == code).findFirst().orElse(null);   
  25.      }   

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

  1. public String getMessage(int code) {   
  2.      MessageEnum messageEnum = MessageEnum.getMessageEnum(code);   
  3.      return messageEnum.getMessage();   

完美。

②集合中的判斷

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

  1. public static MessageEnum getMessageEnum(int code) {   
  2.      for (MessageEnum messageEnum : MessageEnum.values()) {   
  3.          if (code == messageEnum.code) {   
  4.             return messageEnum;   
  5.          }   
  6.      }   
  7.      return null;   

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

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

③簡單的判斷

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

  1. public String getMessage2(int code) {   
  2.      if(code == 1) {   
  3.         return  "成功";   
  4.      }   
  5.      return "失敗";   

改成三目運算符: 

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

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

④Spring 中的判斷

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

  1. public void save(Integer code,String name) {   
  2.      if(code == null) { 
  3.        throw Exception("code不能為空");      
  4.      } else { 
  5.          if(name == null) { 
  6.              throw Exception("name不能為空");      
  7.          } else { 
  8.              System.out.println("doSave"); 
  9.          } 
  10.      } 
  11.  } 

如果參數非常多的話,if...else 語句會很長,這時如果改成使用 Assert 類判斷,代碼會簡化很多: 

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

當然,還有很多其他的場景可以優化 if...else,我再這里就不一一介紹了,感興趣的朋友可以給我留言,一起探討和研究一下。

作者:蘇三

編輯:陶家龍

出處:轉載自公眾號蘇三說技術

 

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

2021-03-10 07:20:43

if-else靜態代碼

2020-04-20 15:40:03

if-elseJava優化

2020-03-11 08:00:12

if-else優化運算符

2023-06-02 07:30:24

If-else結構流程控制

2013-03-06 10:28:57

ifJava

2021-11-04 08:53:00

if-else代碼Java

2020-10-22 09:20:22

SQLNoSQL 數據庫

2022-07-11 08:16:55

策略模式if-else

2020-04-09 08:29:50

編程語言事件驅動

2025-10-27 01:33:00

if-else代碼重構

2021-05-17 14:57:23

策略模式代碼

2020-05-13 14:15:25

if-else代碼前端

2020-12-15 09:31:58

CTOif-else代碼

2025-04-24 08:40:00

JavaScript代碼return語句

2025-07-29 09:01:35

if-else代碼

2025-06-26 01:10:00

服務定位解析器Spring

2020-09-27 14:24:58

if-else cod業務

2024-06-18 18:36:03

2021-01-29 07:45:27

if-else代碼數據

2022-07-04 08:32:55

Map函數式接口
點贊
收藏

51CTO技術棧公眾號

日韩精品福利网| 精品视频高潮| 亚洲欧美激情在线| 国产精品视频在线免费观看| 国产又粗又大又爽的视频| 国产又黄又大又爽| 亚洲精品视频啊美女在线直播| 亚洲精品在线观看www| 羞羞的视频在线| bbw在线视频| 日本一二三不卡| 国产在线播放一区二区| 亚洲无码精品国产| 国产精品视频| 欧美夫妻性视频| 第一次破处视频| 看全色黄大色大片免费久久久| 欧美日韩你懂得| 中国丰满人妻videoshd| 老司机福利在线视频| www久久精品| 九九热视频这里只有精品| 你懂得在线视频| 国产亚洲观看| 欧美亚洲精品一区| 国产美女网站在线观看| 大片免费在线看视频| 国产日韩精品一区二区三区| 成人在线看片| 国产有码在线观看| 日韩av电影免费观看高清完整版| 国外色69视频在线观看| 看片网站在线观看| 久久久久久久久99精品大| 亚洲色图色老头| 亚洲视频在线播放免费| 日韩欧洲国产| 欧美一区二区高清| www.国产视频.com| 成人国产激情在线| 色老汉一区二区三区| av网站在线观看不卡| av在线资源| 亚洲一区免费观看| 2018中文字幕第一页| 国产原厂视频在线观看| 中文字幕在线不卡视频| 亚洲开发第一视频在线播放| yiren22亚洲综合伊人22| 国产亚洲综合性久久久影院| 麻豆亚洲一区| 欧美日韩国产中文字幕在线| 91视频com| 久久免费视频1| 亚洲av成人无码网天堂| 2欧美一区二区三区在线观看视频| http;//www.99re视频| 午夜精品在线播放| 成人激情免费电影网址| 国产精品久久久久久久久婷婷| 精品人妻一区二区三区日产乱码| 久久99久久99精品免视看婷婷| 国产噜噜噜噜噜久久久久久久久 | 青青草娱乐在线| 99re视频精品| 奇米视频888战线精品播放| 青青青草网站免费视频在线观看| 91麻豆免费看片| 欧美一区少妇| 亚洲成人三级| 亚洲美女在线一区| av日韩一区二区三区| 二区三区不卡| 欧美日韩在线综合| 欧美视频亚洲图片| h视频久久久| 国产视频综合在线| 欧美aaa级片| 综合天天久久| 6080yy精品一区二区三区| caoporn国产| 久久国产精品一区二区| 99理论电影网| 加勒比一区二区三区在线| 成人欧美一区二区三区1314| 免费在线黄网站| 老司机2019福利精品视频导航| 欧美日韩一级二级三级| 日韩精品xxx| 亚洲婷婷影院| 欧美成人免费视频| 成人免费毛片男人用品| 精品一区二区三区视频| 国产综合 伊人色| 91福利在线视频| 一区二区三区日韩精品| 免费大片在线观看| 98视频精品全部国产| 亚洲天堂av在线免费观看| 一区二区国产精品精华液| 亚洲日韩成人| 亚洲aⅴ日韩av电影在线观看| 日韩中文字幕免费观看| 国产精品久久久久一区| www.99热这里只有精品| 全球中文成人在线| 天天综合色天天综合| 午夜激情在线观看视频| 91免费精品国偷自产在线在线| 亚洲人成啪啪网站| 久久久久久欧美精品se一二三四 | 色啦啦av综合| 亚洲丁香日韩| 国产+人+亚洲| 国产青青草视频| 久久久国产精华| 男人插女人视频在线观看| 一区二区三区日本视频| 亚洲欧美一区二区激情| 精品视频久久久久| 国模一区二区三区白浆| 欧美视频观看一区| 国产理论在线| 精品久久一区二区三区| 羞羞在线观看视频| 日本系列欧美系列| 欧美乱偷一区二区三区在线| av影片在线| 欧美电影免费观看完整版| 战狼4完整免费观看在线播放版| 99亚洲精品| 国产激情一区二区三区在线观看| 久久精品视频观看| 欧美日韩另类国产亚洲欧美一级| 中文字幕一二三四区| 亚洲综合好骚| 国产精品一区在线播放| 日韩三级电影视频| 日韩一区二区在线看| 黄色录像一级片| 久久aⅴ国产欧美74aaa| 在线视频不卡一区二区| 久久精品国产精品亚洲毛片| 亚洲男子天堂网| 中文字幕亚洲乱码熟女1区2区| caoporen国产精品视频| 一二三四视频社区在线| 久久精品色综合| 91精品国产高清| 青青青草网站免费视频在线观看| 精品久久久中文| 草草地址线路①屁屁影院成人| 国产日韩1区| 欧美日韩国产一二| 国产经典一区| 精品国产欧美成人夜夜嗨| 91国内精品视频| 亚洲日本在线a| 国产一级二级av| 狠狠噜噜久久| 九九久久99| 欧美成a人片在线观看久| 国产一区二区三区免费视频| 在线观看国产精品视频| 亚洲欧美日韩系列| 久久人妻少妇嫩草av蜜桃| 亚洲乱亚洲高清| 欧洲在线视频一区| 四虎国产精品永久在线国在线 | 青青操在线视频观看| 极品销魂美女一区二区三区| 成人午夜免费剧场| 国产一级成人av| 国产精品91在线观看| 黄色小网站在线观看| 日韩欧美一级精品久久| 久久久精品福利| 欧美国产日本韩| 国产吃瓜黑料一区二区| 久久九九免费| 国产香蕉一区二区三区| 美女av一区| 成人免费福利在线| av有码在线观看| 中文字幕不卡在线视频极品| 国产色综合视频| 欧美性猛xxx| 糖心vlog免费在线观看| 97久久精品人人做人人爽50路| 在线观看高清免费视频| 欧美婷婷在线| 天堂一区二区三区| 成人h动漫精品一区二区器材| 国产va免费精品高清在线| 日本www在线| 日韩精品免费在线视频观看| 97人妻精品一区二区三区| 五月激情综合婷婷| 99热在线观看精品| 久久亚洲免费视频| 曰本三级日本三级日本三级| 久久久噜噜噜久久狠狠50岁| 久久综合亚洲精品| 波多野结衣的一区二区三区| 国产精品毛片va一区二区三区| 不卡亚洲精品| 日韩av免费看| 女人天堂av在线播放| 欧美午夜精品电影| 久久久无码精品亚洲国产| 国产欧美一区二区三区鸳鸯浴| 精品无码人妻少妇久久久久久| 日韩电影在线看| 男人操女人免费软件| 欧美激情视频一区二区三区在线播放 | 97国产精东麻豆人妻电影| 亚洲欧美在线专区| 亚洲美女网站18| 九一成人免费视频| 国产一区在线免费观看| 伊人www22综合色| 国产一区二区丝袜| 国产综合av| 97超碰色婷婷| 91色在线看| 欧美高清不卡在线| av在线免费网址| 日韩在线视频播放| 成人激情电影在线看| 亚洲欧美一区二区激情| 亚洲 欧美 精品| 亚洲黄色在线观看| 日本高清视频在线| 亚洲成年网站在线观看| hs视频在线观看| 日韩一区二区三区高清免费看看| 亚洲系列第一页| 欧美久久一区二区| 国产一区二区在线视频观看| 欧美视频日韩视频| 日本丰满少妇做爰爽爽| 一道本成人在线| 蜜臀尤物一区二区三区直播| 一本久久精品一区二区| 欧美一区二区三区网站| 一本一道久久a久久精品综合蜜臀| 日本韩国欧美中文字幕| 欧美丝袜一区二区三区| 国产剧情在线视频| 一本色道a无线码一区v| 日本一区二区三区久久| 欧美色视频在线| 91禁在线观看| 日韩一区二区三区电影在线观看| www.久久久久久久久久| 欧美va日韩va| 欧美自拍偷拍第一页| 国产偷国产偷亚洲清高网站| 可以直接在线观看的av| 永久免费毛片在线播放不卡| 浮生影视网在线观看免费| 少妇高潮久久77777| 1024在线播放| 韩剧1988在线观看免费完整版| 在线高清av| 国产精品午夜视频| 国产精品欧美一区二区三区不卡| 岛国视频一区免费观看| 国产一区二区三区亚洲| 欧美亚洲精品日韩| 91成人免费| 黄色大片中文字幕| 丝袜亚洲另类欧美| 激情图片中文字幕| 成人晚上爱看视频| 中文字幕在线1| 中文字幕一区三区| 日本在线观看中文字幕| 色伊人久久综合中文字幕| 夜夜嗨aⅴ一区二区三区| 欧美一级日韩免费不卡| 亚洲人午夜射精精品日韩| 伊人伊成久久人综合网小说| 国产传媒在线播放| 欧美在线观看网站| 高清精品久久| 欧美日韩在线不卡一区| 亚洲精品小说| 99精品视频播放| 国产老妇另类xxxxx| 国产精品无码午夜福利| 中文字幕一区二区三区视频| 日韩精品一区二区在线播放| 欧美性一级生活| 国产成人手机在线| 色多多国产成人永久免费网站| 福利小视频在线| 国产一区二区在线免费| 日本成人7777| 日韩精品久久一区二区| 日韩高清在线一区| 中文字幕无码人妻少妇免费| 成人免费在线视频| 日本黄色一级视频| 亚洲精品在线网站| 黄色网页在线免费看| 欧美一乱一性一交一视频| 国产一区二区三区视频在线| 欧美日韩视频在线一区二区观看视频| 亚洲自拍偷拍网| 精品久久久久久久无码| 91在线你懂得| 精品午夜福利在线观看| 欧美另类变人与禽xxxxx| 伦理片一区二区三区| 欧美激情视频在线观看| 婷婷久久免费视频| 欧美一区免费视频| 亚洲欧美日韩专区| 久久久久国产精品无码免费看| 亚洲丝袜另类动漫二区| 亚洲无码精品在线播放| 亚洲一区第一页| 国产精品一区二区av影院萌芽| 99re在线| 午夜天堂精品久久久久| 一级做a爱视频| 最新日韩在线视频| 一级黄色录像大片| 神马国产精品影院av| 欧美日韩国产网站| 欧美一区二区三区在线播放| 宅男噜噜噜66国产日韩在线观看| 大桥未久恸哭の女教师| 有坂深雪av一区二区精品| 国产三级精品在线观看| 久久精品视频在线观看| 国产69精品久久| 亚洲成人第一| 麻豆免费精品视频| 麻豆视频免费在线播放| 欧美三级电影网站| 最新av网站在线观看| 国产精品亚洲自拍| 奇米影视亚洲| 国模私拍视频在线观看| 国产精品麻豆网站| 国产又粗又黄又爽| 超薄丝袜一区二区| 最新国产精品精品视频| 精品国产一区二区三区无码| 国产91精品久久久久久久网曝门| 欧美黑人猛猛猛| 精品国产在天天线2019| 91高清视频在线观看| 久久久婷婷一区二区三区不卡| 性xx色xx综合久久久xx| 人妻少妇无码精品视频区| 欧美色区777第一页| 里番在线观看网站| av电影成人| 亚洲大胆视频| av中文字幕免费观看| 色综合欧美在线| 男人的天堂在线视频免费观看 | 亚洲天堂av一区| 午夜精品在线播放| 91成人国产在线观看| 欧美日韩在线二区| 亚洲一区二区中文字幕在线观看| 亚洲一二三四区| 国产精品99999| 91久久在线播放| 99精品福利视频| 五月婷婷六月香| 日韩一区二区免费在线电影| 国产高清视频色在线www| 青青草成人激情在线| 国产呦精品一区二区三区网站| www.99re7.com| 伊人激情综合网| 亚洲va欧美va人人爽成人影院| 国产精品无码av在线播放| 国产日韩欧美不卡| 亚洲国产精品国自产拍久久| 欧美在线观看日本一区| 中文字幕av亚洲精品一部二部| 亚洲一区二区在线免费| 欧美日韩精品欧美日韩精品一综合| 91亚洲天堂| 日本一区二区三区四区高清视频| 久草中文综合在线| 久久国产黄色片| 久久中文字幕国产| 免费看av成人| 久久久久亚洲av无码网站| 在线视频观看一区| 成人影音在线| 四虎影院一区二区| 久久精品欧美日韩精品|