JavaRush /Java блогу /Random-KY /Жаз коркунучтуу эмес, DTO катмары
Павел
Деңгээл

Жаз коркунучтуу эмес, DTO катмары

Группада жарыяланган
МАКАЛАнын МАЗМУНУ Биз жаз жөнүндө сөзүбүздү улантабыз. Бүгүн биз DTO үлгүсүн талдайбыз, түшүнүү үчүн бул жерден окуй аласыз . DTO жөнүндө эң кыйын нерсе - бул эмне үчүн керек экенин түшүнүү. Келгиле, жашылчалар боюнча спекуляцияны баштайлы, ошол эле учурда code жаз, балким, жолдо бир нерсе айкын болуп калат. Жазгы жүктөө долбоорун түзүңүз, жана Lombok туташтырыңыз . Пакеттерди түзүңүз: an objectтер, репозиторийлер, кызматтар, утorттер. Объекттерде Продукт бирдигин түзүңүз:
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;//закупочная цена

}
ProducRepository, ProducService класстарын жана ItiiateUtil классын ишке ашырыңыз ( мурунку макалага окшош ). Картошканы дүң баада 1 кг 20 рублден, сабизди 14 рублден алдык дейли. Сатып алынган продукцияны сактоочу жайга коёбуз. Келгиле, маалымат базасына төмөнкү жазууларды кошолу: [Id =1, аты= “Картошка”, сатып алууPrice = 20] [Id =2, аты= “Сабиз”, buyPrice = 14] Татыктуу алып-сатарлар катары биз товарларыбызды пайдалуу сатууга тийишпиз, бул үчүн аны кооздоп таңгактайлы жана бааны жогорулатабыз. Башкача айтканда, бизде кир жана жагымсыз жашылчалар үйүлгөн, бирок люкс сегментинен таза премиум вегетариандык азыктар болот. Макул, бул мындан ары биз дүңүнөн сатып алган өнүм (an object) болбойт. Жаңы продукт үчүн dto пакетин жана анын ичинде ProductDto классын түзүңүз
package ru.java.rush.dto;

import lombok.Data;

@Data
public class ProductDto {
    Integer id;
    String name;
    Integer purchasePrice;
    String  packaging;//упаковка
    Integer salePrice;//цена реализации
}
ProductDtoдо ProductEntity жок эки өзгөрмө бар: “пакет” жана “сатуу баасы”. dto an objectисинде an object сыяктуу өзгөрмөлөр болушу мүмкүн, же алардын саны аз же көп болушу мүмкүн. Биз бир an objectти экинчи an objectке айландыруу картага түшүрүү маселеси экенин унутпайбыз. Utils пакетинде биз 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;
    }
}
Биз жөн гана бир an objectтин талааларын башка an objectтин окшош талаалары менен толтурабыз. ProductService классында биз бир продуктту же өнүмдөрдүн тизмесин издөө ыкмаларын ишке ашырабыз, бирок ага чейин биз жогоруда жазылган ыкманы колдонуу менен an objectти dtoга айландырабыз.
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
    );
}
Эми ушул жашылчаларды көргөзмөгө койсок эмне болот? көрөлү. Бул үчүн, ItiiateUtil программасына төмөнкү codeду жазып, аны иштетиңиз.
System.out.println("\nВитрина магазина");
for (ProductDto dto : productService.findAll()) {
    System.out.println(dto);
}
Чыгуу: Дүкөн дисплейи ProductDto(id=1, аты=Картошка, сатып алууБаасы=20, таңгактоо=нөл, salePrice=null) ProductDto(id=2, аты=Сабиз, сатып алууБаасы=14, таңгактоо=нөл, salePrice=null) Жакшы мен эмес! Мындай жашылчаларды эч ким сатып алbyte: алар кир, таңгакталган эмес, сатуу баасы белгисиз. Бизнес логикасына убакыт келди. Биз аны ProductService классында ишке ашырабыз. Адегенде бул класска бир нече өзгөрмөлөрдү кошолу:
private final Integer margin = 5;//это наша накрутка на цену
private final String packaging = "Упаковано в лучшем виде";//так будет выглядеть упаковка
Ар бир иш-аракет үчүн: таңгактоо жана баа белгилөө, биз ошол эле класста өзүнчө ыкманы түзөбүз:
// упаковываем товар
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)
    );
}
Биз ItiiateUtilге кайтып келип, дисплейдеги дисплейди төмөнкү code менен алмаштырабыз
List<ProductDto> productDtos = productService.findAll();

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

System.out.println("\nВитрина магазина");
for (ProductDto dto : productDtos)) {
    System.out.println(dto);
}
Биз төмөнкүлөрдү аткарабыз: Дүкөндүн дисплейи ПродуктDto(id=1, аты=Картошка, сатып алууБаасы=20, таңгактоо=Мүмкүн болгон эң жакшы жол менен таңгакталган, salePrice=100) ProductDto(id=2, аты=Сабиз, сатып алууБаасы=14, таңгактоо=Пайгаланган) мүмкүн болушунча мыкты жол менен, salePrice=70) Продукт сонун таңгакталган, баасы бар, бирок сиз аны дүңүнөн сатып алган бааны жана башка идентификаторду терезеден көрдүңүз беле. Жогоруда жазылган codeду файл менен өзгөртөбүз:
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()
    ));
}
класс InitiateUtils төмөнкүдөй болушу керек:
@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()
            ));
        }
    }
}
Ишке киргизели: Дүкөндүн терезеси Сатып алуу: Картошка, баасы: 100 Сатып алуу: Сабиз, баасы: 70 Дагы бир нерсе! Азыр биз жакшы нерселерди алып келди деп ойлойбуз, бир топ кошумча codeдон башкасы: 1. Биз бизнес логикасын маалымат базасындагы an objectтерди өзгөртпөстөн аткара алабыз (айталы, бизде таңгактоо жана сатуу баасы жөнүндө талаалардын кереги жок. бул table). Картошка баа теги менен таңгаксыз да сактоодо жакшы сакталат, ал жерде алар ашыкча. 2. Бул сапта List<ProductDto> productDtos = productService.findAll() бизнес логикасынын алкагында иштөөгө ыңгайлуу an objectтердин кэшин түздүк. Товарлардын бир бөлүгүн дүкөндүн арткы бөлмөсүнө койсок. 3. Бул бизге эки бизнес иш-аракетти аткарууга мүмкүндүк берди: таңгактоо жана белгилөө, бирок биз маалымат базасына бир гана жолу кайрылуу жасадык (базага суроо-талаптар аткаруу жагынан бир топ кыйын). Сиз буюмду таңгактап, анын баасынын белгисин коюп, аны дисплейге койсоңуз болот - акырындык менен аны кампа бөлмөсүнө чейин артынан чуркабай, акырындык менен коммуналдык бөлмөдөн алып. “Эмне үчүн мынчалык кыйын?” деген суроого адамдар да жооп табууга аракет кылышат, окугула . Кийинки макала
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION