Pracuję nad aplikacją z wieloma stałymi. Podczas ostatniego przeglądu kodu okazało się, że stałe są zbyt rozproszone i wszystkie powinny być zorganizowane w jeden „stały” plik stałych. Nieporozumienie dotyczy sposobu ich organizacji. Większość uważa, że użycie stałej nazwy powinno wystarczyć, ale doprowadzi to do kodu, który wygląda następująco:
public static final String CREDITCARD_ACTION_SUBMITDATA = "6767";
public static final String CREDITCARD_UIFIELDID_CARDHOLDER_NAME = "3959854";
public static final String CREDITCARD_UIFIELDID_EXPIRY_MONTH = "3524";
public static final String CREDITCARD_UIFIELDID_ACCOUNT_ID = "3524";
...
public static final String BANKPAYMENT_UIFIELDID_ACCOUNT_ID = "9987";
Uważam, że tego rodzaju konwencja nazewnictwa jest uciążliwa. Pomyślałem, że łatwiej będzie użyć publicznej klasy zagnieżdżonej i mieć coś takiego:
public class IntegrationSystemConstants
{
public class CreditCard
{
public static final String UI_EXPIRY_MONTH = "3524";
public static final String UI_ACCOUNT_ID = "3524";
...
}
public class BankAccount
{
public static final String UI_ACCOUNT_ID = "9987";
...
}
}
Pomysł ten nie został dobrze przyjęty, ponieważ był „zbyt skomplikowany” (nie podałem zbyt wielu szczegółów, dlaczego może to być zbyt skomplikowane). Myślę, że tworzy to lepszy podział między grupami stałych pokrewnych, a autouzupełnianie ułatwia również ich znalezienie. Nigdy tego nie widziałem, więc zastanawiam się, czy jest to zaakceptowana praktyka, czy też istnieją lepsze powody, dla których nie należy tego robić.
źródło
Odpowiedzi:
Nie zgadzam się z żadną z dwóch propozycji.
Stałe powinny znajdować się w swoich odpowiednich klasach , a nie w całkowicie stałej klasie w żadnej z dwóch zaproponowanych form .
Nie powinny istnieć klasy / interfejsy tylko dla stałych.
Klasa
CreditCard
(nie klasa wewnętrzna) powinna istnieć. Ta klasa / interfejs ma metody dotyczące kart kredytowych, a także stałychUI_EXPIRY_MONTH
iUI_ACCOUNT_ID
.Powinna istnieć klasa / interfejs
BankAccount
(nie klasa wewnętrzna). Ta klasa / interfejs ma metody odnoszące się do kont bankowych, a także stałeUI_ACCOUNT_ID
.Na przykład w interfejsie API Java każda klasa / interfejs ma swoje stałe. Nie są w klasie / interfejsie Stałych z setkami stałych, pogrupowanych w klasy wewnętrzne lub nie.
Na przykład te stałe dotyczące zestawów wyników znajdują się w interfejsie
ResultSet
:Ten interfejs ma sygnatury metod w stosunku do zestawów wyników, a klasy implementujące implementują to zachowanie. Nie są zwykłymi posiadaczami.
Stałe związane z działaniami interfejsu użytkownika znajdują się w interfejsie
javax.swing.Action
:Klasy implementujące zachowują się w stosunku do akcji interfejsu użytkownika, nie są jedynie stałymi posiadaczami.
Znam co najmniej jeden interfejs „stałych” (
SwingConstants
bez metod), ale nie ma setek stałych, tylko kilka, i wszystkie one są związane z kierunkami i pozycjami elementów interfejsu:Myślę, że stałe tylko klasy nie są dobrym projektem OO.
źródło
Jest to w 100% błędne rozwiązanie problemu „trudnych do znalezienia” stałych. Podstawowym błędem (niestety zbyt często popełnianym przez programistów) jest grupowanie rzeczy według kryteriów technicznych, takich jak stałe, wyliczenia lub interfejsy.
Z wyjątkiem architektur warstw, rzeczy powinny być pogrupowane według ich domen , a stałe tym bardziej, że są elementami bardzo niskiego poziomu. Stałe powinny być częścią klas lub interfejsów, które wykorzystują je jako część swojego API. Jeśli nie możesz znaleźć dla nich naturalnego miejsca do życia, musisz wyczyścić projekt interfejsu API.
Dodatkowo pojedynczy ogromny plik stałych zabija szybkość programowania w Javie, ponieważ stałe są wbudowane w klasy, które używają ich w czasie kompilacji, więc każda zmiana wymusza rekompilację wszystkich tych plików i wszystkich, które od nich zależą. Jeśli masz jeden plik ze stałymi, który jest używany wszędzie, w dużej mierze tracisz korzyści z kompilacji przyrostowej: obejrzyj blokowanie Eclipse na 15 minut, ponieważ rekompiluje cały projekt dla każdej zmiany w tym pliku. A ponieważ plik ten zawiera wszystkie stałe używane w dowolnym miejscu, będziesz go często zmieniać. Tak, mówię z własnego doświadczenia.
źródło
Masz rację. Twoja sugestia pozwala programistom
import static Constants.BankAccount.*
wyeliminować niezliczoną liczbę powtórzeń „BANKACCOUNT_”. Łączenie jest złym zamiennikiem faktycznego określania zakresu. To powiedziawszy, nie mam wiele nadziei na zmianę kultury zespołu. Mają pojęcie właściwych praktyk i prawdopodobnie nie zmienią się, nawet jeśli pokażesz im 100 ekspertów, którzy twierdzą, że się mylą.Zastanawiam się także, dlaczego w ogóle masz jeden plik „Stałe”. Jest to bardzo zła praktyka, chyba że te stałe są w jakiś sposób powiązane i są bardzo stabilne. Bardziej typowo staje się rodzajem zlewu kuchennego, który zmienia się nieustannie i od tego zależy wszystko.
źródło
Oba podejścia działają, i to jest ważne na koniec dnia.
To powiedziawszy, twoje podejście jest na tyle powszechne, że można je uznać za wzorzec, a dokładniej wystarczająco dobrą poprawę w stosunku do stałego anty-wzorca interfejsu . Nie rozumiem, co jest w tym skomplikowane, ale to dyskusja, którą powinieneś przeprowadzić ze swoim zespołem.
źródło
Jednym z wyzwań związanych z długą listą stałych jest znalezienie „poprawnej” stałej do użycia. Niezmiennie, ktoś dodaje stałą na końcu linii zamiast dodawać ją do grupy, do której należał.
W związku z tym pojawia się kolejna kwestia do dyskusji ze swoim zespołem - istnieje już de facto kategoryzacja stałych według ich nazw. Więc naprawdę nie powinno to być dla nich duże przejście od obecnego stanu do tego, co proponujesz. Korzystanie z autouzupełniania sprawia, że ciągłe wyszukiwanie jest jeszcze łatwiejsze.
Jeśli cokolwiek, twoja sugestia pomaga zniechęcić do stosowania „złej” stałej, nawet jeśli może ona pasować do konkretnej sytuacji. Zawinięcie stałych w reprezentatywną klasę zachęci programistów do przemyślenia, czy powinni z niej korzystać. Na przykład, jeśli używam
CreditCard.SomeConstant
do ogólnego użytku, naprawdę powinienem się zastanawiać, dlaczego nie maGeneral.SomeConstant
takiej sytuacji.Byłem przy projektach z potworami o stałych i wolałbym mieć metodę, którą sugerujesz. Jest czystszy, bardziej bezpośredni i pomaga uniknąć przypadkowego użycia.
źródło
Robię to od czasu do czasu (w języku C #), szczególnie jeśli muszę programować przeciwko / analizować dobrze znaną i ustaloną strukturę XML lub coś podobnie zagnieżdżonego i ciąg znaków ... na przykład niestandardowy parser bloku konfiguracji.
Buduję zagnieżdżoną strukturę klas pasującą do struktury hierarchicznej XML z nazwami klas odpowiadającymi elementom zawierającym właściwość const ciąg „ElementName” i podobną właściwość odpowiadającą każdemu atrybutowi (jeśli istnieje).
Ułatwia to programowanie z odpowiednim Xml.
źródło