Tworzę bibliotekę zawierającą kilka metod analizowania dat i czasów napisów. Mam trudności z podjęciem decyzji o tym, jaki wyjątek powinny te metody wyrzucić, gdy argument łańcuchowy nie jest przetwarzalny. Jestem rozważa kilka opcji:Java API Design: NumberFormatException dla metody, która analizuje ciąg pół-numeryczny?
1. java.lang.IllegalArgumentException
- nieprawidłowy ciąg jest wyraźnie nielegalne argumentem, ale dla mnie IllegalArgumentException
zwykle oznacza błąd programowania, a to rzadko się chce zrobić wyraźne try catch
jednego. Wydaje mi się, że analizowanie ciągów jest często dla danych wejściowych z zewnątrz i jest bardziej szczególnym przypadkiem, który zasługuje na specjalne traktowanie. Jeśli, powiedzmy, masz duży blok kodu, który analizował dane wprowadzone przez użytkownika i zrobił coś innego z tym, możesz chcieć zawinąć ten kod w bloku catch catch, aby móc obsłużyć przypadek danych wejściowych użytkownika zawierających niepoprawny ciąg znaków. Ale złapanie IllegalArgumentException
nie byłoby zbyt dobre, aby wskazać nieprawidłowe dane wprowadzane przez użytkownika, ponieważ najprawdopodobniej w twoim kodzie znalazłoby się wiele miejsc, z których mógłby zostać wyrzucony (a nie tylko analizowanie danych wejściowych przez użytkownika).
2. java.lang.NumberFormatException
- to rzucony przez Integer.parseInt(String)
i innych podobnych metod analizowania w java.lang
. Dlatego większość programistów Javy jest zaznajomiona z tym, że jest wyjątkiem do przechwytywania, gdy próbujesz przeanalizować ciąg znaków, który może być poprawny lub nie (np. Dane wejściowe użytkownika). Ale ma w nazwie "Numer", więc nie jestem pewien, czy rzeczywiście pasuje on do rzeczy takich jak daty i czasy, które są w pewnym sensie numeryczne, ale koncepcyjnie inne w moim umyśle. Jeśli tylko został nazwany "FormatException" ...
3. java.text.ParseException
- nie jest to opcja, ponieważ jest zaznaczona. Chcę tego nie sprawdzać.
4. zwyczaj wyjątek - to robi wokół downsides z IllegalArgumentException
i NumberFormatException
, a to może przedłużyć IllegalArgumentException
też. Ale nie wydaje mi się, że warto dodawać wyjątki do biblioteki, chyba że są naprawdę potrzebne. Cytując Josh Bloch, "If in doubt, leave it out". (Także w moim przypadku, dla pakietu, który analizuje daty i czasy, trudno nazwać taki wyjątek: "DateFormatException", "TimeFormatException", "CalendricalFormatException" (jak JSR 310) - żaden nie wydaje mi się idealny w zastosowaniu do metod które parsują daty, godziny, daty-czasy itd. I myślę, że byłoby głupio tworzyć wiele wyjątków w jednym pakiecie, gdyby wszystkie były używane tylko do identyfikacji ciągów nieodwracalnych.)
Którą z opcji uważasz za najbardziej odpowiednią? sens?
NB Mam dobre powody, dla których nie chcę używać java.util.Date lub Joda Time, lub JSR 310, więc nie ma potrzeby sugerowania tych. Plus myślę, że byłoby dobrze, gdyby to pytanie było dość ogólne, ponieważ musi to być problem, z którym borykają się inni projektanci interfejsów API. Daty i godziny mogą równie dobrze być adresami IP, adresami URL lub innymi rodzajami informacji, które mają formaty łańcuchów, które wymagają analizy.
precedensy ustawione przez inne biblioteki
tylko kilka przykładów znalazłem:
java.sql.Timestamp.valueOf(String) throws IllegalArgumentException
java.util.Date.parse(String) throws IllegalArgumentException
(przestarzała metoda, i sytuacja ta nie jest zadeklarowana, ale można go zobaczyć w źródło)
java.util.UUID.fromString(String) throws IllegalArgumentException
org.apache.axis.types.Time(String) throws NumberFormatException
(również klasa Dzień w Apache Axis)
org.apache.tools.ant.util.DeweyDecimal(String) throws NumberFormatException
com.google.gdata.data.DateTime.parseDateTime(String) throws NumberFormatException
java.lang.Package.isCompatibleWith(String versionString) throws NumberFormatException
(w Java 7, trwa to kilka wersji ciąg z kropkami - trochę jak daty lub czasu w miłym sens)
Jestem pewien, że istnieje wiele pakietów, które używają niestandardowego wyjątku, więc wątpię, że jest dużo sensu w podawaniu ich przykładów.
zgadzam się wyjątki są ciężkie, ale ja zdecydowanie nie zgadzam się na uwzględnienie błędów w wartości zwracanej. To wymaga nadęty obiektów odpowiedzi lub powracający obiekt, z których oba mogą sprawić, że prosty interfejs API będzie bezużyteczny. –
+1 @ sean-patrick-floyd: może zwrócić wartość null, następnie nadpis jest w kodzie, przez co staje się bezużyteczny. – subsub
To naprawdę kwestia gustu. Zastanawiałem się nad wykorzystaniem metod takich jak parseOrNull (String), ale nie sądzę, że tak naprawdę pasuje do sposobu Java, który działa zgodnie z podstawowymi bibliotekami JDK. Poza tym zmuszasz ludzi do sprawdzania wartości zerowych lub uzyskują niepomocny wyjątek NullPointerException w przypadku, gdy analizują łańcuchy, które w 100% spodziewają się, że są poprawne (w przeciwieństwie do danych wprowadzanych przez użytkownika, gdy spodziewają się prawie wszystkiego). –