Jak rozpoznać jakiego typu jest przesyłany obiekt?

0

Hej, postanowiłem zrobić coś na miarę apek treningowych: liczenie kalorii, zestaw ćwiczeń etc.
Jestem na etapie kalkulatora kalorii tzn ktoś przesyła obiekt (przynajmniej tak myślę, że w postaci JSONA) pod jedną z metod kontrolera, odczytuje z niego ile jest gram, co to za produkt i za pomocą danych zapisanych w bazie odnośnie każdego pojedynczego produktu (100g jabłka ma tyle i tyle kalorii, tyle i tyle tłuszczu etc.) wylicza dokładną ilość spożytych makroskładników.

W tym problem, że nie wiem jakiego typu będzie przesłany obiekt, a encji będę mieć kilka (na ten moment tylko Fruit i Meat), a jakiś typ argumentu musze wpisać, żeby wiedzieć z której bazy wyciągać produkty (czy mięsa czy owoce)

Metoda w pseudokodzie wyglądała by tak:

@Service
public class CaloriesCalculationService {

    private final FruitRepository fruitRepository;
    private final MeatRepository meatRepository;

    @Autowired
    public CaloriesCalculationService(FruitRepository fruitRepository, MeatRepository meatRepository) {
        this.fruitRepository = fruitRepository;
        this.meatRepository = meatRepository;
    }

    int countFatNumberOfGivenProduct(Produkt produkt) {
        if (produkt.getClass == Meat.class)
            meatRepository.findById(produkt.getId)
        if (produkt.getClass == Fruit.class)
            fruitRepository.findById(produk.getId)
    }
}

a w kontrolerze jakoś tak:

@PostMapping("/calorieCalculator")
    public Fruit createFruit(@RequestBody Produkt produkt) {
        return caloriesCalculationsService.createFruit(produkt);
    }

Oczywiście nazwy są do zmiany, tak na szybko to teraz napisałem, żeby zobrazować problem.

Encja Fruit wygląda tak:

package trainingapp.product.fruit;

import lombok.*;

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

@Getter
@Setter
@EqualsAndHashCode
@AllArgsConstructor
@NoArgsConstructor
@Entity
public
class Fruit {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    String fruitName;
    double fatNumber;
    double proteinsNumber;
    double carbohydratesNumber;
    int kcal;

    public static class FruitBuilder {
        String fruitName;
        double fatNumber;
        double proteinsNumber;
        double carbohydratesNumber;
        int kcal;

        public FruitBuilder withName(String fruitName) {
            this.fruitName = fruitName;
            return this;
        }

        public FruitBuilder withKcal(int kcal) {
            this.kcal=kcal;
            return this;
        }

        public FruitBuilder withFatNumber(double fatNumber) {
            this.fatNumber = fatNumber;
            return this;
        }

        public FruitBuilder withProteinsNumber(double proteinsNumber) {
            this.proteinsNumber = proteinsNumber;
            return this;
        }

        public FruitBuilder withCarbohydratesNumber(double carbohydratesNumber) {
            this.carbohydratesNumber = carbohydratesNumber;
            return this;
        }

        public Fruit build() {
            Fruit fruit = new Fruit();
            fruit.carbohydratesNumber = this.carbohydratesNumber;
            fruit.fatNumber = this.fatNumber;
            fruit.proteinsNumber = this.proteinsNumber;
            fruit.fruitName = this.fruitName;
            fruit.kcal=this.kcal;
            return fruit;
        }
    }
}


Z czego encja Meat wygląda identycznie z tym, że ma wszędzie meat zamiast fruit.

///EDIT
Nie wiem czy tak się da (czy encję będą działać odpowiednio), ale gdyby zrobić klasę abstrakcyjną Produkt i żeby klasy Fruit i Meat dziedziczyły po tej klasie (z tym, że nie wiem które rzeczy powinienem umieścić wtedy w klasie Produkt)?

1
must napisał(a):

Z czego encja Meat wygląda identycznie z tym, że ma wszędzie meat zamiast fruit.

To po co Ci dwie osobne klasy?

0
danek napisał(a):
must napisał(a):

Z czego encja Meat wygląda identycznie z tym, że ma wszędzie meat zamiast fruit.

To po co Ci dwie osobne klasy?

Miałem dylemat czy połączyć wszystko czy nie, aczkolwiek wydaje mi sie ze teraz jest przejrzyście. Z tego względu, że rodzajów produktów może byc wiele przez co będzie lekki syf.

Btw. Dodałem edit odnośnie dziedziczenia.

1

Ale dla każdego chcesz tworzyć osobny obiekt tylko z zmienionymi nazwami zmiennych? Bez sensu. Zrób klase Product z polem name i resztą tych które masz tutaj. Takie coś wystarczy

4

@must: powrot do lekcji o obiektwosci serio xD jak bedziesz mial slodycze to kolejna klasa? @danek dobrze ci radzi. Zauwaz ze wszystkie jedzenie ma swoje wartosci odzywcze i tym sie rozni. Jesli chodzi o to ze chcesz miesz rodazje typu: mieso, warzywa, owoce, slodycze, fastfood :D to w klasie mozesz rozwiazac to za pomoca pola Type i tam uzyjesz Enuma (https://www.samouczekprogramisty.pl/typ-wyliczeniowy-w-jezyku-java/). Potraktuj klase jako jedzenie a obiekt jak konkretny produkt "jedzeniowy". Dla ciebie do liczenia kalori kazdy produkt ma te same cechy czyli kalorie + makro i mikro elementy.

Podsumowujac zmien pole FruitName na po prostu Name, dodaj pole Type i tam za pomca enuma mozesz sobie wszystkie "rodzaje" jedzenia obslozyc :) tak ze bedziesz mogl rozroznic co jest owocem a co miesem jesli taka potrzeba.

1 użytkowników online, w tym zalogowanych: 0, gości: 1