JavaでのDTOの再考

こんにちは、Habr!StephenWatermanによる記事「RethinkingtheJava DTO」のアマチュア翻訳を紹介します。著者は、JavaでDTOを使用するための興味深い非標準的なアプローチを検討しています。






私はスコットロジックの大学院研修プログラムに12週間滞在し、仲間の卒業生と一緒に社内プロジェクトに取り組みました。そして、他の人よりも私を失速させた瞬間がありました:私たちのDTOを書く構造とスタイル。これはプロジェクト全体で多くの論争と議論を引き起こしましたが、最終的に私はDTOを使用するのが好きだと気づきました。



このアプローチだけが正しい解決策ではありませんが、最新のIDEを使用した開発には非常に興味深く、優れています。最初の衝撃がなくなり、あなたもそれを楽しんでくれることを願っています。



DTO(データ転送オブジェクト)とは何ですか?



多くの場合、クライアント-サーバーアプリケーションでは、クライアント(プレゼンテーションレイヤー)とサーバー(ドメインレイヤー)のデータの構造が異なります。サーバー側では、これにより、データベースにデータを快適に保存したり、パフォーマンスのためにデータの使用を最適化したりすると同時に、クライアント上でデータを「ユーザーフレンドリー」に表示する機会が得られます。サーバー側では、データを1つから変換する方法を見つける必要があります。別のフォーマット。もちろん、他のアプリケーションアーキテクチャもありますが、簡略化として現在のアーキテクチャに焦点を当てます。 DTOのよ​​うなオブジェクトは、任意の2つのデータ表示レイヤー間で使用できます。





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. , , !





PSハブレに関する私の最初の投稿を最後まで読んでいただきありがとうございます。翻訳に関する批判があれば嬉しいです。知識と経験が不足していたため、オリジナルから少し逸脱しなければなりませんでした。




All Articles