Mam klasę pełną funkcji użytkowych. Tworzenie instancji tego nie ma sensu semantycznego, ale nadal chcę wywoływać jego metody. Jak najlepiej sobie z tym poradzić? Klasa statyczna? Abstrakcyjny?
@matt b: Jak zauważył David Robles w swojej odpowiedzi, nie ma potrzeby, aby klasa była ostateczna ... nie można jej dodać do podklasy, ponieważ podklasa nie będzie mogła wywołać konstruktora superklasy, ponieważ jest ona prywatna. Jednak ... nie ma nic złego w wyrażaniu się wprost. Ale jfyi :-).
Punkt 4: Wymuszaj nieinstanowalność za pomocą prywatnego konstruktora
- Próba wymuszenia nieinstancji poprzez tworzenie abstrakcji klasy nie działa.
- Domyślny konstruktor jest generowany tylko wtedy, gdy klasa nie zawiera jawnych konstruktorów, więc klasę można uczynić nieinstanowalną, dołączając konstruktor prywatny:
Ponieważ jawny konstruktor jest prywatny, jest niedostępny poza klasą. AssertionError nie jest ściśle wymagane, ale zapewnia ubezpieczenie na wypadek, gdyby konstruktor został przypadkowo wywołany z poziomu klasy. Gwarantuje, że klasa nigdy nie zostanie utworzona w żadnych okolicznościach. Ten idiom jest nieco sprzeczny z intuicją, ponieważ konstruktor jest dostarczony wyraźnie, więc nie można go wywołać. Dlatego rozsądnie jest zamieścić komentarz, jak pokazano powyżej.
Jako efekt uboczny ten idiom zapobiega również podklasie klasy. Wszystkie konstruktory muszą wywoływać konstruktor nadklasy, jawnie lub niejawnie, a podklasa nie miałaby dostępnego konstruktora nadklasy do wywołania.
Aby płynąć pod prąd, statyczni członkowie i klasy nie uczestniczą w OO i dlatego są źli. Nie, nie jest zły, ale poważnie, poleciłbym zwykłą klasę z pojedynczym wzorcem dostępu. W ten sposób, jeśli musisz zmienić zachowanie w jakimkolwiek przypadku na drodze, nie jest to poważna zmiana narzędzi. OO jest twoim przyjacielem :-)
singleton nie jest bardziej zły niż zastrzyk zależności :)
bezapelacyjny
12
OO ma swoje miejsce, ale są chwile, kiedy jest po prostu niepraktyczne lub byłoby to marnotrawstwem zasobów - na przykład coś tak prostego jak Math.abs (). Nie ma powodu, aby tworzyć instancję obiektu tylko po to, by utworzyć instancję obiektu, podczas gdy statyczne wywołanie metody równie dobrze by Ci służyło bez żadnego z OO-narzutów. ;)
obrabuj
2
@rob re OO, zgadzam się, Math.Abs prawdopodobnie nigdy nie potrzebuje instancji. Kiedy słyszę „Mam klasę użytkową”, widzę Math.Avg (), gdzie należy teraz dodać obsługiwane dla średniej ważonej. Widzę generator adresu URL, parametr wejściowy, wyjściowy adresu URL, który należy refaktoryzować, aby obsługiwał href, lub tylko adres URL itp. Z tego powodu posiadanie klasy narzędziowej opartej na obiektach obiektowych może się opłacić. Teraz zrezygnuję ze standardowej taktyki obronnej OO, testując! / me ducks
Bennett Dill,
3
skomentuj argumenty „prywatnego konstruktora”: daj spokój, programiści nie są tacy głupi; ale są leniwi. tworzenie obiektu, a następnie wywołanie metod statycznych? nie wydarzy się.
nie trać zbyt wiele czasu, aby upewnić się, że Twoja klasa nie zostanie niewłaściwie wykorzystana. miej wiarę w swoich kolegów. i zawsze istnieje sposób na niewłaściwe wykorzystanie Twojej klasy, bez względu na to, jak ją chronisz. jedyną rzeczą, której nie można nadużyć, jest rzecz całkowicie bezużyteczna.
Ktoś, kto widział (w kodzie produkcyjnym, a nie w kodzie studenta jsut) object.staticMethod Myślę, że przeceniasz możliwości Joe Random Programmer! :-P
TofuBeer
2
Klasa końcowa i prywatny konstruktor (dobry, ale nie niezbędny)
Nie ma sensu deklarować klasy jako static. Po prostu zadeklaruj jego metody statici wywołaj je z nazwy klasy w normalny sposób, jak klasa Math w Javie .
Ponadto, mimo że nie jest absolutnie konieczne, aby konstruktor był prywatny, warto to zrobić. Oznaczenie konstruktora jako prywatnego uniemożliwia innym osobom tworzenie wystąpień Twojej klasy, a następnie wywoływanie metod statycznych z tych wystąpień. (Te wywołania działają dokładnie tak samo w Javie, po prostu wprowadzają w błąd i szkodzą czytelności kodu).
Odpowiedzi:
Prywatny konstruktor i metody statyczne w klasie oznaczonej jako ostateczna.
źródło
Według wielkiej książki „Effective Java” :
Punkt 4: Wymuszaj nieinstanowalność za pomocą prywatnego konstruktora
- Próba wymuszenia nieinstancji poprzez tworzenie abstrakcji klasy nie działa.
- Domyślny konstruktor jest generowany tylko wtedy, gdy klasa nie zawiera jawnych konstruktorów, więc klasę można uczynić nieinstanowalną, dołączając konstruktor prywatny:
// Noninstantiable utility class public class UtilityClass { // Suppress default constructor for noninstantiability private UtilityClass() { throw new AssertionError(); } }
Ponieważ jawny konstruktor jest prywatny, jest niedostępny poza klasą. AssertionError nie jest ściśle wymagane, ale zapewnia ubezpieczenie na wypadek, gdyby konstruktor został przypadkowo wywołany z poziomu klasy. Gwarantuje, że klasa nigdy nie zostanie utworzona w żadnych okolicznościach. Ten idiom jest nieco sprzeczny z intuicją, ponieważ konstruktor jest dostarczony wyraźnie, więc nie można go wywołać. Dlatego rozsądnie jest zamieścić komentarz, jak pokazano powyżej.
Jako efekt uboczny ten idiom zapobiega również podklasie klasy. Wszystkie konstruktory muszą wywoływać konstruktor nadklasy, jawnie lub niejawnie, a podklasa nie miałaby dostępnego konstruktora nadklasy do wywołania.
źródło
AssertionError
na inne alternatywy, takie jakIllegalStateException
,UnsupportedOperationException
itp?Wygląda na to, że masz klasę narzędziową podobną do java.lang.Math .
Podejście to ostatnia klasa z prywatnym konstruktorem i metodami statycznymi.
Ale uważaj na to, co to robi dla testowalności, polecam przeczytanie tego artykułu
Static Methods are Death to Testability
źródło
Aby płynąć pod prąd, statyczni członkowie i klasy nie uczestniczą w OO i dlatego są źli. Nie, nie jest zły, ale poważnie, poleciłbym zwykłą klasę z pojedynczym wzorcem dostępu. W ten sposób, jeśli musisz zmienić zachowanie w jakimkolwiek przypadku na drodze, nie jest to poważna zmiana narzędzi. OO jest twoim przyjacielem :-)
Moje .02
źródło
skomentuj argumenty „prywatnego konstruktora”: daj spokój, programiści nie są tacy głupi; ale są leniwi. tworzenie obiektu, a następnie wywołanie metod statycznych? nie wydarzy się.
nie trać zbyt wiele czasu, aby upewnić się, że Twoja klasa nie zostanie niewłaściwie wykorzystana. miej wiarę w swoich kolegów. i zawsze istnieje sposób na niewłaściwe wykorzystanie Twojej klasy, bez względu na to, jak ją chronisz. jedyną rzeczą, której nie można nadużyć, jest rzecz całkowicie bezużyteczna.
źródło
źródło
Nie ma sensu deklarować klasy jako
static
. Po prostu zadeklaruj jego metodystatic
i wywołaj je z nazwy klasy w normalny sposób, jak klasa Math w Javie .Ponadto, mimo że nie jest absolutnie konieczne, aby konstruktor był prywatny, warto to zrobić. Oznaczenie konstruktora jako prywatnego uniemożliwia innym osobom tworzenie wystąpień Twojej klasy, a następnie wywoływanie metod statycznych z tych wystąpień. (Te wywołania działają dokładnie tak samo w Javie, po prostu wprowadzają w błąd i szkodzą czytelności kodu).
źródło
Możesz użyć adnotacji @UtilityClass z lombok https://projectlombok.org/features/experimental/UtilityClass
źródło