إعادة تصور DTOs في جافا

مرحبا هبر! أقدم انتباهكم إلى ترجمة هاوية لمقال "إعادة التفكير في Java DTO" لستيفن ووترمان ، حيث يعتبر المؤلف طريقة مثيرة للاهتمام وغير قياسية لاستخدام DTOs في Java.






أمضيت 12 أسبوعًا في برنامج سكوت لوجيك التدريبي للخريجين ، حيث عملت مع زملائي الخريجين في مشروع داخلي. وكانت هناك لحظة أعاقتني أكثر من غيرها: هيكل وأسلوب كتابة DTOs الخاصة بنا. تسبب هذا في الكثير من الجدل والمناقشات طوال المشروع ، لكن في النهاية أدركت أنني أحب استخدام DTOs.



هذا النهج ليس هو الحل الوحيد الصحيح ، ولكنه ممتع للغاية ورائع للتطوير باستخدام IDEs الحديثة. آمل أن تزول الصدمة الأولية وتستمتع بها أيضًا.



ما هو DTO (كائن نقل البيانات)؟



في كثير من الأحيان ، في تطبيقات خادم العميل ، يتم تنظيم البيانات الموجودة على العميل ( طبقة العرض التقديمي ) وعلى الخادم ( طبقة المجال ) بشكل مختلف. على جانب الخادم ، يمنحنا هذا الفرصة لتخزين البيانات بشكل مريح في قاعدة البيانات أو تحسين استخدام البيانات من أجل الأداء ، وفي الوقت نفسه المشاركة في عرض "سهل الاستخدام" للبيانات على العميل ، وبالنسبة إلى جانب الخادم ، نحتاج إلى إيجاد طريقة لترجمة البيانات من واحد تنسيق لآخر. بالطبع ، هناك بنيات تطبيق أخرى ، لكننا سنركز على التصميم الحالي كنوع من التبسيط. يمكن استخدام الكائنات التي تشبه DTO بين أي طبقتين لعرض البيانات.





DTO — value-object , , . DTO , (Request) , (Response). , Spring.



, endpoint DTO :



// Getters & Setters, ,    
public class CreateProductRequest {
    private String name;
    private Double price;
}

public class ProductResponse {
    private Long id;
    private String name;
    private Double price;
}

@PostMapping("/products")
public ResponseEntity<ProductResponse> createProduct(
    @RequestBody CreateProductRequest request
) { /*...*/ }


DTO?



-, , DTO. .



  • , DTO.
  • JSON, !


. DTO , , , (decoupling) , .



, DTO . DTO API .



API, . (endpoint) . , . price “ ”, price . API , - , .



DTO . DTO , , API . DTO “ ”, — , .



DTO, , .



!



, . . , .



, -. , . Double, BigDecimal.



public enum ProductDTO {;
    private interface Id { @Positive Long getId(); }
    private interface Name { @NotBlank String getName(); }
    private interface Price { @Positive Double getPrice(); }
    private interface Cost { @Positive Double getCost(); }

    public enum Request{;
        @Value public static class Create implements Name, Price, Cost {
            String name;
            Double price;
            Double cost;
        }
    }

    public enum Response{;
        @Value public static class Public implements Id, Name, Price {
            Long id;
            String name;
            Double price;
        }

        @Value public static class Private implements Id, Name, Price, Cost {
            Long id;
            String name;
            Double price;
            Double cost;
        }
    }
}


, enum , ProductDTO. , DTO , (Request) , (Response). endpoint Request DTO Response DTO . Response DTO, Public Private .



. - — , . . , @NotBlank DTO .



DTO . @Value Lombok , .



, , . , DTO.



“ !”



. .



enum ! namespace-, .. DTO ProductDTO.Request.Create. “” , ; enum. () ! namespace- DTO, IDE . , , new ProductDTO() new Create(). , .



— ! . , , .



. , . Lombok . , , DTO . , java . , .



()



DTO. ?





. API , . DTO — IDE . :



@Value public static class PatchPrice implements Id, Price {
    String id;    //    Long;
    Double prise; //    price
}


PatchPrice is not abstract and does not override abstract method getId() in Id
PatchPrice is not abstract and does not override abstract method getPrice() in Price


, , , endpoint .





DTO . . :



private interface Cost {
    /**
     * The amount that it costs us to purchase this product
     * For the amount we sell a product for, see the {@link Price Price} parameter.
     * <b>This data is confidential</b>
     */
    @Positive Double getCost();
}


DTO , .





DTO, . , API, , . , , .



&



: . 4 , , DTO . , “” c DTO. , , . , .



, DTO. @Value public static class [name] implements, . , IDE . ! DTO .



, DTO . . . ctrl + q IntelliJ .





, .. . DTO — , .



, , . , , :



markup = (sale_price - cost_price) / cost_price


java, :



public static <T extends Price & Cost> Double getMarkup(T dto){
    return (dto.getPrice() - dto.getCost()) / dto.getCost();
}


T, . dto Price Cost — , Public (.. Cost). , dto (). .





, DTO. :



  1. API .
  2. .
  3. , , !





ملاحظة: شكرًا لك على قراءة أول منشور لي عن حبري حتى النهاية. سأكون سعيدًا لأي انتقاد بخصوص الترجمة ، لأنه اضطررت إلى الانحراف قليلاً عن الأصل بسبب نقص المعرفة والخبرة.




All Articles