Witam, zastanawiam się jak zaprojektować pewną rzecz. Nie że nie umiem, tylko myślę jak podejść do tego na wielu warstwach, jak dynamicznie to zrobić. Chcę napisać CRUD sklepu internetowego w ramach nauki.
Na stronie pewnego sklepu wyszukując produkty możemy filtrować po cechach smartfonów (system, wielkość ekranu), po cechach telewizora (obraz 3d, czy smart tv), po cechach pralki (wielkość bębna). Czyli z punktu OOP mamy class Product [id, nazwa, cena, ilosc w magazynie] i potem to inne klasy rozszerzają. W podobny sposób trzeba by było projektować tabele SQL.
W wielkim skrócie zastanawiam się, czy jestem w stanie to zrobić bardzo dynamicznie, że dodawanie nowych kategorii produktów, cech filtrowania byłoby możliwe runtime przez administratora na stronie web w panelu admina. Bez zmiany source kodu. Czy może to na etapie developmentu powinienem dodać nowy typ "SmartphoneProduct", tabelę stworzyć do tego i wystawić odpowiednie API RESTowe, które pozwala filtrować po tych cechach. Czyli zmiana source kodu.
Myślę, że z powyższego akapitu wybieram opcję drugą - gdy dodajemy nowe kategorie produktów do sklepu, jest wymagana zmiana kodu backend (w moim wypadku java spring + sql, akurat za pośrednictwem java hibernate). Tylko jak to zakodować?
- główna tabela `products` (id, nazwa, cena, ilosc w magazynie)
a potem wraz z dodawaniem nowych kategorii, tworzyć kolejno tabele
- `products_smartphones` (products.id, cechy: system operacyjny, wielkosc pamieci, ekran, ...)
- `products_zelazka` (products_id, cechy: rodzaj zelazka, rodzaj stopy, moc)
Teraz na stronie glownej jak wyswietlic chociaz dostepne kategorie produktow?
- hardcodować, czyli we warstwie frontu kopiowac model jaki mamy w backend, napisac kolejno smartfony, zelazka, telewizory - brzydkie rozwiazanie. W przypadku potem tworzenia apki mobilnej, apki TV - przy dodawaniu nowej kategorii w systemie, musze kilka frontów modyfikować
- pobrac dostepne kategorie (pobraz model z backendu), ale co, mam SQL pobrac nazwy wszystkich tabel i przefiltrowac te ktore w nazwie maja "products_*" ? Dylematy mam, bo to jakby warstwa struktury bazy i wyciaganie modelu dostepnych kategorii na podstawie pobrania nazw tabel kłóci mi się, bardziej powinna byc jakas tabela `categories`
Do tego dołóżmy fakt, że kategorie mają być rekurencyjne:
- Komputery
- - Podzespoły
- - - Procesory
- - - Ram
- - - Karty graficzne
- - Klawiatury
- - Myszki
- Telewizory
- AGD
Finalnie, mój pomysł na to, to tabela `products` z (id, nazwa, cena, sztuki w magazynie, opis produktu, categories_id), kolejne tabele `products_smartphones`, `products_keyboards`, ktore maja relacje do glownego `products`. Te rozszerzajace posiadaja tylko cechy dla produktu. A jako ze korzystam w systemie z Hibernate, to odpowiednikiem tych tabel bede mial javowe klasy i dla propertiesów klasy SmartphoneProduct - moge im nadac adnotacje wymyslona np. @Filterable, dzieki czemu w backendzie wiem po czym dany typ moge filtrowac (system operacyjny, wielkosc ekranu).
Również potrzebuje tabeli `categories` (id, nazwa, parent_category_id) żeby móc zrobić takie drzewko jak tam akapit wyżej. Trzeba by też związać produkty z tymi kategoriami.
I wydaje mi się że to jest OK. Choć gdybym teraz chciał pobrać wszystkie produkty z bazy wraz z ich szczegółowymi danymi w jednym zapytaniu, to nie jest to możliwe, bo im więcej kategorii produktów, tym więcej tabel. Ale nie ma takiej potrzeby. Za to mogę pobrać wszystko, z podstawowymi danymi. Na stronie sklepu przeglądamy kategorie, szukamy produktu i jeśli już szukamy czegoś, to mamy dokładne wyniki ze wszystkimi cechami dla jednego typu - np smartfony. Nie potrzebujemy wyświetlać pralek i smartfonów na jednej stronie ze wszystkimi ich dokładnymi cechami.
Co myślicie o tym sposobie myślenia? Może coś powinienem inaczej pomyśleć. Długi post, trochę posłużyło to jako metoda gumowej kaczki. Jak po przeczytaniu tego coś komuś się wyraźnie na myśl ciśnie że coś powinienem inaczej, albo czegoś brakuje to chętnie posłucham.