Czemu nie ma być metod statycznych?

1

Podobno metody statyczne to zło: https://4programmers.net/Forum/Kosz/365170-zadanie_java_packages?page=1 (link się pewnie zaczerwieni niedługo, ale cóż)

Czemu?

Pod warunkiem, że funkcja statyczna jest czysta: Czym się różni metoda statyczna od funkcji znanej z funkcyjnych języków programowania? W zasadzie niczym i to pozwala nam na sprowadzenie takiego twierdzenia do absurdu, bo sprowadza się ono do zakazu korzystania z paradygmatu funkcyjnego.

Przynajmniej w C# Jeśli mamy funkcję niestatyczną, która nie korzysta z żadnych pól / properties / itp swojej klasy ani nie stanowi implementacji interfejsu to kompilator radzi, by zmienić ją na statyczną. I słusznie, bo jej nie-statyczność nic nie zdaje się wnosić.

2

Ale o co ci właściwie chodzi?

1
YetAnohterone napisał(a):

Przynajmniej w C# Jeśli mamy funkcję niestatyczną, która nie korzysta z żadnych pól / properties / itp swojej klasy ani nie stanowi implementacji interfejsu to kompilator radzi, by zmienić ją na statyczną. I słusznie, bo jej nie-statyczność nic nie zdaje się wnosić.

Tak zwykle zbudowany jest w wielu językach obiektowych pakiet funkcji matematycznych,z=Math.abs(x,y) i nie słyszałem aby jakiś ortodoks sobie żyły podciął.
OOP to tylko model rzeczywistości (dla mnie bardzo bliski, bliższy niz funkcyjne), a z modelowaniem trzeba wiedzieć, kiedy przestać, bo dochodzi do absurdu. Religijnym wojnom mówimy "nie" (Programowanie funkcyjne ma swoje inne "mury")

Oryginalny kompilator, czy extension od Studio daje tą propozycję? Jakiś linter - przynajmniej tak było w VS 2019?

Zablokowałbyś propozycję ustatycznienia dając virtual ... to jest tych udoskonaleń C# nad Javą, która starsza o 15 lat bardziej prymitywnie podchodzi do dziedziczenia, i nie może złożyć podobnej propozycji

Myśl jest ciekawa, np C# w nowszych wersjach otwiera furtkę, i daje (pozór) metody / funkcji poza klasą (w rzeczywistości w ukrytej automagicznej klasie)

10
YetAnohterone napisał(a):

Pod warunkiem, że funkcja statyczna jest czysta: Czym się różni metoda statyczna od funkcji znanej z funkcyjnych języków programowania? W zasadzie niczym i to pozwala nam na sprowadzenie takiego twierdzenia do absurdu, bo sprowadza się ono do zakazu korzystania z paradygmatu funkcyjnego.

Tak, to prawda.
Problem wziął się stąd, ze kiedyś ludzie przytomnie zauważyli, że globalny statyczny stan, służący do wymiany informacji między funkcjami w programie jest problematyczny, więc lepiej go unikać. Stąd się wzięło hasło, że statyczny stan to zło.
Mniej przytomni programiści zrozumieli, że "statyczne to zło", i teraz biegają po internecie i opowiadają kocopoły o tym, że metody statyczne, to zło.

Przynajmniej w C# Jeśli mamy funkcję niestatyczną, która nie korzysta z żadnych pól / properties / itp swojej klasy ani nie stanowi implementacji interfejsu to kompilator radzi, by zmienić ją na statyczną. I słusznie, bo jej nie-statyczność nic nie zdaje się wnosić.

No, a jak metoda nie korzysta ze stanu klasy, w której jest, to na 90% nie powinna być w tej klasie. :)

1

No, a jak metoda nie korzysta ze stanu klasy, w której jest, to na 90% nie powinna być w tej klasie. :)

może jeszcze być Smart constructorem (czy jak to tam nazywa się w OOP, chodzi mi o metodę statyczną tworzącą obiekty) i wtedy pasuje

2

Zmienne statyczne są złe, bo zazwyczaj są znakiem złego designu. Lepiej trzymać stan w normalnych polach przez co klasa może być używana w różnych kontekstach bez powiązanego stanu globalnego.
Metody statycznie nic tu nie mają, bo w każdej metodzie można zmieniać stan "statyczny".

Co do pytania: metody statyczne nie są złe. Samo przeświadczenie wzieło się, bo w przypadku OOP jest takie (według mnie błędne) przeświadczenie, że wszystko ma być rozszerzalne. Statyczne metody nie mogą być polimorficzne. Ja osobiście nie widzę problemu, jeśli metody statyczne to zwykłe "czyste" funkcje znane z innych języków. W przypadku języka takiego jak Java jest to jedyny sposób implementacji. Metoda statyczna (jeśli nie ma stanu) jest prosta do zrozumienia w kodzie, cały stan to przekazane argumenty przez co analiza kodu jest dużo przyjemniejsza a design lepszy

Tak czy owak w przypadku Javy metody statycznie używałbym tylko w dwóch kontekstach. Pierwszy to klasy czysto statyczne takie jak Objects czyli zwykłe przestrzenie nazw. Drugi to metody powiązane jakoś z typem klasy ale nie w taki sposób, że this to pierwszy argument. Może to być np. helper na funkcję a.add(b) -> add(a, b) albo np. konstruktory T create(...)

0
marian pazdzioch napisał(a):

Ale o co ci właściwie chodzi?

Kontynuuję po prostu tamten wątek. Gdybym mógł, napisałbym wiadomość w tamtym watku, ale nie mogę. W ostatnim poście z tamtego wątku moderator kazał kontynuować dyskusję gdzie indziej, co właśnie czynię

ZrobieDobrze napisał(a):

Myśl jest ciekawa, np C# w nowszych wersjach otwiera furtkę, i daje (pozór) metody / funkcji poza klasą (w rzeczywistości w ukrytej automagicznej klasie)

Niestety, tylko w ograniczonym zakresie: tylko zamiast klasy zawierającej metodę Main.

somekind napisał(a):

No, a jak metoda nie korzysta ze stanu klasy, w której jest, to na 90% nie powinna być w tej klasie. :)

Pomijając wyjątek opisany wyżej: Niestety w C# każda metoda musi być w jakiejś klasie. Więc jeśli mam czystą funkcję to zawsze musi być klasa, w której tej funkcji nie powinno być ;/

Zdarza mi się, że zgrzytam zębami, bo tworzę sztuczną klasę tylko po to, by gdzieś zmieścić funkcję.

4
YetAnohterone napisał(a):

Pomijając wyjątek opisany wyżej: Niestety w C# każda metoda musi być w jakiejś klasie. Więc jeśli mam czystą funkcję to zawsze musi być klasa, w której tej funkcji nie powinno być ;/

Nie to napisałem.
Jeśli w "zwykłej" klasie, która ma pola i metody na nich operujące, pojawia się metoda, która z tych pól nie korzysta, to znaczy najprawdopodobniej, że jej miejsce nie jest w tej klasie, bo nic ją z tą klasą nie łączy.
To, że metoda statyczna też musi być w jakiejś klasie, to szczegół. Mnie chodzi o pryncypia - jeśli metoda została umieszczona w klasie, mimo że nic ją z tą klasą nie wiążę, to najprawdopodobniej złamane jest SRP.

1

Poprawcie mnie jeżeli się mylę, ale programowanie obiektowe polega na tworzeniu obiektów, z których każdy ma swój stan reprezentowany przez jego instancję. Zmienne statyczne pasują tu jak pięść do nosa. Pomijając, że nie da się nawet potem namierzyć jak i gdzie są inicjalizowane.

1
ZrobieDobrze napisał(a):

OOP to tylko model rzeczywistości

Bzdura.

2
Riddle napisał(a):
ZrobieDobrze napisał(a):

OOP to tylko model rzeczywistości

Bzdura.

OOP to religia jak Scrum :p

2
KamilAdam napisał(a):
Riddle napisał(a):
ZrobieDobrze napisał(a):

OOP to tylko model rzeczywistości

Bzdura.

OOP to religia jak Scrum :p

Dla mnie OOP to po prostu paradygmat, taki sam jak FP. Albo spełniasz pewne kryteria i wpisujesz się w paradygmat, albo nie i się nie wpisujesz. Simple.

Ale zgadzam się że dookoła OOP krąży dużo więcej mitów niż wokół FP, nie wiem czemu.

2
YetAnohterone napisał(a):

Podobno metody statyczne to zło: https://4programmers.net/Forum/Kosz/365170-zadanie_java_packages?page=1 (link się pewnie zaczerwieni niedługo, ale cóż)

Czemu?

Pod warunkiem, że funkcja statyczna jest czysta: Czym się różni metoda statyczna od funkcji znanej z funkcyjnych języków programowania? W zasadzie niczym i to pozwala nam na sprowadzenie takiego twierdzenia do absurdu, bo sprowadza się ono do zakazu korzystania z paradygmatu funkcyjnego.

Przynajmniej w C# Jeśli mamy funkcję niestatyczną, która nie korzysta z żadnych pól / properties / itp swojej klasy ani nie stanowi implementacji interfejsu to kompilator radzi, by zmienić ją na statyczną. I słusznie, bo jej nie-statyczność nic nie zdaje się wnosić.

Kilka błędów tu widzę - po pierwsze, pewnie @KamilAdam się wypowie, ale to nie jest prawda że w paradygmacie funkcyjnym da się pisać tylko funkcjami. Metodami w obiektach też się da, to po pierwsze.

Po drugie, owszem - w moim poście z tamtego tematu zasugerowałem, że metody statyczne właściwie niczym się nie różnią od funkcji globalnych, i nadal to podtrzymuję. W niektórych językach, takich jak Python, PHP czy JavaScript, można deklarować funkcje jako tzw. first-class citizen (czyli możemy mieć funkcje, a nie metodę czy metodę statyczną). I tak jak o ile w takim JS'ie, Pythonie i PHP można rozumieć projekt który jest pisany takim stylem, tak w Javie i C# (przynajmniej dla mnie), to całkowicie nie ma sensu. Np zadanie z tego wątku: https://4programmers.net/Forum/Kosz/365170-zadanie_java_packages?page=1 całkowicie nie pasuje do funkcji statycznych, i jest to doskonały przykład jak nie dobierać rozwiązania do problemu.

Oczywiście, nie wszystkie metody statyczne mają tą wadę. Jak pisane było wcześniej, metody które pełnią funkcję "nazwanego konstruktora", jak Optional.of() albo Array.stream() są jak najbardziej okej. Możnaby je zamienić na konstruktor z przeładowanymi argumentami, ale takie "nazwane" instancjonowanie jest czytelniejsze. Dodatkowo, jest kilka ograniczonych metod, które mogłyby być funkcjami globalnymi, jak np Math.min(), Math.max(), Math.abs(), i one również są okej jako metody statyczne. Pewnie znalazłyby się kilka takich przypadków, może jak String.join(), ale to są raczej ograniczone przypadki. Wtedy taka klasa pełni trochę rolę namespace'a. Ciężko znaleźć koncepcyjną różnicę między metodą statyczną Math.max(), a funkcją globalną max() w namespace'ie Math. Można w Javie nawet dodać import static i używać normalnie return max(2,3); tak jakby faktycznie była funkcją globalną.

Problem się zaczyna, kiedy zaczynamy umieszczać nietrywialną logikę w funkcjach statycznych, albo robimy wszelakiego rodzaju "helpery" czy "utilsy" które nie są niczym innym jak tylko funkcjami globalnymi które łamią enkapsulację, i są wsadzone jako takie static methody do jakiejś klasy do której nie należą. Moim zdaniem wynika to z kilku błędów programistów, a najbardziej z tego, że niektórzy po prostu nie umieją dobrze projektować swoich klas, nazywać klas, dbać o SRP, odpowiednio organizować klas oraz znajdować odpowiednich proporcji i rozgraniczenia pomiędzy "domain-classes" a "general-purpose classes" (często niepotrzebnie przechylonych w stronę tego drugiego), i z tej nieumiejętności właśnie rodzą się statyczne metody - nieokrzesane bloby kodu niewiadomego pochodzenia który nie wiadomo gdzie pasuje, i nie wiadomo na czym operuje.

Dodatkowo, jak metoda jest niestatyczna, to łatwiej jest napisać kod, który jest cohesive, czyli "bliskie rzeczy są blisko, dalekie są daleko". Jak mamy publiczną metodę statyczną, to czasem aż prosi się żeby użyć jej tam gdzie się nie powinno. Np metody FileSystem.splitLines(), podczas wrapowania HTML'a w HtmlParser. No bo skoro jest gdzieś metoda statyczna do splitowania, to czemu jej nie użyć - a dobra praktyka (żeby nie łączyć systemu plików z HTMLem) jest olana. Z tego powodu metody statyczne łatwo jest użyć raz tu, raz tu, raz tu - często w jednej klasie mamy różne metody statyczne używane w czasem różnych modułach, zwłaszcza jak taka klasa jest typowym "utilsem", czyli nigdy nie jest instancjonowana, i ma same statici, i nie dość że w ten sposób robimy duże spaghetti, to robimy ukryte powiązania takim staticiem między klasami.

3

@Riddle

Dodatkowo, chciałbym jeszcze raz podkreślić, że bardzo się niezgadzam z wypowiedzią @ZrobieDobrze, że w programowaniu obiektowym chodzi o jakieś "modelowanie świata rzeczywistego". To jest absolutny absurd i nie ma nic wspólnego z prawdą. Obiekty oraz klasy, tworzy się tam, gdzie jest ku temu techniczny/programistyczny powód:

Nie wiem co masz na myśli pisząc "w programowaniu obiektowym chodzi o jakieś ", ale OOP jak najbardziej jest narzędziem do modelowania... rzeczywistości.

Praca programisty właśnie tym jest - zapisuje prawdziwe procesy w computer-friendly sposób, aby komputery mogły je obsługiwać i tutaj dobrym przykładem będzie np. branża logistyczna.

To jest całkowity absurd i nie ma żadnego sensu. Takie przekonanie że obiekt w kodzie źródłowym ma choćby w przypominać prawdziwy obiekt, to mit.

To że OOP służy do modelowania rzeczywistości wcale nie oznacza że masz zrobić klasę i dać jej propertisy odzwierciedlające te wszystkie prawdziwe.

To jakie hierarchie, zależności pomiędzy i API sobie przygotujesz to już twoja decyzja, ale nadal używasz do tego OOP (w językach OOP)

Gdyby było tak jak ty piszesz, to wszyscy powinni byliby tworzyć takie same klasy aby być zgodni z OOP, a jednak designy są różne i nadal jest to OOP.

1
1a2b3c4d5e napisał(a):

@Riddle

Dodatkowo, chciałbym jeszcze raz podkreślić, że bardzo się niezgadzam z wypowiedzią @ZrobieDobrze, że w programowaniu obiektowym chodzi o jakieś "modelowanie świata rzeczywistego". To jest absolutny absurd i nie ma nic wspólnego z prawdą. Obiekty oraz klasy, tworzy się tam, gdzie jest ku temu techniczny/programistyczny powód:

Nie wiem co masz na myśli pisząc "w programowaniu obiektowym chodzi o jakieś ", ale OOP jak najbardziej jest narzędziem do modelowania... rzeczywistości.

Praca programisty właśnie tym jest - zapisuje prawdziwe procesy w computer-friendly sposób, aby komputery mogły je obsługiwać i tutaj dobrym przykładem będzie np. branża logistyczna.

Ten tok myślenia.

Riddle napisał(a):

Noi trzecią rzeczą, są tutoriale które mówią "funkcje mają być czasownikami, a obiekty rzeczownikami" - czy też "obiekty powinny reprezentować rzeczy", co nie jest prawdą, bo mamy obiekty typu "event", "command", "strategy", które nie reprezentują rzadnej rzeczy, ale używamy do tego klas i obiektów.

Poczułem potrzebę wypowiedzenia się nt rzeczy, rzeczowników i czasowników. Owszem, w dialektach prostych ludów afrykańskich są tylko rzeczowniki krowa, banan itd... - to paralela do naszego szkolnego wykładu OOP Jabłko extends Owoc itd (na marginesie: te ludy / jezyki nie maja abstrakcji liczby większej niz kilka)

Ale w języku ludzi wykształconych od tysięcy lat są rzeczowniki abstrakcyjne (i to bardzo ważne, regulujące stosunki gospodarcze, prawne itd), i "event" DLA MNIE nie jest żadnym złamaniem tej zasady

Więc jak mamy rzeczownik-abstrakcję np "transakcja" (w sensie handlowa, prawna, zaledwie od 3000 lat) dlaczego słowa nie poobracać w palcach jako programista, czym taka "transakcja" (np logistyczna jak podejmuje @1a2b3c4d5e ) jest, jakie ma dane, etapy, co się z nią moze zrobić, jakie ma niezmienniki i asercje itd...
Małżeństwo, pattern obiektowy od "klku" tysięcy lat (inaczej implementowany w kulturach, ale zawsze jako kolekcja referencji do niezależnych obiektów)

0

Jestem niekompetentny i nie chcę rozpętywać żadnej gównoburzy albo dyskusji oraz mam pozytywne nastawienie do użytkownika @Riddle. Piszesz, że bzdura i przedstawiasz oraz narzucasz swoją interpretację OOP, a pamiętam temat o strategii (wzorcu) w programowaniu obiektowym, gdzie usilnie forsowałeś swoje rozumienie i inerpretację OOP, a po kilku stronach burzliwej dyskusji wyszło, że zgodnie z Twoim paradygmatem OOP, wyrażenie 2 + 3 jest obiektowe. Tak jak napisałem, jestem niekompetentny, ale po prostu widać, że często chcesz narzucić innym swoją logikę, przekonania lub interpretację zagadnień programistycznych jako tą jedyną prawidłową.

2

Statiki to nie ZUO.
Howgh. Rzekłem.
Leniwy Bawół.

1

No i tym można zamknąć temat, dziękujemy można się rozejść.

1
Riddle napisał(a):

Ale zgadzam się że dookoła OOP krąży dużo więcej mitów niż wokół FP, nie wiem czemu.

Przypuszczam, że znam odpowiedź bo pamiętam jak strasznie ciężko było mi wskoczyć w "obiektówkę". Gdyby wówczas FP było porównywanie promowane jak OOP to pewnie szybciej bym załapał FP bo ogólna idea jest bardziej klarowna i szybciej można dostrzec korzyści. Zanim zacząłem swobodnie poruszać się w OOP minęło sporo czasu a po drodze powstała masa obiektowych bubli.

A teraz patrz... Poza wieloma zaletami OOP gratis mamy jeszcze metody statyczne, które pozwalają wykorzystywać je w "dziwny" sposób :-)

1
katakrowa napisał(a):

A teraz patrz... Poza wieloma zaletami OOP gratis mamy jeszcze metody statyczne, które pozwalają wykorzystywać je w "dziwny" sposób :-)

Dla mnie metoda statyczna to nie jest część OOP, tylko część JĘZYKA obiektowego lub "zasadniczo obiektowego" (kłócić się nie będę), któremu robi sie taki wytrych (ze względów MZ uzasadnionych)

Czyli jest POZA teorią Object Oriented Programming (a że teoria się tym nie zajmuje, to i nie zakazuje)

2
Riddle napisał(a):

I tak jak o ile w takim JS'ie, Pythonie i PHP można rozumieć projekt który jest pisany takim stylem, tak w Javie i C# (przynajmniej dla mnie), to całkowicie nie ma sensu.

Po pierwsze nikt nie zabrania łączenia ze sobą paradygmatów. Mozna napisać jedną trzecią kodu proceduralnie, jedną trzecią obiektowo i jedną trzecią funkcyjnie. Albo, przy tylko lekkim nagięciu dogmatycznych definicji tych paradygmatów wręcz twierdzić, że kod jest 100% funkcyjny i 100% obiektowy jednoczesnie.

Po drugie wybór języka często nie zależy od samego języka, ale od ekosystemu wokół tego języka i od tego, w czym już jest napisany codebase, z którym musimy pracować. Tym samym fakt, że język jest w teorii obiektowy jeszcze nie znaczy, że musimy pisać w nim obiektowo. Przykład: Unity3D promuje ostatnio ECS i DOTS, tymczasem to podejście jest dokładną odwrotnością tego, do czego został zaprojektowany C#.

Po trzecie, jak już kiedyś pisałem na tym forum, C# zdaje się powoli dryfować w kierunku wspierania paradygmatu data driven i rozdzielania kodu i danych. W szczególności jest coraz większe wsparcie dla statycznych metod, można je już definiować w interfejsach.

0
YetAnohterone napisał(a):

, C# zdaje się powoli dryfować

Spowodowałeś u mnie powrót myślenia, czy/kiedy stanie się kolejnym C++
Tzn na tym etapie jeszcze podoba mi elastycznośc komitetu sterujacego C# większa niż w Javie, ale mam złe przeczucie dokąd to zaprowadzi z latami.

Edit: ale tak, zgadzam się z sensem postu.

4

Nie wiem czemu ma nie być metod statycznych. Jestem w stanie zrozumieć, dla czego ma nie być zmiennych statycznych (też duże uproszczenie), ale dla mnie metoda będąca funkcją pure wręcz powinna być statyczna, bo od razu sygnalizuje to właśnie jej czystość.

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