Bezpieczna mutowalność

0

Mamy obiekt:

@Getter
@Setter
public class Person {
    // ...
    private String gender;
    private String race;
    private Address address;
}

Jak wiadomo płeć może się zmieniać wiele razy w życiu z minuty na minutę. Chciałbym jednak walidować zmianę płci w zalenożści od miejsca zamieszkania. Jeśli ktoś zamieszkuje zacofane kraje jak Chiny to nie może zmienić płci i ma tylko 2 do wyboru, a jak nowoczesne jak Szwecja to ma do dyspozycji 57 płci.

Stworzyłem więc bezpieczny serwis do zmian atrybutów Person walidacji tych pól. Jak wymusić by nikt nie zrobił czegoś takiego: person.setRace("Spanish") tylko przez serwis?

Jedyne co mi porzychodzi do głowy to umieszczenie Person i PersonService w jednym pakiecie i ustawienie setterów "scope" Person na pakietowe, a serwisowe na publiczne. Niestety nie zawsze jest to możliwe, bo ludzie ładują serwisy do pakietów services a obiekty do model.

Inne rozwiązania?

1

Weź kotlina i zrób sealed class.

A jeśli już musisz to to rozwiązanie z pakietami można zrobić tak, że w pakiecie masz domenowego Person a do model leci tylko jakieś dto

1
  1. Ja bym nadal nie mutował tylko robił klona osoby ze zmienioną płcią, najlepiej jakimś ładnym Builderem.
  2. Builder czy Factory mogą zbać o poprawność danych, wrzucaniem tego do jakiegoś serwisu jest trochę dziwne
  3. Pamiętaj że to wszystko da się obejść ;)
0

Źle opisałem przykład. Dodajmy, że walidacja zmiany płci odbywa się w oparciu o inne obiekty, które muszą być zczytane z bazy oraz towarzyszy mu jakieś zdarzenie np. w krajach zacofanych jak PL przy każdej zmianie płci trzeba zgłosić to do urzędu.

0

O panie, jak ty chcesz się bawić w ściąganie danych z bazy bo ktoś zawołał setter to ten twój program za szybko nie podziała :D Walidowałbym tam gdzie zmiany robią się "trwałe", więc w jakimś repozytorium.

0

no to masz

repository.save(person) {
     if (!oldPerson.sex.equals(person.sex) {
         validateSex(oldPerson, person);
     }
}

a skąd masz poprzedni person oldPerson? Musisz tak chyba:

repository.save(person) {
     oldPerson = repository.getById(person.id);
     if (!oldPerson.sex.equals(person.sex) {
         validateSex(oldPerson, person);
     }
}

czyli, żeby zmienić płeć musisz dodatkowo odczytać coś z bazy

1

Wszystko zalezy od reszty kodu. Równie dobrze możesz mieć to wszystko zapisane w postaci eventów stylu sex change event przetwarzać listę eventów, zamiast mieć obiekt Person i robić na nim setSex. W takim wypadku wspomniany problem nie istnieje. Przykro mi ale trudno coś poradzić kiedy wymyślasz jakieś sztuczne przykłady.

Zresztą odczytanie z bazy raz przy zapisie i tak jest 100 razy lepsze niż robienie tego przy każdym set ;)

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