Wzory wyrażeń regularnych Java - kompilować stałe czasowe lub elementy instancji?

13

Obecnie mam kilka pojedynczych obiektów, w których dopasowuję wyrażenia regularne, a moje Patterns są zdefiniowane w następujący sposób:

class Foobar {
  private final Pattern firstPattern =
    Pattern.compile("some regex");
  private final Pattern secondPattern =
    Pattern.compile("some other regex");
  // more Patterns, etc.
  private Foobar() {}
  public static Foobar create() { /* singleton stuff */ }
}

Ale ktoś mi kiedyś powiedział, że to zły styl, i zawszePattern należy je definiować na poziomie klasy, a zamiast tego wyglądać mniej więcej tak:

class Foobar {
  private static final Pattern FIRST_PATTERN =
    Pattern.compile("some regex");
  private static final Pattern SECOND_PATTERN =
    Pattern.compile("some other regex");
  // more Patterns, etc.
  private Foobar() {}
  public static Foobar create() { /* singleton stuff */ }
}

Żywotność tego konkretnego obiektu nie jest tak długa, a moim głównym powodem zastosowania pierwszego podejścia jest to, że nie ma sensu trzymać Patternsię litery s, gdy obiekt otrzyma GC.

Wszelkie sugestie / przemyślenia?

yamafontes
źródło

Odpowiedzi:

18

Obiekty Java Pattern są bezpieczne dla wątków i niezmienne (są to elementy dopasowujące, które nie są bezpieczne dla wątków).

W związku z tym nie ma powodu, aby ich nie robić, staticjeśli będą używane przez każdą instancję klasy (lub ponownie w innej metodzie w klasie).

Uczynienie ich zmiennymi instancji, bez względu na to, jak krótki (lub długi) ich czas życia oznacza, że ​​rekompilujesz wyrażenie regularne za każdym razem, gdy tworzysz instancję klasy.

Jednym z głównych powodów tej struktury (wzorzec będący fabryką obiektów Matcher) jest to, że kompilacja wyrażenia regularnego w jego skończonych automatach jest umiarkowanie kosztownym działaniem. Jednak okazuje się, że często to samo wyrażenie regularne jest używane wielokrotnie w danej klasie (poprzez wielokrotne wywołanie tej samej metody lub różne miejsca w klasie).

Z drugiej strony Matcher jest raczej lekki - wskazuje na stan wzorca w Wzorze i lokalizację w tablicy znaków dla łańcucha.


Dla Singleton , to sprawa nie powinna zbyt dużo, bo mimo wszystko, jest tylko jedna instancja tego, który znajduje się wokół i nie są ponownie i ponownie odtworzyć singleton (czekaj, „żywotność Singleton nie jest tak długa” ? Czy to znaczy, że uruchamianiu go wiele razy w ciągu aplikacji?)

Przekonasz się jednak, że niektóre statyczne analizatory kodu źródłowego nie rozpoznają, że coś jest singletonem, i narzekają, że tworzysz instancje wzorców ze stałych dla każdej instancji klasy.

Problem polega na tym, że nie jest to dobry wybór (nie jest zły w przypadku singletona) i możesz zacząć ignorować inne ostrzeżenia dotyczące rzeczy, o których mówi kompilator i narzędzia analityczne (czytaj więcej o uszkodzonych oknach ).

Związane z:

Społeczność
źródło
Niesamowita odpowiedź - tak, miałem na myśli, że kiedykolwiek został stworzony / użyty tylko raz, a kiedy wychodzi poza zakres, jest robiony na dobre. Dzięki za dalsze czytanie!
yamafontes