Java - statyczne klasy

0

Witam.
Mam pewne przyzwyczajenie z C# że piszę sobie statyczne klasy, które odpowiadają za konkretne operacje w aplikacji. Przykład:
SQL - connectionStringi, zapytania do bazy, operacje na bazie danych
Methods lub Utils - funkcje, zmienne wykorzystywane w cały projekcie.
Pytanie: Czy Java też pozwala na takie zabiegi? Czy jest jakieś inne podejście tego języka do moich przyzwyczajeń?

Ps.
Chodzi o apke na Androida.

0

ogolnie jezeli tylko mozesz to omijaj staticki jak tylko sie da, tworz sobie normalne klasy i injectuj je np. daggerem.

kod gdzie jest masa statickow jest koszmarem jezeli chodzi o testowanie, a w androidzie tego akurat sporo.

0

A mogę prosić o delikatne wytłumaczenie jak to pisać. Ogólnie po tych filmikach i tutorialach jest pełno info, skąd, po co i że super działa ale nigdzie konkretnego przykładu.
Żeby zrozumieć dobrze:
CSharp

public static class SQL
{
  public static string ConnectionString = "bla bla bla";

  public static int GetID(string name)
  {
     return 123456;
  }
}

//użycie

string con = SQL.ConnectionString;
int id = SQL.GetID("AdamWox");

Nie ukrywam, że gdzieś obiło mi się o oczy/uszy żeby w Java nie używać static tak więc chce to zrobić dobrze :)
Jak takie coś by wyglądało w Javie z daggerem?

0

Stałe możesz spokojnie mieć jako statyczne pola w klasie. Ważne żeby były rzeczywiście stałymi, a nie np listami o zmienianej długości.

Nie ma żadnej filozofii w robieniu stałych w Javie:

public class Stałe {
  public static final String stała = "stała";
}

A connection string to bardziej pasuje do pliku konfiguracyjnego niż do stałych w kodzie.

Nie ukrywam, że gdzieś obiło mi się o oczy/uszy żeby w Java nie używać static tak więc chce to zrobić dobrze :)

Problemy ze staticami raczej nie zależą od języka.

0

Czy metody też mogę robić static

1

Co do:

obiło mi się o oczy/uszy żeby w Java nie używać static

To nawet nie wiesz ile bzdur ludzie powtarzaja, w ramach tzw. kultu cargo.

Methody i pola static mozesz mieć. Są dla ludzi. Ale fakt, że początkujący zwykle nadużywają i większość staticów tylko przeszkadza.
W praktyce pól static nie potrzeba w zasadzie nigdy, a metody static pisze się bardzo rzadko (poza public static void main).

Powód to taki, że static może poważnie utrudnić testowanie kodu. W szczególności przytoczony przez Ciebie kawałek klasy SQL to niezła katastrofa. Zarówno w Javie, jak i w C#.
Gdybyś w tej klasie miał jakisbardziej skomplikowany SQL z selectem, to jak byś napisał test, korzystając na czas testu z jakiejś testowej bazy danych?
A w większych projektach testy automatyczne są w zasadzie niezbędne.

Chyba, że podlegasz pod sułtana kosmitów:
Po co testować

0

Ok, rozumiem. To są moje początki w Java. Jestem zmuszony, ponieważ odkąd M$ przejął Xamarina to nie chce działać...
Jak w takim przypadku ogarnąć takie klasy, które odpowiadają za konkretny "moduł" w aplikacji - SQL, Utils?

0

A co by Ci sie złego stało, gdyby to była zwykła klasa z niestatycznymi metodami?
(pewnie by było lepiej jakbyś dorzucił większy kawałek kodu: jak tego chcesz używać)

0

Wydawało mi się, ze lepiej jest zrobić SQL.GetTowary() niż

SQL sql = new SQL();
sql.GetTowary();

Czy singleton?

0

Nie wiem czy dla początkującego dagger to nie za dużo. Najpierw wypadałoby poznać jak działa całe api androida, dagger to dopiero potem.

0
AdamWox napisał(a):

Wydawało mi się, ze lepiej jest zrobić SQL.GetTowary() niż

SQL sql = new SQL();
sql.GetTowary();

Czy singleton?

A nie możesz tej klasy SQL zrobić raz z danymi z konfiguracji, a potem wstrzykiwać do innych klas (tylko tych które bezpośrednio korzystają z klasy SQL) przez konstruktor? Np:

// tworzenie
String connectionString = config.getConnectionString();
SQL sql = new SQL(connectionString);
// wstrzykiwanie przez konstruktor
Service1 service1 = new Service1(sql);
Service2 service2 = new Service2(sql);
// itd
// korzystanie
class Service1 {
  // bolierplate potrzebny by wstrzykiwanie działało i wyglądało po ludzku
  private final SQL sql;
  public Service1(SQL sql) {
    this.sql = sql;
  }
  // przykładowa metoda w serwisie korzystająca z bazki
  Typ1 metoda1(Typ2 parametr1) {
    Typ3 daneZBazki = sql.metodaNaBazce(parametr1);
    Typ1 wynik = mielimyDane(daneZBazki);
    return wynik;
  }
}
0

Co w przypadku gdy obiektu klasy SQL będę musiał użyć w więcej niż jednym miejscu? Za każdym razem mam go tworzyć?
Powiedzmy, że mam dwie formy LoginActivity i MainActivity. W tej pierwszej loguje się do aplikacji czyli wykorzystał bym obiekt SQL do sprawdzenia czy użytkownik istnieje w bazie, w drugiej powiedzmy, że na wejście ściągam listę kontrahentów i znowu tworze obiekt SQL żeby zrobić inną operację.
Inny przykład, połączenie do mojego Web API. Mogę mieć 3 różne formy KontrahenciActivity, TowaryActivity, DokumentyActivity i w każdym z nich będę tworzył obiekt klasy API, aby wykonać konkretną operacje? Czy to nie wpłynie na wydajność jak będę miał tyle obiektów, które robią to samo?

0

Po pierwsze nie wpłynie na wydajność. Po drugie, gdzie tam widziesz kilka instancji SQL? Jest jeden obiekt SQL stworzony w kodzie podanym przez @Wibowit.
(możesz zrobić analogicznie).

0

Nie chodziło mi o tworzenie obiektów SQL w jednej formie tylko dla kilku. @Wibowit podał przykład z wykorzystaniem czyli tak jakby w jednej formie. Rozumiem, że mogę tworzyć obiekt SQL, tak jak @Wibowit pokazał w każdej możliwej formie nawet jeśli będę miał ich 15?

0

Możesz to też wrzucić w zasoby, coś w tym stylu (w res/values/strings.xml):

<string name="connection_string" translatable="false">blablabloa</string>

A w każdym activity możesz dostać się do tego przez:

String connectionString = getString(R.string.connection_string);
0

@Wibowit: w Androidzie dane do Activity przekazuje się przez Intent, w ogóle nie wywołuje się jawnie konstruktora.

0

OK. Skoro ktoś inny wywołuje za nas konstruktor to niestety też trzeba kogoś innego by dostarczał zależności.

Tak czy siak nie trzeba popadać ze skrajności w skrajność. Można mieć globalne repozytorium zależności, ale korzystać z niego bezpośrednio w jak najmniejszej ilości miejsc, a resztę załatwiać normalnym wstrzykiwaniem zależności bądź przekazywaniem zależności jako parametry metod.

0

No i taki mechanizm jest - Intent.

0

W Javie nie ma czegoś takiego jak klasa statyczna w rozumieniu C#. W przypadku Java klasa statyczna to szczególny przypadek inner class, nie mający dostępu do elementów klasy nadrzędnej: Java klasa wewnętrzna statyczna

Występują natomiast pola i metody statyczne. Deklarowanie stałych jako:

public static String CONNECTION_STRING = "mysql://....";

Jest całkowicie ok. Jeżeli chcesz mieć funkcjonalny odpowiednik klasy statycznej z C# zadeklaruj normalną klasę, wpisz stałe których potrzebujesz i oznacz konstruktor jako prywatny.
Metody statyczne - tutaj trzeba uważać, ale moim zdaniem używanie ich nie jest samo w sobie niczym złym. Zakładam samowystarczalność takiej metody - dostaje jakieś parametry, coś na ich podstawie, lub z nimi robi, zwraca wartość i koniec.Mam na myśli metodę typu:

public static int sum(int a, int b){return a+b;}

Zmienne statyczne - w dzisiejszych czasach nie używać. Jedyne sensowne użycie jakie znam to implementacja wzorca singleton, ale dzisiaj lepiej to zrobić za pomocą enum. W szczególności - nie wolno używać pól statycznych jako "zmiennych globalnych". Nigdy.

Co do problemu z większą ilością obiektów odpowiadających za dostęp do bazy - musisz mieć jeden. Trzeba zaimplementować jakoś singleton. Najprościej używając enum (chociaż w Androidzie jest to wyklęte, ale raz się żyje), w wersji pro warto zerknąć na Dagger 2 + Android Extensions do niego, ale na początek to trochę hardcore jest.

1 użytkowników online, w tym zalogowanych: 0, gości: 1