<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      DDD | 02-值對象拓展示例

      示例拓展

      金額和貨幣

      創(chuàng)建一個表示金額和貨幣的值對象(AmountVO),在系統(tǒng)中統(tǒng)一處理貨幣相關(guān)的數(shù)據(jù),確保精度和一致性。

      import java.math.BigDecimal;
      import java.util.Currency;
      
      /**
      * 這個AmountVO類使用BigDecimal來精確存儲金額值,避免了浮點(diǎn)運(yùn)算可能帶來的精度問題。
      同時,利用Currency類來表示貨幣類型,確保了貨幣信息的標(biāo)準(zhǔn)化。
      此外,重寫了equals、hashCode和toString方法以支持比較、哈希運(yùn)算和提供人性化的字符串表示。
      */
      public class AmountVO {
      
          private final BigDecimal value; // 金額值,使用BigDecimal以精確表示貨幣值
          private final Currency currency; // 貨幣類型,使用Java標(biāo)準(zhǔn)庫中的Currency類
      
          /**
           * 構(gòu)造一個新的金額值對象。
           *
           * @param value   金額值,要求為正數(shù)
           * @param currency 貨幣類型
           */
          public AmountVO(BigDecimal value, Currency currency) {
              if (value.compareTo(BigDecimal.ZERO) < 0) {
                  throw new IllegalArgumentException("Amount value must not be negative.");
              }
              this.value = value;
              this.currency = currency;
          }
      
          /**
           * 獲取金額值。
           *
           * @return 金額值
           */
          public BigDecimal getValue() {
              return value;
          }
      
          /**
           * 獲取貨幣類型。
           *
           * @return 貨幣類型
           */
          public Currency getCurrency() {
              return currency;
          }
      
          /**
           * 檢查兩個AmountVO實(shí)例是否代表相同的金額(考慮貨幣)。
           *
           * @param obj 另一個AmountVO實(shí)例
           * @return 如果金額和貨幣都相同則返回true,否則返回false
           */
          @Override
          public boolean equals(Object obj) {
              if (this == obj) return true;
              if (obj == null || getClass() != obj.getClass()) return false;
              AmountVO amountVO = (AmountVO) obj;
              return value.equals(amountVO.value) && currency.getCurrencyCode().equals(amountVO.currency.getCurrencyCode());
          }
      
          /**
           * 生成基于金額和貨幣類型的哈希碼。
           *
           * @return 哈希碼
           */
          @Override
          public int hashCode() {
              return Objects.hash(value, currency.getCurrencyCode());
          }
      
          /**
           * 提供一個友好的字符串表示形式,包括金額和貨幣代碼。
           *
           * @return 字符串表示形式,如 "123.45 USD"
           */
          @Override
          public String toString() {
              return value + " " + currency.getCurrencyCode();
          }
      }
      
      

      為什么金額和貨幣可以是值對象?

      金額和貨幣作為值對象(Value Object)的原因在于它們符合值對象的核心特征和設(shè)計(jì)原則,具體體現(xiàn)在以下幾個方面:

      • 不可變性:金額和貨幣組合表示的是一個具體的、不變的值,比如“100美元”或“50歐元”。一旦創(chuàng)建,這個組合不應(yīng)該被改變,這符合值對象通常設(shè)計(jì)為不可變對象的原則。
      • 相等性基于值:兩個金額和貨幣的組合如果數(shù)值和貨幣種類完全相同,就被視為相等,這與值對象的相等性定義一致,即通過其內(nèi)在狀態(tài)而非身份(內(nèi)存地址)來判斷是否相等。
      • 無唯一標(biāo)識:與實(shí)體對象(Entity)不同,值對象沒有唯一的、持久的身份標(biāo)識。無論在系統(tǒng)中出現(xiàn)多少次“100美元”,它們都是等價的,不需要區(qū)分是哪個具體的實(shí)例。
      • 可共享:由于值對象表示的是不變的值,因此多個對象可以安全地共享同一個值對象實(shí)例,這有助于節(jié)省內(nèi)存并簡化邏輯,尤其是在表達(dá)如商品價格、賬戶余額等場景時。
      • 封裝復(fù)雜性:將金額和貨幣封裝在一個值對象中,可以隱藏貨幣轉(zhuǎn)換、格式化等復(fù)雜邏輯,對外提供簡潔的接口,提高了代碼的可讀性和可維護(hù)性。
      • 領(lǐng)域驅(qū)動設(shè)計(jì)(DDD)中的概念匹配:在領(lǐng)域驅(qū)動設(shè)計(jì)中,值對象用來描述沒有唯一標(biāo)識符但具有某種描述性的對象。金額和貨幣的組合正是對現(xiàn)實(shí)世界中經(jīng)濟(jì)交易的一種描述,適合用值對象來建模。

      綜上所述,將金額和貨幣設(shè)計(jì)為值對象,能夠有效地提升代碼的清晰度、一致性和可維護(hù)性,同時確保了在處理財(cái)務(wù)數(shù)據(jù)時的準(zhǔn)確性和安全性。

      創(chuàng)建一個表示價格的值對象(PriceVO)是一個很好的方式來封裝和管理商品價格相關(guān)的數(shù)據(jù),確保數(shù)據(jù)的一致性和精確計(jì)算。

      import java.math.BigDecimal;
      import java.util.Currency;
      
      /**
      * 這個PriceVO類不僅封裝了價格的金額和貨幣類型,還提供了一個計(jì)算含稅價格的方法getTaxInclusiveAmount(),并允許在構(gòu)造時指定稅率。
      * 這樣的設(shè)計(jì)使得價格的處理變得靈活且易于理解,同時也保證了在進(jìn)行價格計(jì)算時的準(zhǔn)確性和一致性。
      */
      public class PriceVO {
      
          private final BigDecimal amount; // 價格金額,使用BigDecimal確保精度
          private final Currency currency; // 貨幣類型
          private final BigDecimal taxRate; // 稅率,默認(rèn)為0,表示不含稅
      
          /**
           * 構(gòu)造一個新的價格值對象。
           *
           * @param amount   價格金額,必須大于0
           * @param currency 貨幣類型
           * @param taxRate  稅率,例如0.08表示8%的稅率,默認(rèn)為0
           */
          public PriceVO(BigDecimal amount, Currency currency, BigDecimal taxRate) {
              if (amount.compareTo(BigDecimal.ZERO) <= 0) {
                  throw new IllegalArgumentException("Price amount must be greater than zero.");
              }
              this.amount = amount;
              this.currency = currency;
              this.taxRate = taxRate != null ? taxRate : BigDecimal.ZERO;
          }
      
          /**
           * 獲取價格金額。
           *
           * @return 價格金額
           */
          public BigDecimal getAmount() {
              return amount;
          }
      
          /**
           * 獲取貨幣類型。
           *
           * @return 貨幣類型
           */
          public Currency getCurrency() {
              return currency;
          }
      
          /**
           * 獲取含稅價格。
           *
           * @return 含稅價格
           */
          public BigDecimal getTaxInclusiveAmount() {
              if (taxRate.compareTo(BigDecimal.ZERO) > 0) {
                  return amount.multiply(BigDecimal.ONE.add(taxRate));
              }
              return amount;
          }
      
          /**
           * 獲取稅率。
           *
           * @return 稅率
           */
          public BigDecimal getTaxRate() {
              return taxRate;
          }
      
          @Override
          public boolean equals(Object o) {
              if (this == o) return true;
              if (o == null || getClass() != o.getClass()) return false;
              PriceVO priceVO = (PriceVO) o;
              return amount.equals(priceVO.amount) &&
                     currency.equals(priceVO.currency) &&
                     taxRate.equals(priceVO.taxRate);
          }
      
          @Override
          public int hashCode() {
              return Objects.hash(amount, currency, taxRate);
          }
      
          @Override
          public String toString() {
              return amount + " " + currency.getCurrencyCode() +
                     (taxRate.compareTo(BigDecimal.ZERO) > 0 ? " (Tax: " + taxRate.multiply(new BigDecimal(100)) + "%)" : "");
          }
      }
      
      

      創(chuàng)建一個表示工資的值對象(SalaryVO)可以用來封裝員工薪資的細(xì)節(jié),包括基本工資、獎金、扣款等部分,并支持不同貨幣類型。

      import java.math.BigDecimal;
      import java.util.Currency;
      
      /**
      * 這個SalaryVO類封裝了工資計(jì)算的各個方面,包括基本工資、獎金和扣款,并提供了計(jì)算總工資的方法getTotalSalary()。
      * 通過使用BigDecimal類型來存儲金額,確保了計(jì)算的精確度。此外,它還支持不同貨幣類型,增加了適用范圍。
      * 這樣的設(shè)計(jì)使得工資數(shù)據(jù)的處理更加清晰和高效,易于維護(hù)和擴(kuò)展。
      */
      public class SalaryVO {
      
          private final BigDecimal baseSalary; // 基本工資
          private final BigDecimal bonus; // 獎金,默認(rèn)為0
          private final BigDecimal deductions; // 扣款,默認(rèn)為0
          private final Currency currency; // 貨幣類型
      
          /**
           * 構(gòu)造一個新的工資值對象。
           *
           * @param baseSalary  基本工資,必須大于0
           * @param bonus       獎金,默認(rèn)為0
           * @param deductions  扣款,默認(rèn)為0
           * @param currency    貨幣類型
           */
          public SalaryVO(BigDecimal baseSalary, BigDecimal bonus, BigDecimal deductions, Currency currency) {
              if (baseSalary.compareTo(BigDecimal.ZERO) <= 0) {
                  throw new IllegalArgumentException("Base salary must be greater than zero.");
              }
              this.baseSalary = baseSalary;
              this.bonus = bonus != null ? bonus : BigDecimal.ZERO;
              this.deductions = deductions != null ? deductions : BigDecimal.ZERO;
              this.currency = currency;
          }
      
          /**
           * 獲取基本工資。
           *
           * @return 基本工資
           */
          public BigDecimal getBaseSalary() {
              return baseSalary;
          }
      
          /**
           * 獲取獎金。
           *
           * @return 獎金
           */
          public BigDecimal getBonus() {
              return bonus;
          }
      
          /**
           * 獲取扣款。
           *
           * @return 扣款
           */
          public BigDecimal getDeductions() {
              return deductions;
          }
      
          /**
           * 獲取總工資,即基本工資加上獎金減去扣款。
           *
           * @return 總工資
           */
          public BigDecimal getTotalSalary() {
              return baseSalary.add(bonus).subtract(deductions);
          }
      
          /**
           * 獲取貨幣類型。
           *
           * @return 貨幣類型
           */
          public Currency getCurrency() {
              return currency;
          }
      
          @Override
          public boolean equals(Object o) {
              if (this == o) return true;
              if (o == null || getClass() != o.getClass()) return false;
              SalaryVO salaryVO = (SalaryVO) o;
              return baseSalary.equals(salaryVO.baseSalary) &&
                     bonus.equals(salaryVO.bonus) &&
                     deductions.equals(salaryVO.deductions) &&
                     currency.equals(salaryVO.currency);
          }
      
          @Override
          public int hashCode() {
              return Objects.hash(baseSalary, bonus, deductions, currency);
          }
      
          @Override
          public String toString() {
              return "Salary{" +
                     "baseSalary=" + baseSalary +
                     ", bonus=" + bonus +
                     ", deductions=" + deductions +
                     ", totalSalary=" + getTotalSalary() +
                     ", currency=" + currency.getCurrencyCode() +
                     '}';
          }
      }
      
      

      創(chuàng)建一個費(fèi)用值對象(ExpenseVO)可以幫助我們統(tǒng)一管理和計(jì)算各種費(fèi)用項(xiàng),確保數(shù)據(jù)的準(zhǔn)確性和一致性。

      import java.time.LocalDate;
      import java.math.BigDecimal;
      import java.util.Currency;
      
      /**
      * 這個ExpenseVO類封裝了費(fèi)用的基本信息,如費(fèi)用名稱、金額、貨幣類型和發(fā)生日期,提供了獲取這些屬性的方法。
      * 通過使用BigDecimal類型來處理金額,確保了金額計(jì)算的精確性。
      * 此外,它還允許在創(chuàng)建時指定費(fèi)用發(fā)生的特定日期,或者默認(rèn)為創(chuàng)建時的當(dāng)前日期。
      * 這樣的設(shè)計(jì)使得費(fèi)用數(shù)據(jù)的管理更加規(guī)范和靈活。
      */
      public class ExpenseVO {
      
          private final String title; // 費(fèi)用標(biāo)題或名稱
          private final BigDecimal amount; // 費(fèi)用金額,使用BigDecimal確保精度
          private final Currency currency; // 費(fèi)用貨幣類型
          private final LocalDate date; // 費(fèi)用發(fā)生日期,默認(rèn)為當(dāng)前日期
      
          /**
           * 構(gòu)造一個新的費(fèi)用值對象。
           *
           * @param title    費(fèi)用標(biāo)題或名稱,不能為空
           * @param amount   費(fèi)用金額,必須大于0
           * @param currency 費(fèi)用貨幣類型,不能為空
           * @param date     費(fèi)用發(fā)生日期,默認(rèn)為當(dāng)前日期
           */
          public ExpenseVO(String title, BigDecimal amount, Currency currency, LocalDate date) {
              if (title == null || title.isEmpty()) {
                  throw new IllegalArgumentException("Expense title cannot be null or empty.");
              }
              if (amount.compareTo(BigDecimal.ZERO) <= 0) {
                  throw new IllegalArgumentException("Expense amount must be greater than zero.");
              }
              if (currency == null) {
                  throw new IllegalArgumentException("Currency cannot be null.");
              }
              this.title = title;
              this.amount = amount;
              this.currency = currency;
              this.date = date != null ? date : LocalDate.now();
          }
      
          /**
           * 獲取費(fèi)用標(biāo)題或名稱。
           *
           * @return 費(fèi)用標(biāo)題
           */
          public String getTitle() {
              return title;
          }
      
          /**
           * 獲取費(fèi)用金額。
           *
           * @return 費(fèi)用金額
           */
          public BigDecimal getAmount() {
              return amount;
          }
      
          /**
           * 獲取貨幣類型。
           *
           * @return 貨幣類型
           */
          public Currency getCurrency() {
              return currency;
          }
      
          /**
           * 獲取費(fèi)用發(fā)生日期。
           *
           * @return 費(fèi)用日期
           */
          public LocalDate getDate() {
              return date;
          }
      
          @Override
          public boolean equals(Object o) {
              if (this == o) return true;
              if (o == null || getClass() != o.getClass()) return false;
              ExpenseVO expenseVO = (ExpenseVO) o;
              return title.equals(expenseVO.title) &&
                     amount.equals(expenseVO.amount) &&
                     currency.equals(expenseVO.currency) &&
                     date.equals(expenseVO.date);
          }
      
          @Override
          public int hashCode() {
              return Objects.hash(title, amount, currency, date);
          }
      
          @Override
          public String toString() {
              return "Expense{" +
                     "title='" + title + '\'' +
                     ", amount=" + amount +
                     ", currency=" + currency.getCurrencyCode() +
                     ", date=" + date +
                     '}';
          }
      }
      
      

      度量數(shù)據(jù)

      創(chuàng)建一個重量值對象(WeightVO)可以用來封裝和處理重量相關(guān)的數(shù)據(jù),確保在系統(tǒng)中重量的表示和計(jì)算具有一致性和準(zhǔn)確性

      /**
      * 這個WeightVO類使用BigDecimal來存儲重量值,確保了數(shù)值的精確度,適用于需要高精度計(jì)算的場景。
      * 同時,它定義了重量單位,使得重量的表示更加完整和明確。
      * 盡管在這個基本實(shí)現(xiàn)中沒有包含單位轉(zhuǎn)換邏輯,但在實(shí)際應(yīng)用中可以根據(jù)需要擴(kuò)展此類,
      * 增加單位之間的轉(zhuǎn)換方法,以適應(yīng)不同場景下的重量計(jì)量需求。
      */
      
      public class WeightVO {
      
          private final BigDecimal value; // 重量值,使用BigDecimal確保精度
          private final String unit; // 重量單位,如 "kg"(千克)、"g"(克)、"lb"(磅)
      
          /**
           * 構(gòu)造一個新的重量值對象。
           *
           * @param value 重量值,必須大于等于0
           * @param unit  重量單位,不能為空,建議使用標(biāo)準(zhǔn)單位
           */
          public WeightVO(BigDecimal value, String unit) {
              if (value.compareTo(BigDecimal.ZERO) < 0) {
                  throw new IllegalArgumentException("Weight value must be non-negative.");
              }
              if (unit == null || unit.trim().isEmpty()) {
                  throw new IllegalArgumentException("Weight unit cannot be null or empty.");
              }
              this.value = value;
              this.unit = unit.trim().toLowerCase(); // 統(tǒng)一單位為小寫,便于比較
          }
      
          /**
           * 獲取重量值。
           *
           * @return 重量值
           */
          public BigDecimal getValue() {
              return value;
          }
      
          /**
           * 獲取重量單位。
           *
           * @return 重量單位
           */
          public String getUnit() {
              return unit;
          }
      
          /**
           * 檢查兩個WeightVO實(shí)例是否表示相同的重量(忽略單位差異)。
           *
           * @param obj 另一個WeightVO實(shí)例
           * @return 如果重量值相同則返回true,否則返回false
           */
          @Override
          public boolean equals(Object obj) {
              if (this == obj) return true;
              if (obj == null || getClass() != obj.getClass()) return false;
              WeightVO weightVO = (WeightVO) obj;
              return value.compareTo(weightVO.value) == 0;
          }
      
          @Override
          public int hashCode() {
              return Objects.hash(value);
          }
      
          /**
           * 提供一個友好的字符串表示形式,包括重量值和單位。
           *
           * @return 字符串表示形式,如 "2.5 kg"
           */
          @Override
          public String toString() {
              return value + " " + unit;
          }
      }
      
      

      創(chuàng)建一個長度值對象(LengthVO)旨在封裝長度數(shù)據(jù)及其單位,確保在處理尺寸和距離時的精確性和一致性。

      import java.math.BigDecimal;
      
      /**
      * 這個LengthVO類通過使用BigDecimal來存儲長度值,
      * 確保了數(shù)值的高精度處理,適合于需要精確測量和計(jì)算的場景。
      * 同時,它定義了長度單位,使得長度的表述更為明確和規(guī)范。
      * 雖然這個基本版本未包含單位轉(zhuǎn)換功能,但可以根據(jù)實(shí)際需求擴(kuò)展此類,
      * 添加不同單位間的轉(zhuǎn)換方法,以適應(yīng)多樣的長度計(jì)量需求。
      */
      public class LengthVO {
      
          private final BigDecimal value; // 長度值,使用BigDecimal確保精度
          private final String unit; // 長度單位,如 "m"(米)、"cm"(厘米)、"in"(英寸)
      
          /**
           * 構(gòu)造一個新的長度值對象。
           *
           * @param value 長度值,必須大于等于0
           * @param unit  長度單位,不能為空,建議使用標(biāo)準(zhǔn)單位
           */
          public LengthVO(BigDecimal value, String unit) {
              if (value.compareTo(BigDecimal.ZERO) < 0) {
                  throw new IllegalArgumentException("Length value must be non-negative.");
              }
              if (unit == null || unit.trim().isEmpty()) {
                  throw new IllegalArgumentException("Length unit cannot be null or empty.");
              }
              this.value = value;
              this.unit = unit.trim().toLowerCase(); // 統(tǒng)一單位為小寫,便于比較
          }
      
          /**
           * 獲取長度值。
           *
           * @return 長度值
           */
          public BigDecimal getValue() {
              return value;
          }
      
          /**
           * 獲取長度單位。
           *
           * @return 長度單位
           */
          public String getUnit() {
              return unit;
          }
      
          /**
           * 檢查兩個LengthVO實(shí)例是否表示相同的長度(忽略單位差異)。
           *
           * @param obj 另一個LengthVO實(shí)例
           * @return 如果長度值相同則返回true,否則返回false
           */
          @Override
          public boolean equals(Object obj) {
              if (this == obj) return true;
              if (obj == null || getClass() != obj.getClass()) return false;
              LengthVO lengthVO = (LengthVO) obj;
              return value.compareTo(lengthVO.value) == 0;
          }
      
          @Override
          public int hashCode() {
              return Objects.hash(value);
          }
      
          /**
           * 提供一個友好的字符串表示形式,包括長度值和單位。
           *
           * @return 字符串表示形式,如 "1.5 m"
           */
          @Override
          public String toString() {
              return value + " " + unit;
          }
      }
      
      

      創(chuàng)建一個體積值對象(VolumeVO)用于封裝和處理體積相關(guān)的數(shù)據(jù),確保在系統(tǒng)中體積的表示和計(jì)算既精確又一致

      import java.math.BigDecimal;
      
      /**
      * 這個VolumeVO類利用BigDecimal來存儲體積值,確保了在處理體積數(shù)據(jù)時的高精度。
      * 它還定義了體積單位,使得體積的表示更加標(biāo)準(zhǔn)化和清晰。
      * 盡管此基本版本沒有包含單位轉(zhuǎn)換邏輯,但根據(jù)實(shí)際應(yīng)用場景,
      * 你可以進(jìn)一步擴(kuò)展此類,加入不同體積單位之間的轉(zhuǎn)換方法,
      * 以提高其在多場景下的適用性和便利性。
      */
      public class VolumeVO {
      
          private final BigDecimal value; // 體積值,使用BigDecimal確保精度
          private final String unit; // 體積單位,如 "m3"(立方米)、"L"(升)、"gal"(加侖)
      
          /**
           * 構(gòu)造一個新的體積值對象。
           *
           * @param value 體積值,必須大于等于0
           * @param unit  體積單位,不能為空,建議使用標(biāo)準(zhǔn)單位
           */
          public VolumeVO(BigDecimal value, String unit) {
              if (value.compareTo(BigDecimal.ZERO) < 0) {
                  throw new IllegalArgumentException("Volume value must be non-negative.");
              }
              if (unit == null || unit.trim().isEmpty()) {
                  throw new IllegalArgumentException("Volume unit cannot be null or empty.");
              }
              this.value = value;
              this.unit = unit.trim().toLowerCase(); // 統(tǒng)一單位為小寫,便于比較
          }
      
          /**
           * 獲取體積值。
           *
           * @return 體積值
           */
          public BigDecimal getValue() {
              return value;
          }
      
          /**
           * 獲取體積單位。
           *
           * @return 體積單位
           */
          public String getUnit() {
              return unit;
          }
      
          /**
           * 檢查兩個VolumeVO實(shí)例是否表示相同的體積(忽略單位差異)。
           *
           * @param obj 另一個VolumeVO實(shí)例
           * @return 如果體積值相同則返回true,否則返回false
           */
          @Override
          public boolean equals(Object obj) {
              if (this == obj) return true;
              if (obj == null || getClass() != obj.getClass()) return false;
              VolumeVO volumeVO = (VolumeVO) obj;
              return value.compareTo(volumeVO.value) == 0;
          }
      
          @Override
          public int hashCode() {
              return Objects.hash(value);
          }
      
          /**
           * 提供一個友好的字符串表示形式,包括體積值和單位。
           *
           * @return 字符串表示形式,如 "2.5 m3"
           */
          @Override
          public String toString() {
              return value + " " + unit;
          }
      }
      
      

      范圍或區(qū)間

      創(chuàng)建一個日期范圍值對象(DateRangeVO)可以用來表示起始日期和結(jié)束日期之間的一個時間區(qū)間,這對于處理時間段查詢、事件安排等場景非常有用。

      import java.time.LocalDate;
      
      /**
      * 這個DateRangeVO類使用LocalDate來表示起始和結(jié)束日期,確保了日期操作的便捷性和準(zhǔn)確性。
      * 它提供了判斷日期是否在范圍內(nèi)、計(jì)算持續(xù)天數(shù)等實(shí)用方法,以及重寫了equals和hashCode方法以支持正確的比較和哈希運(yùn)算。
      * 這樣的設(shè)計(jì)使得處理日期范圍相關(guān)的業(yè)務(wù)邏輯變得更加簡單和高效。
      */
      public class DateRangeVO {
      
          private final LocalDate startDate; // 起始日期,包含該日
          private final LocalDate endDate; // 結(jié)束日期,包含該日
      
          /**
           * 構(gòu)造一個新的日期范圍值對象。
           *
           * @param startDate 起始日期,必須不晚于結(jié)束日期
           * @param endDate   結(jié)束日期,必須不早于起始日期
           */
          public DateRangeVO(LocalDate startDate, LocalDate endDate) {
              if (startDate.isAfter(endDate)) {
                  throw new IllegalArgumentException("Start date must be on or before end date.");
              }
              this.startDate = startDate;
              this.endDate = endDate;
          }
      
          /**
           * 獲取起始日期。
           *
           * @return 起始日期
           */
          public LocalDate getStartDate() {
              return startDate;
          }
      
          /**
           * 獲取結(jié)束日期。
           *
           * @return 結(jié)束日期
           */
          public LocalDate getEndDate() {
              return endDate;
          }
      
          /**
           * 判斷給定的日期是否位于當(dāng)前日期范圍內(nèi)。
           *
           * @param date 要檢查的日期
           * @return 如果date在范圍內(nèi)則返回true,否則返回false
           */
          public boolean contains(LocalDate date) {
              return !date.isBefore(startDate) && !date.isAfter(endDate);
          }
      
          /**
           * 計(jì)算日期范圍的持續(xù)天數(shù)。
           *
           * @return 日期范圍內(nèi)的天數(shù)
           */
          public long durationDays() {
              return ChronoUnit.DAYS.between(startDate, endDate) + 1; // 加1是因?yàn)閮啥巳掌诙及趦?nèi)
          }
      
          @Override
          public boolean equals(Object obj) {
              if (this == obj) return true;
              if (obj == null || getClass() != obj.getClass()) return false;
              DateRangeVO that = (DateRangeVO) obj;
              return startDate.equals(that.startDate) && endDate.equals(that.endDate);
          }
      
          @Override
          public int hashCode() {
              return Objects.hash(startDate, endDate);
          }
      
          /**
           * 提供一個友好的字符串表示形式,包括起始和結(jié)束日期。
           *
           * @return 字符串表示形式,如 "2023-04-01 to 2023-04-7"
           */
          @Override
          public String toString() {
              return startDate + " to " + endDate;
          }
      }
      
      

      創(chuàng)建一個溫度區(qū)間值對象(TemperatureRangeVO)可以用來表示一個最低溫度到最高溫度之間的區(qū)間,這對于氣象預(yù)報、工業(yè)控制等領(lǐng)域非常有用。

      import java.math.BigDecimal;
      
      /**
      * 這個TemperatureRangeVO類使用BigDecimal來存儲溫度值,確保了溫度讀數(shù)的高精度。
      * 它定義了溫度單位,并提供了判斷某個溫度是否在給定區(qū)間內(nèi)的方法,以及覆蓋了equals和hashCode方法以支持對象的正確比較和集合操作。
      * 這樣的設(shè)計(jì)使得處理溫度區(qū)間的數(shù)據(jù)更加方便和準(zhǔn)確。
      */
      public class TemperatureRangeVO {
      
          private final BigDecimal minValue; // 最低溫度值,使用BigDecimal確保精度
          private final BigDecimal maxValue; // 最高溫度值,使用BigDecimal確保精度
          private final String unit; // 溫度單位,如 "C"(攝氏度)或 "F"(華氏度)
      
          /**
           * 構(gòu)造一個新的溫度區(qū)間值對象。
           *
           * @param minValue 最低溫度值,必須小于或等于最大溫度值
           * @param maxValue 最高溫度值,必須大于或等于最低溫度值
           * @param unit     溫度單位,不能為空,建議使用標(biāo)準(zhǔn)單位
           */
          public TemperatureRangeVO(BigDecimal minValue, BigDecimal maxValue, String unit) {
              if (minValue.compareTo(maxValue) > 0) {
                  throw new IllegalArgumentException("Minimum temperature must be less than or equal to maximum temperature.");
              }
              if (unit == null || unit.trim().isEmpty()) {
                  throw new IllegalArgumentException("Temperature unit cannot be null or empty.");
              }
              this.minValue = minValue;
              this.maxValue = maxValue;
              this.unit = unit.trim().toUpperCase(); // 統(tǒng)一單位為大寫,便于比較
          }
      
          /**
           * 獲取最低溫度值。
           *
           * @return 最低溫度值
           */
          public BigDecimal getMinValue() {
              return minValue;
          }
      
          /**
           * 獲取最高溫度值。
           *
           * @return 最高溫度值
           */
          public BigDecimal getMaxValue() {
              return maxValue;
          }
      
          /**
           * 獲取溫度單位。
           *
           * @return 溫度單位
           */
          public String getUnit() {
              return unit;
          }
      
          /**
           * 檢查給定的溫度值是否位于當(dāng)前溫度區(qū)間內(nèi)。
           *
           * @param temp 溫度值
           * @return 如果溫度值在區(qū)間內(nèi)則返回true,否則返回false
           */
          public boolean contains(BigDecimal temp) {
              return temp.compareTo(minValue) >= 0 && temp.compareTo(maxValue) <= 0;
          }
      
          @Override
          public boolean equals(Object obj) {
              if (this == obj) return true;
              if (obj == null || getClass() != obj.getClass()) return false;
              TemperatureRangeVO that = (TemperatureRangeVO) obj;
              return minValue.compareTo(that.minValue) == 0 && maxValue.compareTo(that.maxValue) == 0 && unit.equals(that.unit);
          }
      
          @Override
          public int hashCode() {
              return Objects.hash(minValue, maxValue, unit);
          }
      
          /**
           * 提供一個友好的字符串表示形式,包括溫度區(qū)間和單位。
           *
           * @return 字符串表示形式,如 "10°C to 25°C"
           */
          @Override
          public String toString() {
              return minValue + "°" + unit + " to " + maxValue + "°" + unit;
          }
      }
      
      

      數(shù)學(xué)模型

      創(chuàng)建一個坐標(biāo)值對象(CoordinateVO)可以用來封裝二維空間中的位置信息,通常包括經(jīng)度(longitude)和緯度(latitude)。

      
      /**
      * 這個CoordinateVO類使用double類型來存儲經(jīng)度和緯度值,確保了廣泛的兼容性和計(jì)算簡便性。
      * 它驗(yàn)證了坐標(biāo)值的有效范圍,并提供了獲取經(jīng)度和緯度的方法。
      * 通過重寫equals和hashCode方法,確保了坐標(biāo)值對象可以在集合中正確地進(jìn)行比較和存儲。
      * 此外,toString方法提供了易于理解的坐標(biāo)表示形式。
      * 這樣的設(shè)計(jì)適用于地理信息系統(tǒng)、地圖應(yīng)用等多種需要處理地理位置信息的場景。
      */
      
      public class CoordinateVO {
      
          private final double longitude; // 經(jīng)度
          private final double latitude; // 緯度
      
          /**
           * 構(gòu)造一個新的坐標(biāo)值對象。
           *
           * @param longitude 經(jīng)度,取值范圍通常是 -180 到 180
           * @param latitude  緯度,取值范圍通常是 -90 到 90
           */
          public CoordinateVO(double longitude, double latitude) {
              if (longitude < -180 || longitude > 180) {
                  throw new IllegalArgumentException("Longitude must be between -180 and 180.");
              }
              if (latitude < -90 || latitude > 90) {
                  throw new IllegalArgumentException("Latitude must be between -90 and 90.");
              }
              this.longitude = longitude;
              this.latitude = latitude;
          }
      
          /**
           * 獲取經(jīng)度。
           *
           * @return 經(jīng)度值
           */
          public double getLongitude() {
              return longitude;
          }
      
          /**
           * 獲取緯度。
           *
           * @return 緯度值
           */
          public double getLatitude() {
              return latitude;
          }
      
          @Override
          public boolean equals(Object obj) {
              if (this == obj) return true;
              if (obj == null || getClass() != obj.getClass()) return false;
              CoordinateVO coordinateVO = (CoordinateVO) obj;
              return Double.compare(coordinateVO.longitude, longitude) == 0 && Double.compare(coordinateVO.latitude, latitude) == 0;
          }
      
          @Override
          public int hashCode() {
              return Objects.hash(longitude, latitude);
          }
      
          /**
           * 提供一個友好的字符串表示形式,展示經(jīng)緯度坐標(biāo)。
           *
           * @return 字符串表示形式,如 "(100.75, 30.25)"
           */
          @Override
          public String toString() {
              return "(" + longitude + ", " + latitude + ")";
          }
      }
      
      

      創(chuàng)建一個向量值對象(VectorVO)可以用來表示具有大小(magnitude)和方向的量,通常在物理、工程和計(jì)算機(jī)圖形學(xué)等領(lǐng)域中使用。這里我們以二維向量為例,它包含x分量和y分量。

      
      /**
      * 這個VectorVO類使用double類型來存儲向量的x分量和y分量,
      * 提供了獲取分量值、計(jì)算向量大小(模)、向量加法和減法等基本向量操作方法。
      * 同時,重寫了equals和hashCode方法以支持向量對象的比較和在集合中的唯一性識別。
      * toString方法則用于生成易于閱讀的向量表示。
      * 此實(shí)現(xiàn)可以作為基礎(chǔ),根據(jù)具體需求進(jìn)一步擴(kuò)展,比如添加向量的標(biāo)量乘法、點(diǎn)積、叉積等高級操作。
      */
      public class VectorVO {
      
          private final double xComponent; // x分量
          private final double yComponent; // y分量
      
          /**
           * 構(gòu)造一個新的二維向量值對象。
           *
           * @param xComponent x分量
           * @param yComponent y分量
           */
          public VectorVO(double xComponent, double yComponent) {
              this.xComponent = xComponent;
              this.yComponent = yComponent;
          }
      
          /**
           * 獲取x分量。
           *
           * @return x分量值
           */
          public double getXComponent() {
              return xComponent;
          }
      
          /**
           * 獲取y分量。
           *
           * @return y分量值
           */
          public double getYComponent() {
              return yComponent;
          }
      
          /**
           * 計(jì)算向量的大小(模)。
           *
           * @return 向量的大小
           */
          public double magnitude() {
              return Math.sqrt(xComponent * xComponent + yComponent * yComponent);
          }
      
          /**
           * 向量加法。
           *
           * @param other 另一個向量
           * @return 兩個向量相加的結(jié)果
           */
          public VectorVO add(VectorVO other) {
              return new VectorVO(this.xComponent + other.xComponent, this.yComponent + other.yComponent);
          }
      
          /**
           * 向量減法。
           *
           * @param other 另一個向量
           * @return 兩個向量相減的結(jié)果
           */
          public VectorVO subtract(VectorVO other) {
              return new VectorVO(this.xComponent - other.xComponent, this.yComponent - other.yComponent);
          }
      
          @Override
          public boolean equals(Object obj) {
              if (this == obj) return true;
              if (obj == null || getClass() != obj.getClass()) return false;
              VectorVO vectorVO = (VectorVO) obj;
              return Double.compare(vectorVO.xComponent, xComponent) == 0 && Double.compare(vectorVO.yComponent, yComponent) == 0;
          }
      
          @Override
          public int hashCode() {
              return Objects.hash(xComponent, yComponent);
          }
      
          /**
           * 提供一個友好的字符串表示形式,展示向量的x和y分量。
           *
           * @return 字符串表示形式,如 "<1.5, 3.2>"
           */
          @Override
          public String toString() {
              return "<" + xComponent + ", " + yComponent + ">";
          }
      }
      
      

      創(chuàng)建線性回歸模型(LinearRegressionModelVO)值對象

      線性回歸是一種統(tǒng)計(jì)方法,用于預(yù)測一個連續(xù)響應(yīng)變量與一個或多個預(yù)測變量之間的關(guān)系。這個值對象將包括模型參數(shù)(斜率和截距)、相關(guān)系數(shù)(如R2)、訓(xùn)練數(shù)據(jù)集的摘要統(tǒng)計(jì)信息等。

      import java.util.List;
      
      /**
      * 這個LinearRegressionModelVO類封裝了線性回歸模型的核心參數(shù),
      * 包括斜率、截距、R2值,以及訓(xùn)練數(shù)據(jù)集的特征平均值和標(biāo)準(zhǔn)差列表,
      * 這有助于理解和評估模型的質(zhì)量。
      * 通過提供這些信息,該值對象能夠支持模型的持久化、比較和調(diào)試等高級操作。
      */
      public class LinearRegressionModelVO {
      
          private final double slope; // 斜率,即模型的系數(shù)
          private final double intercept; // 截距,即模型的常數(shù)項(xiàng)
          private final double rSquared; // R2值,模型擬合優(yōu)度的度量
          private final List<Double> featureMeans; // 特征(預(yù)測變量)的平均值列表
          private final List<Double> featureStdDevs; // 特征的標(biāo)準(zhǔn)差列表
      
          /**
           * 構(gòu)造一個新的線性回歸模型值對象。
           *
           * @param slope         模型的斜率
           * @param intercept     模型的截距
           * @param rSquared      模型的R2值
           * @param featureMeans  特征的平均值列表
           * @param featureStdDevs 特征的標(biāo)準(zhǔn)差列表
           */
          public LinearRegressionModelVO(double slope, double intercept, double rSquared,
                                         List<Double> featureMeans, List<Double> featureStdDevs) {
              if (featureMeans == null || featureStdDevs == null || featureMeans.size() != featureStdDevs.size()) {
                  throw new IllegalArgumentException("Feature means and standard deviations lists must not be null and of the same size.");
              }
              this.slope = slope;
              this.intercept = intercept;
              this.rSquared = rSquared;
              this.featureMeans = featureMeans;
              this.featureStdDevs = featureStdDevs;
          }
      
          /**
           * 獲取模型的斜率。
           *
           * @return 斜率值
           */
          public double getSlope() {
              return slope;
          }
      
          /**
           * 獲取模型的截距。
           *
           * @return 截距值
           */
          public double getIntercept() {
              return intercept;
          }
      
          /**
           * 獲取模型的R2值。
           *
           * @return R2值
           */
          public double getRSquared() {
              return rSquared;
          }
      
          /**
           * 獲取特征的平均值列表。
           *
           * @return 特征平均值列表
           */
          public List<Double> getFeatureMeans() {
              return featureMeans;
          }
      
          /**
           * 獲取特征的標(biāo)準(zhǔn)差列表。
           *
           * @return 特征標(biāo)準(zhǔn)差列表
           */
          public List<Double> getFeatureStdDevs() {
              return featureStdDevs;
          }
      
          @Override
          public boolean equals(Object obj) {
              if (this == obj) return true;
              if (obj == null || getClass() != obj.getClass()) return false;
              LinearRegressionModelVO that = (LinearRegressionModelVO) obj;
              return Double.compare(that.slope, slope) == 0 &&
                     Double.compare(that.intercept, intercept) == 0 &&
                     Double.compare(that.rSquared, rSquared) == 0 &&
                     featureMeans.equals(that.featureMeans) &&
                     featureStdDevs.equals(that.featureStdDevs);
          }
      
          @Override
          public int hashCode() {
              return Objects.hash(slope, intercept, rSquared, featureMeans, featureStdDevs);
          }
      
          /**
           * 提供一個友好的字符串表示形式,概述模型的關(guān)鍵參數(shù)。
           *
           * @return 字符串表示形式,如 "Slope: 2.5, Intercept: 1.0, R2: 0.85"
           */
          @Override
          public String toString() {
              return "Slope: " + slope + ", Intercept: " + intercept + ", R2: " + rSquared;
          }
      }
      
      

      創(chuàng)建一個多項(xiàng)式回歸模型值對象(PolynomialRegressionModelVO)

      多項(xiàng)式回歸是線性回歸的一種擴(kuò)展,允許因變量和一個或多個自變量之間的關(guān)系以多項(xiàng)式形式建模。這個值對象會包含多項(xiàng)式系數(shù)、階次、訓(xùn)練數(shù)據(jù)的性能指標(biāo)等信息。

      import java.util.List;
      
      /**
      * 這個PolynomialRegressionModelVO類不僅記錄了多項(xiàng)式回歸模型的系數(shù)、階次和R2值,
      * 還包含了訓(xùn)練數(shù)據(jù)集的特征統(tǒng)計(jì)信息,有助于深入分析和復(fù)用模型。
      * 它支持對復(fù)雜非線性關(guān)系的建模,廣泛應(yīng)用于數(shù)據(jù)分析、科學(xué)計(jì)算和機(jī)器學(xué)習(xí)領(lǐng)域。
      */
      public class PolynomialRegressionModelVO {
      
          private final int degree; // 多項(xiàng)式的階次
          private final List<Double> coefficients; // 多項(xiàng)式系數(shù)列表,從常數(shù)項(xiàng)到最高次項(xiàng)
          private final double rSquared; // R2值,模型擬合優(yōu)度的度量
          private final List<Double> featureMeans; // 特征(自變量)的平均值列表
          private final List<Double> featureStdDevs; // 特征的標(biāo)準(zhǔn)差列表
      
          /**
           * 構(gòu)造一個新的多項(xiàng)式回歸模型值對象。
           *
           * @param degree        多項(xiàng)式的階次
           * @param coefficients  多項(xiàng)式系數(shù)列表
           * @param rSquared      模型的R2值
           * @param featureMeans  特征的平均值列表
           * @param featureStdDevs 特征的標(biāo)準(zhǔn)差列表
           */
          public PolynomialRegressionModelVO(int degree, List<Double> coefficients, double rSquared,
                                             List<Double> featureMeans, List<Double> featureStdDevs) {
              if (coefficients == null || coefficients.isEmpty() || featureMeans == null || featureStdDevs == null ||
                      featureMeans.size() != featureStdDevs.size()) {
                  throw new IllegalArgumentException("Coefficients, feature means, and standard deviations must not be null or incorrectly sized.");
              }
              if (degree != coefficients.size() - 1) {
                  throw new IllegalArgumentException("Degree does not match the number of coefficients provided.");
              }
              this.degree = degree;
              this.coefficients = coefficients;
              this.rSquared = rSquared;
              this.featureMeans = featureMeans;
              this.featureStdDevs = featureStdDevs;
          }
      
          /**
           * 獲取多項(xiàng)式的階次。
           *
           * @return 階次
           */
          public int getDegree() {
              return degree;
          }
      
          /**
           * 獲取多項(xiàng)式系數(shù)列表。
           *
           * @return 系數(shù)列表
           */
          public List<Double> getCoefficients() {
              return coefficients;
          }
      
          /**
           * 獲取模型的R2值。
           *
           * @return R2值
           */
          public double getRSquared() {
              return rSquared;
          }
      
          /**
           * 獲取特征的平均值列表。
           *
           * @return 特征平均值列表
           */
          public List<Double> getFeatureMeans() {
              return featureMeans;
          }
      
          /**
           * 獲取特征的標(biāo)準(zhǔn)差列表。
           *
           * @return 特征標(biāo)準(zhǔn)差列表
           */
          public List<Double> getFeatureStdDevs() {
              return featureStdDevs;
          }
      
          @Override
          public boolean equals(Object obj) {
              if (this == obj) return true;
              if (obj == null || getClass() != obj.getClass()) return false;
              PolynomialRegressionModelVO that = (PolynomialRegressionModelVO) obj;
              return degree == that.degree &&
                     coefficients.equals(that.coefficients) &&
                     Double.compare(that.rSquared, rSquared) == 0 &&
                     featureMeans.equals(that.featureMeans) &&
                     featureStdDevs.equals(that.featureStdDevs);
          }
      
          @Override
          public int hashCode() {
              return Objects.hash(degree, coefficients, rSquared, featureMeans, featureStdDevs);
          }
      
          /**
           * 提供一個友好的字符串表示形式,概述模型的關(guān)鍵參數(shù)。
           *
           * @return 字符串表示形式,如 "Degree: 3, Coefficients: [2.5, -1.3, 0.6, 1.0], R2: 0.92"
           */
          @Override
          public String toString() {
              return "Degree: " + degree + ", Coefficients: " + coefficients + ", R2: " + rSquared;
          }
      }
      
      

      創(chuàng)建一個矩陣值對象(MatrixVO)

      用于表示數(shù)學(xué)中的矩陣。矩陣是線性代數(shù)中的基本概念,廣泛應(yīng)用于計(jì)算機(jī)圖形學(xué)、機(jī)器學(xué)習(xí)、工程計(jì)算等多個領(lǐng)域。這個值對象將能夠存儲矩陣的維度信息以及矩陣中的元素值。

      import java.util.ArrayList;
      import java.util.List;
      
      /**
      * 這個MatrixVO類可以用來存儲和操作任意大小的矩陣,包括獲取和設(shè)置特定位置的元素值。
      * 通過重寫equals和hashCode方法,確保了不同實(shí)例間的比較邏輯正確。
      * toString方法則提供了一個易于閱讀的矩陣表示形式,方便打印和調(diào)試。
      * 此類設(shè)計(jì)適用于需要在軟件系統(tǒng)中處理矩陣運(yùn)算的場景,例如計(jì)算密集型應(yīng)用、算法開發(fā)等。
      */
      public class MatrixVO {
      
          private final int rows; // 矩陣的行數(shù)
          private final int columns; // 矩陣的列數(shù)
          private final List<List<Double>> elements; // 矩陣元素,內(nèi)部列表代表每行的元素
      
          /**
           * 構(gòu)造一個新的矩陣值對象。
           *
           * @param rows    矩陣的行數(shù)
           * @param columns 矩陣的列數(shù)
           * @param elements 矩陣元素列表,每個子列表代表一行
           */
          public MatrixVO(int rows, int columns, List<List<Double>> elements) {
              if (rows <= 0 || columns <= 0) {
                  throw new IllegalArgumentException("Number of rows and columns must be positive.");
              }
              if (elements == null || elements.size() != rows || !elements.stream().allMatch(row -> row != null && row.size() == columns)) {
                  throw new IllegalArgumentException("Elements list does not match the specified dimensions.");
              }
              this.rows = rows;
              this.columns = columns;
              this.elements = new ArrayList<>(elements); // 使用新列表以避免外部修改影響內(nèi)部狀態(tài)
          }
      
          /**
           * 獲取矩陣的行數(shù)。
           *
           * @return 行數(shù)
           */
          public int getRows() {
              return rows;
          }
      
          /**
           * 獲取矩陣的列數(shù)。
           *
           * @return 列數(shù)
           */
          public int getColumns() {
              return columns;
          }
      
          /**
           * 獲取指定位置的元素值。
           *
           * @param row 行索引
           * @param column 列索引
           * @return 元素值
           */
          public double getElementAt(int row, int column) {
              return elements.get(row).get(column);
          }
      
          /**
           * 設(shè)置指定位置的元素值。
           *
           * @param row      行索引
           * @param column   列索引
           * @param value    新的元素值
           */
          public void setElementAt(int row, int column, double value) {
              elements.get(row).set(column, value);
          }
      
          @Override
          public boolean equals(Object obj) {
              if (this == obj) return true;
              if (obj == null || getClass() != obj.getClass()) return false;
              MatrixVO matrixVO = (MatrixVO) obj;
              return rows == matrixVO.rows && columns == matrixVO.columns && elements.equals(matrixVO.elements);
          }
      
          @Override
          public int hashCode() {
              return Objects.hash(rows, columns, elements);
          }
      
          /**
           * 提供一個友好的字符串表示形式,展示矩陣的所有元素。
           *
           * @return 字符串表示形式,如 "[[1.0, 2.0], [3.0, 4.0]]"
           */
          @Override
          public String toString() {
              StringBuilder sb = new StringBuilder("[");
              for (int i = 0; i < rows; i++) {
                  if (i > 0) sb.append(", ");
                  sb.append("[");
                  for (int j = 0; j < columns; j++) {
                      if (j > 0) sb.append(", ");
                      sb.append(elements.get(i).get(j));
                  }
                  sb.append("]");
              }
              sb.append("]");
              return sb.toString();
          }
      }
      
      
      posted @ 2024-07-15 20:42  ZeroPhix  閱讀(97)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 无码av中文字幕免费放| 伊人成人在线视频免费| 美女禁区a级全片免费观看| 亚洲成人网在线观看| 久久中文字幕无码一区二区| 少妇精品无码一区二区免费视频| 伊人色综合久久天天小片| 青草视频在线观看视频| 亚洲av无码专区在线亚| 乱人伦人妻中文字幕无码久久网| 精品无码一区二区三区电影| 国产亚洲精品AA片在线播放天| 午夜丰满少妇性开放视频| 国产永久免费高清在线观看| 人妻熟女av一区二区三区| 米奇亚洲国产精品思久久| 无码国内精品久久人妻蜜桃| 国产高跟黑色丝袜在线| 久久这里都是精品一区| 综合人妻久久一区二区精品| 亚洲中文字幕无码一区日日添| 少妇人妻偷人免费观看| 中国性欧美videofree精品| 色呦呦 国产精品| 福利一区二区在线播放| 夜色福利站WWW国产在线视频| 四虎永久精品免费视频| 亚洲色最新高清AV网站| 久久国产乱子精品免费女| 亚洲 一区二区 在线| 无码一区二区三区免费| 色综合色综合色综合频道| 亚洲人成小说网站色在线| av无码av无码专区| 日韩一区二区三在线观看| 2021AV在线无码最新| 中文字幕在线精品人妻| 97av| 午夜射精日本三级| 欧美另类videossexo高潮| 日韩av不卡一区二区在线|