精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

免费视频亚洲| 91看片一区| 99久久综合国产精品| 日本欧美国产在线| 免费精品在线视频| 一区二区三区视频免费视频观看网站| 偷拍亚洲欧洲综合| 一区二区视频在线播放| 黄色一级a毛片| 麻豆一区二区在线| 国内精品国产三级国产在线专| 精品人妻无码一区二区三区 | 粉色视频免费看| 国产精品一品| 国产精品理论片在线观看| 成人免费91在线看| 久久这里只有精品9| 亚洲无线视频| 日韩中文字幕国产| 国产男女猛烈无遮挡a片漫画| 在线免费观看亚洲| 日韩欧美有码在线| 成人免费看片'免费看| 一级毛片视频在线| 91蝌蚪porny成人天涯| 亚洲综合国产精品| 在线观看视频二区| 日日噜噜夜夜狠狠视频欧美人| 欧美疯狂性受xxxxx另类| 免费黄色在线网址 | 亚洲精品成人自拍| 午夜视频福利在线观看| 国产成人a级片| 成人国产精品一区二区| 日韩乱码一区二区三区| 免费在线亚洲欧美| 午夜精品久久久久久久99热浪潮| 免费污网站在线观看| 国产精品久久久久久久久久白浆| 91精品欧美一区二区三区综合在 | 亚洲成人av观看| 欧美日韩国产丝袜另类| 妞干网在线观看视频| 性爱视频在线播放| 亚洲精品午夜久久久| 一区二区三区四区在线视频| 国产高清在线| 国产亚洲美州欧州综合国 | 天天色天天射综合网| 一本久久综合亚洲鲁鲁| 性高潮久久久久久久| 五月综合久久| 亚洲精品一区在线观看香蕉| 美国黄色a级片| 欧美三级午夜理伦三级在线观看| 精品成人在线观看| 欧美xxxxx精品| 欧美午夜寂寞| 亚洲欧美日韩区| 亚洲精品午夜视频| 日韩在线不卡| 久久影视免费观看| 国产大片免费看| 欧美日韩免费观看一区=区三区| 久久成人免费视频| 久久久香蕉视频| 99riav1国产精品视频| 5566日本婷婷色中文字幕97| 欧美国产成人精品一区二区三区| 久久精品一区二区国产| 国产精品男人爽免费视频1| 中文字幕久久久久| 国产一区二区三区四| 国产精品区一区二区三在线播放| 五月婷婷伊人网| 久久免费视频色| 亚洲巨乳在线观看| huan性巨大欧美| 五月综合激情日本mⅴ| 日韩精品一区二区三区色欲av| 日韩天堂在线| 91精品国产综合久久福利软件| 波多野结衣电影免费观看| 精品成人自拍视频| 国产亚洲免费的视频看| 国产又粗又猛又爽又黄的视频四季 | 二区三区四区视频| 亚洲免费观看| 国产精品美女久久久久av超清| 国产三级小视频| 99视频一区二区三区| 视频三区二区一区| 污视频网站在线免费| 色综合久久综合网| 国产高清av片| 亚洲+变态+欧美+另类+精品| 色妞欧美日韩在线| 日韩熟女精品一区二区三区| 蜜芽一区二区三区| 国产成人成网站在线播放青青| 每日更新av在线播放| 日韩码欧中文字| 成人久久久久久久久| 国产高清亚洲| 亚洲系列中文字幕| 国产一级在线观看视频| 裸体一区二区三区| 好吊妞www.84com只有这里才有精品 | 99视频热这里只有精品免费| 亚洲毛片aa| 亚洲美女久久精品| 欧美成人vps| 中文乱码字幕高清一区二区| 国产亚洲网站| 国产精品久久7| 国产精品va在线观看视色| 狠狠久久五月精品中文字幕| 国产黑丝在线视频| 欧美中文字幕一区二区| 91精品国产91| 亚洲精品久久久久久久久久| 国产精品精品国产色婷婷| 日本中文字幕片| 国产精品主播在线观看| 欧美不卡视频一区发布| 在线观看免费高清视频| 久久色在线视频| 免费国产黄色网址| 精品按摩偷拍| 欧美极品在线播放| 国产高中女学生第一次| 国产精品久久久久久久久免费桃花 | 久久综合图片| 久久99国产精品99久久| 123区在线| 精品久久久久久久久久久久久久久 | 91精品国产色综合| 男人天堂一区二区| 亚洲综合图片区| 亚洲熟妇一区二区| 欧美fxxxxxx另类| 亚洲free性xxxx护士hd| 国产超级va在线视频| 91精品国产综合久久精品性色| 91社区视频在线观看| 美女视频免费一区| 一卡二卡3卡四卡高清精品视频| 男人最爱成人网| 亚洲欧美日韩天堂| а中文在线天堂| 国产婷婷色一区二区三区在线| 精品久久久久久久免费人妻| 亚洲va久久| 国产国语刺激对白av不卡| 国产小视频福利在线| 欧美综合视频在线观看| 国产激情av在线| 久久99国产精品成人| 中文字幕欧美人与畜| 蜜桃在线一区| 久久久久久久久中文字幕| 日本久久一级片| 欧美日韩国产在线播放| 91精品人妻一区二区三区| 视频一区欧美精品| 中文字幕综合在线观看| 精品一区二区三区中文字幕| 久久久久中文字幕2018| 完全免费av在线播放| 日韩精彩视频在线观看| 亚洲一区二区免费视频软件合集 | 日韩av网站在线播放| 国产尤物一区二区| 欧美高清中文字幕| 久久不见久久见免费视频7| 国产精品久久久久av| 精品自拍一区| 亚洲福利在线看| 中文字幕手机在线视频| 中文字幕永久在线不卡| 黄色激情在线观看| 巨乳诱惑日韩免费av| 一区二区三区久久网| 99a精品视频在线观看| 清纯唯美日韩制服另类| 久久黄色美女电影| 亚洲激情视频在线| 一道本在线视频| 亚洲www啪成人一区二区麻豆| 91网站免费视频| 国产精品77777| 日韩中文字幕免费在线| 欧美国产精品| 日韩精品在在线一区二区中文| 色综合视频一区二区三区44| 高清在线视频日韩欧美| 成人av一区| 亚洲国产天堂久久综合| 国产精品久久欧美久久一区| 午夜av区久久| 亚洲国产成人精品综合99| 久久久精品国产免费观看同学| 日本黄色www| 日本不卡一二三区黄网| 国产日韩av网站| 国产高清欧美| 欧美一区视久久| 超碰97久久国产精品牛牛| 国产精品入口免费视| 超碰激情在线| 欧美精品在线免费观看| 日韩黄色影院| 亚洲国产精品va在线看黑人| 国产特黄一级片| 欧美三级视频在线| 800av免费在线观看| 夜夜精品视频一区二区| 99自拍视频在线| 亚洲国产精品传媒在线观看| 亚洲精品女人久久久| 国产乱理伦片在线观看夜一区| wwwwxxxx日韩| 另类国产ts人妖高潮视频| a级免费在线观看| 欧美va天堂| 欧美日韩一区二区三区电影| 国产精品欧美三级在线观看| 久久国产精品99久久久久久丝袜| 欧州一区二区三区| 91欧美精品午夜性色福利在线| 日韩欧美精品电影| 国产高清视频一区三区| 美女福利一区二区三区| 韩国三级日本三级少妇99| 婷婷av在线| 欧美成人精品一区二区| 成人午夜在线影视| 久久亚洲精品一区二区| 日p在线观看| 精品精品国产国产自在线| h视频网站在线观看| 中文字幕日韩欧美在线 | 国产精品污网站| 日韩欧美黄色网址| 亚洲国产成人一区二区三区| 韩国女同性做爰三级| 国产日韩精品一区二区三区| 久久精品视频18| 国产欧美精品一区二区色综合朱莉| 欧美图片一区二区| 久久综合狠狠综合久久综合88| 久久人人妻人人人人妻性色av| 99视频有精品| 一级片视频免费看| 国产精品久久久久7777按摩| 一级黄色片日本| 亚洲靠逼com| 国产精品18p| 精品久久久久久久久久久久久| 亚洲黄色激情视频| 日本精品视频一区二区| 伊人网视频在线| 欧美一区二区三区白人| 黄色av免费观看| 日韩精品视频中文在线观看| 黄视频在线观看免费| 中文字幕最新精品| 午夜dj在线观看高清视频完整版 | japanese23hdxxxx日韩| 国产精品色视频| 精品一区二区三区亚洲| 国产午夜精品在线| 国产一区二区三区网| 不卡中文字幕在线| 精品999网站| 中文字幕国内自拍| 国产成人综合自拍| 国产精品亚洲无码| 亚洲欧洲精品一区二区三区| 国产无遮无挡120秒| 日本高清不卡一区| 国产日韩欧美视频在线观看| 亚洲第一在线视频| 91社区在线观看播放| 久久777国产线看观看精品| 麻豆成全视频免费观看在线看| 国产精品久久久久久久久久久新郎| 亚洲青青久久| 久久综合精品一区| 91精品国产自产在线观看永久∴| 秋霞无码一区二区| 久久99国产精品免费| 北岛玲一区二区| 亚洲欧洲综合另类| 午夜婷婷在线观看| 精品免费视频一区二区| 国产污视频在线| 久久久久久伊人| 久久精品黄色| 久久偷窥视频| 自拍日韩欧美| 99视频在线视频| aaa亚洲精品| 国产盗摄x88av| 欧美日韩午夜精品| 日本在线视频1区| 欧美国产日本高清在线| 黄色精品视频| 精品在线观看一区二区| 欧美一区国产在线| av在线网址导航| 2024国产精品| 欧美激情一区二区视频| 欧美日韩一区 二区 三区 久久精品| 日韩在线观看视频一区| 久久影院免费观看| 国产资源一区| 日产国产精品精品a∨| 妖精视频成人观看www| 无码国产精品一区二区高潮| 中文字幕一区二区三区在线播放| 手机在线看片1024| 亚洲成人999| 免费在线播放电影| 91在线免费看网站| 欧美va久久久噜噜噜久久| 成年人小视频网站| 91色|porny| 亚洲黄色小说图片| 亚洲精品国精品久久99热| 精品精品导航| 成人动漫视频在线观看免费| 97精品国产福利一区二区三区| 欧洲熟妇精品视频| 久久久精品蜜桃| 天天爱天天做天天爽| 亚洲香蕉伊综合在人在线视看| 亚洲一级少妇| 麻豆91av| 日韩精品1区2区3区| 中国女人特级毛片| 欧美午夜一区二区| 成人影院免费观看| 国产精品丝袜白浆摸在线| 欧美最新另类人妖| 艹b视频在线观看| 一色屋精品亚洲香蕉网站| 一级片视频免费| 久久九九有精品国产23| 久久免费福利| 91网站在线观看免费| 丰满白嫩尤物一区二区| 日本熟妇乱子伦xxxx| 日韩h在线观看| 久九九久频精品短视频| 深田咏美在线x99av| 麻豆国产欧美一区二区三区| 久久嫩草捆绑紧缚| 日韩欧美色综合| 成人三级高清视频在线看| 精品视频导航| 久久午夜精品一区二区| 亚洲女同二女同志奶水| 717成人午夜免费福利电影| 伊人手机在线| 精品欧美日韩| 蜜臀av在线播放一区二区三区| 永久免费看片直接| 精品福利av导航| 裤袜国产欧美精品一区| 亚洲蜜桃av| 成人做爰69片免费看网站| 日日摸天天添天天添破| 主播福利视频一区| 18国产精品| 成人免费观看毛片| 亚洲欧美日韩在线不卡| 亚洲三区在线观看无套内射| 国产精品www色诱视频| 一区二区在线影院| 精品国产人妻一区二区三区| 欧美日韩五月天| аⅴ资源天堂资源库在线| 视频一区视频二区视频| 国产成人午夜精品影院观看视频| 青青操免费在线视频| 久久精品国产久精国产一老狼 | 久久网一区二区| 亚洲人成网在线播放| 亚洲国产欧美国产第一区| 国产日韩一区二区在线观看| 亚洲日本青草视频在线怡红院| 五十路在线视频| 91精品国产综合久久久久久久久| 在线日韩av| 日本不卡一二区| 亚洲精品在线看| 一本色道69色精品综合久久| 男人操女人免费| 亚洲伊人色欲综合网|