JavaRush /Java Blog /Random-TL /Ang tagsibol ay hindi nakakatakot, isang layer ng DTO

Ang tagsibol ay hindi nakakatakot, isang layer ng DTO

Nai-publish sa grupo
NILALAMAN NG ARTIKULO CYCLE Patuloy nating pinag-uusapan ang Spring. Ngayon ay susuriin namin ang pattern ng DTO, para sa pag-unawa maaari mong basahin dito . Ang pinakamahirap sa DTO ay ang pag-unawa kung bakit ito kailangan. Magsimula tayong mag-speculate sa mga gulay, at sa parehong oras, magsulat ng ilang code, baka may isang bagay na maging mas malinaw sa daan. Gumawa ng spring-boot project , ikonekta ang h2 at Lombok . Lumikha ng mga pakete: entity, repositoryo, serbisyo, utils. Sa mga entity, lumikha ng isang Product entity:
package ru.java.rush.entities;

import lombok.Data;
import lombok.experimental.Accessors;
import org.hibernate.annotations.GenericGenerator;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Accessors(chain = true)
@Entity
@Data
public class ProductEntity {

    @Id
    @Column
    @GenericGenerator(name = "generator", strategy = "increment")
    @GeneratedValue(generator = "generator")
    Integer id;

    @Column
    String name;

    @Column
    Integer purchasePrice;//закупочная цена

}
Ipatupad ang mga klase ng ProducRepository, ProducService at ang klase ng ItiiateUtil ( katulad ng nakaraang artikulo ). Sabihin nating bumili kami ng patatas sa presyong pakyawan na 20 rubles bawat kg, at mga karot sa 14 rubles bawat kg. Ilalagay namin ang mga biniling produkto sa imbakan. Idagdag natin ang mga sumusunod na tala sa database: [Id =1, name= “Potatoes”, purchasePrice = 20] [Id =2, name= “Carrots”, purchasePrice = 14] Bilang mga disenteng speculators, kailangan nating ibenta ang ating mga kalakal, para dito, i-package natin ito nang maganda at tataas natin ang presyo. Ibig sabihin, nagkaroon kami ng marurumi at hindi kaakit-akit na mga gulay na nakatambak sa isang tambak, ngunit magkakaroon ng malinis na premium na mga produktong vegan mula sa luxury segment. Sumang-ayon, hindi na ito ang parehong produkto (object) na binili namin nang maramihan. Para sa isang bagong produkto, gumawa tayo ng isang pakete ng dto at sa loob nito ang klase ng ProductDto
package ru.java.rush.dto;

import lombok.Data;

@Data
public class ProductDto {
    Integer id;
    String name;
    Integer purchasePrice;
    String  packaging;//упаковка
    Integer salePrice;//цена реализации
}
Ang ProductDto ay may dalawang variable na wala sa ProductEntity: “packaging” at “selling price”. Ang bagay na dto ay maaaring maglaman ng eksaktong kaparehong mga variable gaya ng entity, o maaaring may higit pa o mas kaunti sa mga ito. Naaalala namin na ang pag-convert ng isang bagay sa isa pa ay isang bagay ng pagmamapa. Sa utils package gagawa kami ng klase ng MappingUtils
package ru.java.rush.utils;

import org.springframework.stereotype.Service;
import ru.java.rush.dto.ProductDto;
import ru.java.rush.entities.ProductEntity;

@Service
public class MappingUtils {
//из entity в dto
    public ProductDto mapToProductDto(ProductEntity entity){
        ProductDto dto = new ProductDto();
        dto.setId(entity.getId());
        dto.setName(entity.getName());
        dto.setPurchasePrice(entity.getPurchasePrice());
        return dto;
    }
//из dto в entity
    public ProductEntity mapToProductEntity(ProductDto dto){
        ProductEntity entity = new ProductEntity();
        entity.setId(dto.getId());
        entity.setName(dto.getName());
        entity.setPurchasePrice(dto.getPurchasePrice());
        return entity;
    }
}
Pinupuno lang namin ang mga patlang mula sa isang bagay na may katulad na mga patlang mula sa isa pang bagay. Sa klase ng ProductService, nagpapatupad kami ng mga pamamaraan para maghanap ng isang produkto o isang listahan ng mga produkto, ngunit bago iyon, iko-convert namin ang entity sa isang dto gamit ang paraan na nakasulat sa itaas.
private final ProductRepository productRepository;
private final MappingUtils mappingUtils;


//для листа продуктов мы использовали стрим
public List<ProductDto> findAll() {
    return productRepository.findAll().stream() //создали из листа стирим
            .map(mappingUtils::mapToProductDto) //оператором из streamAPI map, использовали для каждого element метод mapToProductDto из класса MappingUtils
.collect(Collectors.toList()); //превратor стрим обратно в коллекцию, а точнее в лист
}

//для одиночного продукта обошлись проще
public ProductDto findById(Integer id) {
    return mappingUtils.mapToProductDto( //в метод mapToProductDto
            productRepository.findById(id) //поместor результат поиска по id
                    .orElse(new ProductEntity()) //если ни чего не нашли, то вернем пустой entity
    );
}
Ano ang mangyayari kung ilalagay na natin ang mga gulay na ito sa display? Tingnan natin. Upang gawin ito, isulat ang sumusunod na code sa ItiiateUtil at patakbuhin ito.
System.out.println("\nВитрина магазина");
for (ProductDto dto : productService.findAll()) {
    System.out.println(dto);
}
Ang output ay: Store display ProductDto(id=1, name=Potatoes, purchasePrice=20, packaging=null, salePrice=null) ProductDto(id=2, name=Carrots, purchasePrice=14, packaging=null, salePrice=null) Well, ayoko! Walang bibili ng gayong mga gulay: ang mga ito ay marumi, hindi nakabalot, at ang presyo ng pagbebenta ay hindi alam. Panahon na para sa lohika ng negosyo. Ipinapatupad namin ito sa klase ng ProductService. Magdagdag muna tayo ng ilang variable sa klase na ito:
private final Integer margin = 5;//это наша накрутка на цену
private final String packaging = "Упаковано в лучшем виде";//так будет выглядеть упаковка
Para sa bawat aksyon: packaging at markup ng presyo, gagawa kami ng hiwalay na paraan sa parehong klase:
// упаковываем товар
public void pack(List<ProductDto> list) {
    list.forEach(productDto ->
            productDto.setPackaging(packaging)
    );
}

// делаем деньги
public void makeMoney(List<ProductDto> list) {
    list.forEach(productDto ->
            productDto.setSalePrice(productDto.getPurchasePrice() * margin)
    );
}
Bumalik kami sa ItiiateUtil at pinapalitan ang display sa display ng sumusunod na code
List<ProductDto> productDtos = productService.findAll();

productService.pack(productDtos);
productService.makeMoney(productDtos);

System.out.println("\nВитрина магазина");
for (ProductDto dto : productDtos)) {
    System.out.println(dto);
}
Isinasagawa namin ang: Store display ProductDto(id=1, name=Patatas, purchasePrice=20, packaging=Packed in the best possible way, salePrice=100) ProductDto(id=2, name=Carrots, purchasePrice=14, packaging=Packed sa pinakamabuting posibleng paraan, salePrice=70) Ang produkto ay maganda ang pagkaka-package, may presyo, ngunit nakita mo ba sa isang lugar sa window na ipinapakita ang presyo kung saan binili mo ito nang maramihan at ilang iba pang id. Binabago namin ang code na nakasulat sa itaas gamit ang isang file:
List<ProductDto> productDtos = productService.findAll();

productService.pack(productDtos);
productService.makeMoney(productDtos);

System.out.println("\nВитрина магазина");
for (ProductDto dto : productDtos) {
    System.out.println(String.format(
            "Купите: %s , по цене:  %d", dto.getName(), dto.getSalePrice()
    ));
}
class InitiateUtils dapat sa huli ay ganito ang hitsura:
@Service
@RequiredArgsConstructor
public class InitiateUtils implements CommandLineRunner {

    private final ProductService productService;

    @Override
    public void run(String... args) throws Exception {

        List<ProductEntity> products = new ArrayList<>(
                Arrays.asList(
                        new ProductEntity()
                                .setName("Картофель")
                                .setPurchasePrice(20),
                        new ProductEntity()
                                .setName("Морковь")
                                .setPurchasePrice(14)
                ));

        productService.saveAll(products);

        List<ProductDto> productDtos = productService.findAll();

        productService.pack(productDtos);
        productService.makeMoney(productDtos);

        System.out.println("\nВитрина магазина");
        for (ProductDto dto : productDtos) {
            System.out.println(String.format(
                    "Купите: %s , по цене:  %d", dto.getName(), dto.getSalePrice()
            ));
        }
    }
}
Ilunsad natin: Window ng tindahan Bilhin: Patatas, presyo: 100 Bilhin: Karot, presyo: 70 Isa pang bagay! Ngayon ay iniisip namin na ang dto ay nagdala ng magagandang bagay, maliban sa isang bungkos ng karagdagang code: 1. Maaari kaming magsagawa ng lohika ng negosyo nang hindi binabago ang mga bagay sa database (sabihin natin, well, hindi namin kailangang magkaroon ng mga patlang tungkol sa packaging at presyo ng mga benta sa mesa na ito). Ang mga patatas ay tatagal nang maayos sa imbakan kahit na walang packaging na may tag ng presyo, sila ay kalabisan pa doon. 2. Sa linyang ito List<ProductDto> productDtos = productService.findAll() gumawa kami ng cache ng mga bagay na madaling gamitin sa loob ng logic ng negosyo. Ito ay kung ilalagay natin ang ilan sa mga kalakal sa likod na silid ng tindahan. 3. Nagbigay-daan ito sa amin na magsagawa ng dalawang aksyon sa negosyo: packaging at markup, ngunit isang beses lang kaming gumawa ng kahilingan sa database (ang mga query sa database ay medyo mahirap sa mga tuntunin ng pagganap). Maaari mong i-package ang produkto, lagyan ng price tag at ilagay ito sa display - unti-unting kunin ito mula sa utility room, sa halip na sundan ito sa bawat oras sa storage room. Sa tanong na: "Bakit napakahirap?", sinusubukan din ng mga tao na hanapin ang sagot, basahin . Susunod na artikulo
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION