Rzucanie wyjątków w czasie budowy jest ogólnie postrzegane jako mało grzeczne, ale nie jestem pewien, jak tego uniknąć, próbując wymusić ograniczenia na wartości klas przypadków .Jaki jest poprawny sposób wymuszania ograniczeń na wartości klas przypadków?
Powiedzmy na przykład, że muszę reprezentować zakres i że obie granice muszą być dodatnie. Natychmiastowa realizacja będzie:
case class Range(from: Int, to: Int)
To jednak nie upewnić się, że zarówno from
i to
są pozytywne, ani że to
jest większa niż from
.
Moim pierwszym odruchem jest wdrożenie go w następujący sposób:
case class Range(from: Int, to: Int) {
require(from >= 0)
require(to >= 0)
require(to >= from)
}
To jednak sprawia, że konstruktor Range
„s niebezpieczne.
Czy istnieje wspólny wzorzec zachowania łatwości użycia klas przypadków, wymuszania ograniczeń wartości i unikania wyjątków wyrzucania?
"wymuszać ograniczenia wartości i unikać wyrzucania wyjątków?" - co rozumiesz przez egzekwowanie?Co chcesz zrobić, gdy ktoś spróbuje skonstruować Range z nieprawidłową wartością from/to? –
Dzięki Paul, to jest sedno mojego pytania. Co powinienem zrobić? Próbuję zapobiec tworzeniu nieprawidłowych instancji i wydaje się, że istnieje zgoda co do tego, że konstruktorzy lub metody konstrukcyjne nie powinni rzucać. Nie wiem, jak to zrobić bez drugiego, czy istnieje rozwiązanie, którego nie widzę? –
Idealną odpowiedzią jest programowanie na poziomie typu (ale stroma krzywa uczenia się). Powinien to być błąd podczas kompilacji, aby coś takiego stworzyć. Jednak bez tego wydaje się, że masz cztery możliwości: zignoruj problem (zaakceptuj nieprawidłowe parametry), wyrzuć wyjątek, wymuś parametry do prawidłowych zakresów, oznacz instancję jako niepoprawną z flagą (i wyrzuć wyjątki po wywołaniu dowolnej metody to?). Ja, rzuciłbym wyjątek w konstruktorze ... –