Jak organizować funkcyjny kod?

1

Hej
Od kiedy piszemy w firmie w kotlinie, zaczęło się pojawiać dużo więcej "funkcyjnego" kodu niż wcześniej w javie. (okej, funkcyjne to może nadużycie, ale więcej jest metod, które nie potrzebują obiektu, żeby działać) I tak jak w OOP plik=klasa i nie ma raczej problemu, tak przy samych metodach zaczynają się 'schody'.

Używać po prostu bezstanowych obiektów? Może po prostu samych object? Czy jest na to jakiś inny myk? :)

@jarekr000000 @scibi92

2

Ale w Kotlinie funkcje mogą być poza klasa, więc ja bym stworzył plik zawierający podobne co do zastosowania funkcje

1
// plik  Foo.java
public class Foo
{
   public static void x() { Foo_x.execute(); }
   public static int y() { return Foo_y.execute(); }
}

// plik  Foo_x.java
public class Foo_x
{
   public static void execute() { /* do something */ }
}

// plik  Foo_y.java
public class Foo_y
{
   public static int execute() { /* do something */ return 0; }
}
0

@scibi92: no o to mi chodzi, tylko jak to sensownie ogarnąć, żeby w tym nawigować sensownie?

0

W przypadku kodu bezpośrednio związanego z projektem to mam płaską strukturę i pracuje z plikami po 2-5k lini kodu.

Są też fragmenty kodu, których nie zmieniam i jeśli to ma sens to wydzialam je do osobnych plików w utils.

Wolę proste rozwiązania, wtedy nie tracę wtedy czasu na wymyślanie przestrzeni, dodatkowych nazw i podziałów, które przy małych / średnich projektach i tak się nie zwracają.

4

Chyba wszystko zależy od tego jak duże chcesz mieć pliki. Ja lubię małe pliki po 50-200 linii. Pracowałem kiedyś w firmie gdzie mocno przestrzegali zasady jednej odpowiedzialności tak bardzo że wiele serwisów biznesowych miało tylko jedną funkcję (metodę, to była Java). Np zamiast wielkiego UserService były klasy CreateUserService GetUserService DeleteUserService FindUserService itd. Klas było bardzo dużo, ale dobrze się po nich nawigowało bo miały prostą strukturę.
Teraz jak piszę hobbystycznie w Haskellu staram się pisać podobnie. Moduł (plik) ma często tylko jedną funkcję publiczną a reszta to funkcje pomocnicze prywatne. (Czasem oprócz głównej funkcji publicznej udostępniam też inne na potrzeby testów jednostkowych co mnie martwi :/ ) Oczywiście nie wszystkie moduły tak wyglądają. Mam też moduły *Util gdzie jest wiele małych publicznych funkcji które nie zasługują jeszcze na osobne moduły

0

Może podejdź do tego tak że wyobrażasz sobie jakby to wyglądało gdybyś miał klasy Javova i w ten sposób dziel na pliki? Tzn niech plik odpowiada klasie, taki mój pomysł

1

Ja bym dawał object i dzielil domenowo

2

Polecam popatrzeć jak wygląda organizacja w takich bibliotekach jak Arrow, Kotlinx-Coroutines, Kotest czy standardowa biblioteka Kotlina. W skrócie - jeśli coś może być rozszerzeniem na typie, to jest rozszerzeniem na typie. Te rozszerzenia grupowane są za pomocą kategorii czy domeny w plikach. Jeśli coś jest czystą funkcją wejścia i wyjścia jak generatory czy buildery, to są top level funkcjami zebranymi w podobny sposób, co wcześniej wspomniane rozszerzenia. Jeśli obawiasz się zatłoczonej przestrzeni nazw i podpowiedzi w IDE, to modyfikator internal, moduły oraz zależności implementation w Gradle są zbawieniem.

Jeśli interesuje Cię organizacja też w kontekście współpracy z Javą warto sprawdzić jak wyglądają struktury Okio i OkHttp.

2
danek napisał(a):

Hej
Od kiedy piszemy w firmie w kotlinie, zaczęło się pojawiać dużo więcej "funkcyjnego" kodu niż wcześniej w javie. (okej, funkcyjne to może nadużycie, ale więcej jest metod, które nie potrzebują obiektu, żeby działać) I tak jak w OOP plik=klasa i nie ma raczej problemu, tak przy samych metodach zaczynają się 'schody'.

Używać po prostu bezstanowych obiektów? Może po prostu samych object? Czy jest na to jakiś inny myk? :)

Przecież programowania funkcyjnego nie wynaleziono wczoraj.
https://blog.inf.ed.ac.uk/sapm/2014/02/14/funtional-programming-in-large-scale-project-development/

W programowaniu funkcyjnym nie masz obiektów, tylko funkcje i struktury.
Nie robiłem nic dużego w FP, raczej para-FP, ale zwykle najpierw wydzielasz funkcje operujące na wybranych strukturach na wzór Apache Commons.
Potem ew. usztywniasz struktury (Employees zamiast List<Employees>) i definiujesz na nich specyficzne funkcje - jeśli potrzebne (np. Employee supervisor(Employees es, Employee e1)).

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