Konwencje stosowania interfejsów, klas abstrakcyjnych oraz klas

0

Cześć, wiem co to są interfejsy, klasy abstrakcyjne oraz klasy, wiem również na czym polega dziedziczenie. Jednak mam zagwozdkę jak projektować programy tak, aby tworzyć je zgodnie z konwencją o ile takowa istnieje. Co jeżeli zamiast klasy stworzę interfejs i będę implementował metody, a następnie tworzył je w docelowych klasach albo co będzie jak stworzę klasę. Nie chce żeby dochodziło do sytuacji że ktoś mówi że powinienem to zaimplementować w inny sposób. Podam może przykład. Aktualnie uczę się JDBC i jak wiemy aby połączyć się tam z bazą danych należy utworzyć za pomocą klasy Connection obiekt np. connection. Problem polega na tym, że mając kilka klas odpowiadających za logikę JDBC metodę tę trzeba tworzyć w każdej klasie, dlatego postanowiłem przenieść metodę do osobnego tworu aby metoda połączenia była napisana tylko raz, a wszystkie klasy zainteresowane mogłyby z niej korzystać. Jednak problem jest taki że nie rozumiem za bardzo kiedy twory typu klasy abstrakcyjne, interfejsy się wykorzystuje, a w internecie prezentują klasy abstrakcyjne i interfejsy na podstawie pojazdu albo zwierzęcia i psa - nic mi to nie mówi. Patrząc na mój przykład mógłbym:

  1. Utworzyć klasę z publiczną metodą statyczną getConnection() i wywołać tę metodę w klasach docelowych.
  2. Utworzyć klasę po której będzie dziedziczyć każda klasa docelowa i wywoływać tę metodę.
  3. Utworzyć interfejs gdzie utworzę metodę getConnection(), zaimplementuje go do każdej klasy docelowej, a następnie utworzę docelową metodę w każdej z nich.
  4. Utworzę klasę abstrakcyjną - w zasadzie punkt 1, 2 i 3.

Każda implementacja jaka jest tutaj opisywana powinna zadziałać identycznie, jednak różni się. Pytanie jest, jak powinno się to stosować i kiedy stosujemy klasy abstrakcyjne, interfejsy, a kiedy zwykłe klasy, bo tak na prawdę cały program można stworzyć na zwykłych klasach... Z góry dzięki za odpowiedzi.

2

Poczytaj trochę, hasła: design patterns, SOLID, DDD.

3

1 vs 2 to jest problem kompozycja vs dziedziczenie. przy czym w 99% kompozycja jest lepsza niż dziedziczenie w Javie. (W Scali może być na odwrót bo tak można więcej naczarować z dziedziczeniem i standardem jest dziedziczenie z LazyLogging jak chce się logera)

0

@NadpobudliwyTraktor:

No właśnie, słusznie odkryłeś, umiejętność napisania syntaktycznie poprawnej klasy to jeszcze nie OOP.
Dobra literatura, udział/kibicowanie w jakimś DOBRYM projekcie o.s.

KamilAdam napisał(a):

1 vs 2 to jest problem kompozycja vs dziedziczenie. przy czym w 99% kompozycja jest lepsza niż dziedziczenie w Javie.

Jak w przeszłości dziedziczenie było o wiele przeceniane (zwłaszcza w dydaktyce), tak teraz chyba wahadło się odwinęło w przeciwną stronę, i jest wynalazkiem diabła, MSZ nieslusznie.
Obok jest śliczny watek na dziedziczenie (ew implementowanie interfejsu), ale autor tego nie zrobił.

Tak w ogóle, co do aktualnie modnych i niemodnych, to we własnym kodzie może bym sobie wstrzyknął? (@NadpobudliwyTraktor to zdanie nie dla Ciebie,. he, he)

NadpobudliwyTraktor napisał(a):
  1. getConnection() i wywołać tę metodę w klasach docelowych.

Wyłącznie w bloku "try with resources" - inaczej będziesz gubił otwarte połączenia. To tak w szczegółowej kwestii. Można mieć kod elegancki z punktu widzenia designu obiektowego, ale mający błędy runtimowe , np gubienie zasobów

0

@NadpobudliwyTraktor: pytanie, co ty w ogóle piszesz. Jeśli po prostu chcesz obsłużyć łączenie się do różnych baz to możesz to prosto ogarnąć:

public class ConnectionFactory { 
   private final String connectionUrl; 
   private final Properties connectionProperties;

   public ConnectionFactory(final String connectionUrl, final Properties properties) {
      // ...
   }

   public Connection getConnection() {
      // ...
   }

   public static ConnectionFactory database1ConnectionFactory(/* arguments */) {
      // create connectionUrl and properties based on arguments
   }
   
   public static ConnectionFactory database1ConnectionFactory(/* arguments */) {
      // create connectionUrl and properties based on arguments
   }

   // ...
}

Albo w ogóle stworzenie URLa i Propertiesów byłoby poza klasą - np. wczytywane z pliku.

2

Trochę za szybko wchodzisz w ten temat. Opanuj "teorię", dowiedz się co to klasa, interface, klasa abstrakcyjna. Poczytaj trochę o wzorcach projektowych, spróbuj używać, rozpoznawać je w użytych bibliotekach. W którymś momencie, jeden po drugim zaczną "klikać". To akurat taki temat, który łatwo wykuć, ale zrozumienie nie jest proste. Dobra książka do przeczytania to Effective Java, chociaż pewnie na początek będzie trudna do zrozumienia. Ale wciąż z bardziej sensownymi i realnymi przykładami niż te koty i psy z tutoriali. Moim zdaniem trzeba parę razy wpakować się na minę, zrozumieć, że człowiek wpakował się na minę i czym była ta mina, żeby zrozumieć po co są wzorce projektowe, jak i przede wszystkim kiedy ich używać.

0

@wartek01: nic takiego nie powiedziałem. Zupełnie nie zrozumiałeś co oznacza ten tekst o prawnikach. Relacje między rzeczywistością "Pies jest Zwierzęciem", nie są odzwierciedlane przez rzeczy, które reprezentują rzeczy Psa i Zwierze (w kodzie). Relacja Mąż-Żona podczas rozwodu nie odzwierciedlana przez relację między prawnikami ich reprezentujących. Polecam filmik, jest przykład Prostokąt/Kwadrat. — MarekR22 19 minut temu

Prostokąt/kwadrat jest znanym przykładem testującym granice intelektualne pomiędzy szkolno-codzienno-matematycznym światem a konkretnie programowaniem (coś a'la w zupełnie innej dziedzinie, problemy relacyjno-obiektowe).

a) W moim odczuciu problem kwadratu/prostokąta na zawsze odsuwa poza orbitę przyjęcie niezmienniczości (immutability), bo (znany mi) problem k/p jest w setterach.
Matematyka zawsze mówi "dany jest prostokąt 100x100" i nigdy nie mówi "zmieńmy go na". Byty matematyczne są wieczne, nie podlegaja zmianie (w tych dziedzinach matematyki, nie będę się kłócił na poziomie Hawkinga)

b) jako PROGRAMISTA bym np rzucił wyjatkiem przy próbie ustawienia X innego od Y - czego jako MATEMATYK bym nie mógł zrobić, bo tam nie ma czegoś takiego.

Dobrze, że problem kwadrat/prostokąt został postawiony w teorii informatyki. Nie dlatego, ze mówi coś wiekopomnego o kwadracie czy prostokącie, ale o nas, o naszej oldmiennosci od matematyki

Drugie, co tzreba powiedzieć, że jednak my programiści nieustannie pracujemy w modelu, a nie w rzeczywistości, którą model odwzorowuje, nawet jeśli ta rzeczywistości jest też abstrakcyjna bo matematyczna, ale nawet matematyka, to nie to samo co my.
A modelowanie nigdy nie jest doskonałe. Powszechnie się uznaje "ten model jest wystarczający" / "ten nie jest"
Nikt oprócz dziennikarzy w kolorowych brukowcach nie wierz w doskonały model.

1

nic takiego nie powiedziałem. Zupełnie nie zrozumiałeś co oznacza ten tekst o prawnikach. Relacje między rzeczywistością "Pies jest Zwierzęciem", nie są odzwierciedlane przez rzeczy, które reprezentują rzeczy Psa i Zwierze (w kodzie). Relacja Mąż-Żona podczas rozwodu nie odzwierciedlana przez relację między prawnikami ich reprezentujących. Polecam filmik, jest przykład Prostokąt/Kwadrat. — MarekR22 28 minut temu

Użyłeś słowa "relacja" w dwóch znaczeniach
a) relacja miedzy niezaleznymi obiektami (jak w życiu). jest relacja męża-żony ew. prawnika/ów
b) relacja miedzy klasami, a to już wynika tylko z ludzkiego procesu poznawczego. Nie istnieją jednocześnie klasa konkretna i klasa abstrakcyjna, szczęśliwie informatyka właśnie takiego słowa używa

W realnym świecie istnieje Pies, o określenie Zwierzę jest uczynioną przez ludzki umysł abstrakcją.
Co @wartek01 podkreślił, że realny Pies może umrzeć w tej samej mikrosekundzie co abstrakcja Zwierzę którą JEST A umiera tylko jedno.
(O ile kogoś obchodzą abstrakcje. Padlinożercze robaki interesuje tylko GC obiektu konkretnego Psa)

3

Używaj samych klas bez dziedziczenia tak długo jak będziesz chciał. Dodawaj interfejsy tylko tam gdzie chcesz użyć polimorfizmu albo DI. Dodawaj klasy abstrakcyjne jak będziesz miał prosty przypadek różnic w implementacji między klasami. Dodawaj dziedziczenie jak oszalejesz i będziesz chciał ze sobą skończyć.

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