Wątek przeniesiony 2022-06-21 17:19 z Kosz przez Adam Boduch.

Strategia w programowaniu obiektowym

0

Wydaje mi się że strategia nie wpisuje się w programowanie obiektowe.

Bo ostatecznie strategia to dostarczenie dwóch implementacji jakiegoś algorytmu, do użycia przez inną klasę, ale przecież sam algorytm strategi niczego nie enkapsuluje, więc nie może być obiektem.

No bo jak stworzę dwie instancje tej samej strategii, to one będą identyczne. Nie będę mógł nigdy mieć dwóch instancji z różnmi tożsamościami, a to mi nie pasuje do obiektówki.

Dobrze myślę? Czy coś mi uciekło.

1

Czy strategia to jest ten pattern, za pomocą którego wyznawcy OOP symulują zwykłe callbacki?

W sensie, czy funkcję sortByAbs można nazwać implementacją strategii?

const array = [10, -2, 6, -5, 8, -100];
const sortByAbs = (a, b) => Math.abs(a) - Math.abs(b); // strategia?
array.sort(sortByAbs);
console.log(array); // [ -2, -5, 6, 8, 10, -100 ]

Jeśli tak, to myślę, że można powiedzieć, że ten pattern enkapsuluje wymienialną logikę (tutaj: konkretny sposób sortowania).

0
LukeJL napisał(a):

Jeśli tak, to myślę, że można powiedzieć, że ten pattern enkapsuluje wymienialną logikę (tutaj: konkretny sposób sortowania).

Załóżmy na potrzeby tego wątku, że kiedy mówię "enkapsulować coś" to mam na myśli "enkapsulować dane, parametry, wartości".

2

sam algorytm strategi niczego nie enkapsuluje, więc nie może być obiektem.

Dlaczego nie? Przecież algorytm może mieć swoje parametry, które może enkapsulować.

0
LukeJL napisał(a):

Czy strategia to jest ten pattern, za pomocą którego wyznawcy OOP symulują zwykłe callbacki?

W sensie, czy funkcję sortByAbs można nazwać implementacją strategii?

const array = [10, -2, 6, -5, 8, -100];
const sortByAbs = (a, b) => Math.abs(a) - Math.abs(b); // strategia?
array.sort(sortByAbs);

Raczej nie.

Strategią byłoby gdybyś za pomocą tego callbacka mógł wybrać czy sortowanie będzie np bubble sort vs quick sort. To czy sortujesz rosnąco lub malejąco, to raczej nie jest strategia.

Spearhead napisał(a):

sam algorytm strategi niczego nie enkapsuluje, więc nie może być obiektem.

Dlaczego nie? Przecież algorytm może mieć swoje parametry, które może enkapsulować.

Tak, i jeśli dostałby jakieś parametry to byłoby obiektem, wtedy spoko.

Ale ja mówię o takich "bezparametrowych" strategiach.

0

Strategia w programowaniu obiektowym jak najbardziej występuje.
To jeden z najczęściej wykorzystywanych wzorców przeze mnie.
Już sam routing w dowolnym frameworku to jest strategia właśnie.
Przykładowo strategie możesz mieć dla każdego typu enum.
Masz załóżmy 3 typy userów client, admin, seller i dla każdego robisz sobie oddzielną strategię, która załóżmy przy rejestracji robi inne rzeczy, wyświetla inne widoki userom, czy sprawdza uprawnienia, do tych trzech rzeczy może być po jednej klasie strategii, dla każdego typu z trzema takimi samymi metodami, ale mającymi inną logikę.

Swoją drogą wystarczy wpisać w googlach jak działa strategia.
Wszyscy gadają o wzorcach nie wiadomo ile, a tu z takim podstawowym wzorcem problem.

0
omenomn2 napisał(a):

Strategia w programowaniu obiektowym jak najbardziej występuje.
To jeden z najczęściej wykorzystywanych wzorców przeze mnie.

Jesteś pewien że ten kod jest obiektowy? Masz jak pokazać?

0

No jeżeli używam klasy z metodami, to tak jest to kod obiektowy.

0

Aha, czyli jeżeli zrobię klasę ClientStrategy z metodami register(), view(), can() i utworzę drugą klasę AdminStrategy z takimi samymi metodami i teraz w zależności od typu wywołam strategię (obiekt!!!), a następnie metodę to według Ciebie to nie jest obiektowy kod?
Jeśli nie, to może najpierw zapoznaj się z definicjami programowania obiektowego, a dopiero później jakieś wzorce ogarniaj, po kolei!

2
omenomn2 napisał(a):

Aha, czyli jeżeli zrobię klasę ClientStrategy z metodami register, view, can i utworzę drugą klasę AdminStrategy z takimi samymi metodami i teraz w zależności od typu wywołam strategię (obiekt!!!), a następnie metodę to według Ciebie to nie jest obiektowy kod?

Nope.

To o czym mówisz to polimorfizm, po prostu.

Jeśli nie, to może najpierw zapoznaj się z definicjami programowania obiektowego, a dopiero później jakieś wzorce ogarniaj, po kolei!

No jeśli ktoś uważa że programowanie obiektowe, to jest po prostu używanie obiektów, to dziękuję Panu za taką opinię. Może jeszcze powiesz że jak używasz funkcji, to to jest programowanie funkcyjne?

Dziękuję za Twój wkład w ten wątek, ale proszę, wstrzymaj się już od odpowiedzi w nim, bardzo proszę.

0

No jeśli ktoś uważa że programowanie obiektowe, to jest po prostu używanie obiektów, to dziękuję Panu za taką opinię

No, bo dokładnie tak jest.

2

Bo ostatecznie strategia to dostarczenie dwóch implementacji jakiegoś algorytmu, do użycia przez inną klasę, ale przecież sam algorytm strategi niczego nie enkapsuluje, więc nie może być obiektem.

a czemu nie? jeżeli tym algorytmem byłby jakiś złożony parser - pdf | worda(rtf) | worda(docx), to jak najbardziej pod spodem, za publicznym API może dziać się wiele - tymczasowa tablica danych wypełniana i używana w czasie jednego przejścia, indeksy, aktualny stan FSM, itd.

No bo jak stworzę dwie instancje tej samej strategii, to one będą identyczne. Nie będę mógł nigdy mieć dwóch instancji z różnmi tożsamościami, a to mi nie pasuje do obiektówki.

Czyli Singleton na ratunek algorytmom?

0

No bo jak stworzę dwie instancje tej samej strategii, to one będą identyczne. Nie będę mógł nigdy mieć dwóch instancji z różnmi tożsamościami, a to mi nie pasuje do obiektówki.

Nie muszą być identyczne, można wstrzykiwać do straregii do konstruktora np. model z wiersza bazy danych, i wtedy jak utworzysz dwie strategie z dwoma różnymi modelami, to będą mogły zwracać różne rzeczy i jeszcze w zależności od danej strategii.

Tak to jest programowanie obiektowe spełnione w 3 kwestiach czyli: atrybuty, metody i przechowywany stan, przechowywanym stanem w tym przypadku jest model zapisany w atrybucie przez konstruktor.

0
Riddle napisał(a):

Dobrze myślę? Czy coś mi uciekło.

Masz jakiegoś NPC w grze, wstrzykujesz mu strategię ruchu. Możesz utworzyć wiele instancji tego obiektu, ale z różnymi parametrami (stanem).:

public int steps
public String getNextStep(...){
return "w lewo"+steps+" kroków";
}

Możesz też zmieniać te parametry w trakcie życia samej strategii, albo nawet podmienić całą strategię w trakcie życia obiektu "gospodarza".

5
Riddle napisał(a):

Bo ostatecznie strategia to dostarczenie dwóch implementacji jakiegoś algorytmu, do użycia przez inną klasę, ale przecież sam algorytm strategi niczego nie enkapsuluje, więc nie może być obiektem.

Konkretna implementacja strategii jak najbardziej enkapsuluje algorytm. Nie wynika z tego oczywiście obiektowość. Tak samo jak z braku enkapsulacji nie wynika brak obiektowości.

No bo jak stworzę dwie instancje tej samej strategii, to one będą identyczne. Nie będę mógł nigdy mieć dwóch instancji z różnmi tożsamościami, a to mi nie pasuje do obiektówki.

Dobrze myślę? Czy coś mi uciekło.

Niektóre będą, inne nie będą.
Z tego, że w szczególnym przypadku można mieć implementację strategii, która nie posiada stanu nie sprawia, że to nie jest programowanie obiektowe.
Zwłaszcza, że klient strategii musi mieć do niej referencję, a więc ma już stan.

Próbujesz udowodnić, że jeśli np. jeden obiekt w programie nie posiada w stanu, to cały program nie jest obiektowy?

0

Kiedy mówię "enkaosulacja" mam na myśli hermetyzację parametrów, wartości danych, nie zachowania.

Jeśli stragia może nie przyjmować żadnych wartości i nadal być obiektowa, to znaczy to że wszystkie klasy mogłyby nie enkaosulować nic, i nadal być obiektowe.

A skoro tak, to można by napisać całą aplikacje nie enkapsulujac nic, i nazwać ją obiektową.

A to mi się nie wydaje prawdziwe.

0
Riddle napisał(a):

Wydaje mi się że strategia nie wpisuje się w programowanie obiektowe.

łoł, będzie tu ostro

Bo ostatecznie strategia to dostarczenie dwóch implementacji jakiegoś algorytmu, do użycia przez inną klasę, ale przecież sam algorytm strategi niczego nie enkapsuluje, więc nie może być obiektem.

Hm, czy widzisz tu podobieństwo do wizytatora? A jeśli widzisz to czy wizytator tez będzie nieobiektowy?
Nie obiektowe będą też bezstanowe serwisy w Javie. i mozliwe że wszystkie obiekty bezstanowe

No bo jak stworzę dwie instancje tej samej strategii, to one będą identyczne. Nie będę mógł nigdy mieć dwóch instancji z różnmi tożsamościami, a to mi nie pasuje do obiektówki.

Czy dotyczy to wszystkich obiektów które nie mają tożsamości, jak obiekty wartości (Value Object), rekordy w Javie, data class w Kotlinie, case class w Scali?

Czy wzorzec Pyłek to w takim razie wzorzec niszczenia obiektowości? Służy on przecież do cachowania obiektów wartości?

Czy wzorzec Prototyp też jest nieobiektowy? Też ważny jest tylko jego stan przed skopiowaniem a nie jego tożsamość

Pytanie nie na temat: czy metoda copy dla data class w Kotlinie i case class w Scali jest przykładem wzorca Prototyp? (Wiem że klasyczny prototyp zakłada najpierw skopiowanie, a potem modyfikacje, jednak metoda copy robi to jednocześnie)

3
Riddle napisał(a):

Kiedy mówię "enkaosulacja" mam na myśli hermetyzację parametrów, wartości danych, nie zachowania.

Jeśli stragia może nie przyjmować żadnych wartości i nadal być obiektowa, to znaczy to że wszystkie klasy mogłyby nie enkaosulować nic, i nadal być obiektowe.

W tym przypadku popełniasz błąd logiczny.
Fakt, że istnieje grupa obiektów, która może nie przyjmować żadnych wartości i nadal być obiektowa nie oznacza, że możesz z takich obiektów zbudować aplikację.

To tak, jakbyś powiedział, że jeśli człowiek składa się w 70% z wody to nic nie stoi na przeszkodzie, żeby wyłącznie z wody zbudować człowieka.

0
KamilAdam napisał(a):
Riddle napisał(a):

Wydaje mi się że strategia nie wpisuje się w programowanie obiektowe.

łoł, będzie tu ostro

Bo ostatecznie strategia to dostarczenie dwóch implementacji jakiegoś algorytmu, do użycia przez inną klasę, ale przecież sam algorytm strategi niczego nie enkapsuluje, więc nie może być obiektem.

Hm, czy widzisz tu podobieństwo do wizytatora? A jeśli widzisz to czy wizytator tez będzie nieobiektowy?
Nie obiektowe będą też bezstanowe serwisy w Javie. i mozliwe że wszystkie obiekty bezstanowe

Te serwisy w Javie tak, na pewno są nieobiektowe.

"Bezstanowe" masz na myśli takie które niczego nie enkapsulują czy takie które nie są mutable?

Co do wizytora, nie pamiętam kiedy zrobiłem wizytora który by czegoś nie enkaosulował, ale w strategi to normalne. W świecie lambd, trudno odróżnić strategie od callback'a.

No bo jak stworzę dwie instancje tej samej strategii, to one będą identyczne. Nie będę mógł nigdy mieć dwóch instancji z różnmi tożsamościami, a to mi nie pasuje do obiektówki.

Czy dotyczy to wszystkich obiektów które nie mają tożsamości, jak obiekty wartości (Value Object), rekordy w Javie, data class w Kotlinie, case class w Scali?

Czemu mają nie mieć tożsamości? Dwa Value Object mogą mieć różne dane i tym samym są inne od siebie.

Czy wzorzec Pyłek to w takim razie wzorzec niszczenia obiektowości? Służy on przecież do cachowania obiektów wartości?

No ale z zewnątrz zachowuje się jak obiekt. Klient jakiegoś interfejsu nie musi wiedzieć czy on jest pyłkiem czy nie.

Czy wzorzec Prototyp też jest nieobiektowy? Też ważny jest tylko jego stan przed skopiowaniem a nie jego tożsamość

Trzeba by się zastanowić. Nie wiem.

Pytanie nie na temat: czy metoda copy dla data class w Kotlinie i case class w Scali jest przykładem wzorca Prototyp? (Wiem że klasyczny prototyp zakłada najpierw skopiowanie, a potem modyfikacje, jednak metoda copy robi to jednocześnie)

0
wartek01 napisał(a):
Riddle napisał(a):

Kiedy mówię "enkaosulacja" mam na myśli hermetyzację parametrów, wartości danych, nie zachowania.

Jeśli stragia może nie przyjmować żadnych wartości i nadal być obiektowa, to znaczy to że wszystkie klasy mogłyby nie enkaosulować nic, i nadal być obiektowe.

W tym przypadku popełniasz błąd logiczny.
Fakt, że istnieje grupa obiektów, która może nie przyjmować żadnych wartości i nadal być obiektowa nie oznacza, że możesz z takich obiektów zbudować aplikację.

To tak, jakbyś powiedział, że jeśli człowiek składa się w 70% z wody to nic nie stoi na przeszkodzie, żeby wyłącznie z wody zbudować człowieka.

Jeśli według Ciebie to błąd logiczny, to wykarz to. Zakładając że strategia może być bez stanowa i obiektowa, to czemu miałoby się nie dać zbudować aplikacji z obiektów które są tylko bezstanowe i obiektowe. Z resztą cały Twój argument jest bez sensu, bo oczywiście że dałoby się to zrobić - po prostu przekazujesz wszystkie dane przez parametry - taką aplikację dałoby się bardzo łatwo zrobić, ale po prostu nie była by napisana w paradygmacie obiektowym.

W moim poście chodziło to, "Czemu miałoby się nie dać zbudować aplikacji z bezstanowych obiektów (tak by nadal była w paradgymacie obiektowym), skoro strategia rzekomo jest obiektowa a jest bezstanowa".

Próbowałem wykazać niemożliwość tego że strategia jest obiektowa, albo chociaż fakt że czymś ta strategia się musi różnić od innych obiektów. Tego żę albo jest jakaś granica pomiędzy "byciem strategią" a "nie byciem strategią", albo po prostu strategia jest nieobiektowa.

0
Riddle napisał(a):

Nie obiektowe będą też bezstanowe serwisy w Javie. i mozliwe że wszystkie obiekty bezstanowe

Te serwisy w Javie tak, na pewno są nieobiektowe.

"Bezstanowe" masz na myśli takie które niczego nie enkapsulują czy takie które nie są mutable?

Mam namyśli takie które nie posiadają danych jak Servisy w Javie, I czyste funkcje, które z powodów implementacyjnych są obiektami. Ale odpowiedzieć na twoje pytanie jest mi trudno no bo czy serwis

class MyService {
  String MY_CONST = "WriteOnly.pl"
  // miejsce na metody
}

przestał byc bezstanowy, bo mam zdefiniowaną jedną stałą? Raczej nie. Więc chodzi mi o wszystkie które nie są mutable

0
KamilAdam napisał(a):

Ale odpowiedzieć na twoje pytanie jest mi trudno no bo czy serwis

class MyService {
  String MY_CONST = "WriteOnly.pl"
  // miejsce na metody
}

przestał byc bezstanowy, bo mam zdefiniowaną jedną stałą? Raczej nie. Więc chodzi mi o wszystkie które nie są mutable

Moim zdaniem nie przestał, bo nadal new MyService() == new MyService(). Nadal posiadanie jednej instancji niczym się nie różni od posiadania wielu. Więc moim zdaniem to też jest nieobiektowe.

0
Riddle napisał(a):

Moim zdaniem nie przestał, bo nadal new MyService() == new MyService(). Nadal posiadanie jednej instancji niczym się nie różni od posiadania wielu. Więc moim zdaniem to też jest nieobiektowe.

Z tym new MyService() == new MyService() to uważaj bo w Javie zwróci to false :D Oczywiście wiem że szczegół implementacyjny :P
Hm, z drugiej strony jak się dla nich zaimplementuje equals to będą się zachowywać tak samo jak new MyRecordWithDifaults().equals(new MyRecordWithDifaults())

0
KamilAdam napisał(a):
Riddle napisał(a):

Moim zdaniem nie przestał, bo nadal new MyService() == new MyService(). Nadal posiadanie jednej instancji niczym się nie różni od posiadania wielu. Więc moim zdaniem to też jest nieobiektowe.

Z tym new MyService() == new MyService() to uważaj bo w Javie zwróci to false :D Oczywiście wiem że szczegół implementacyjny :P
Hm, z drugiej strony jak się dla nich zaimplementuje equals to będą się zachowywać tak samo jak new MyRecordWithDifaults() == new MyRecordWithDifaults()

Chodzi mi po prostu o to, że zadziałałyby tak samo. Nie ważne czy wywołam coś na instancji którą już mam, czy stworzę nową, to one są takie same.

I nie pasuje mi to do paradygmatu obiektowego.

0
Riddle napisał(a):

Chodzi mi po prostu o to, że zadziałałyby tak samo. Nie ważne czy wywołam coś na instancji którą już mam, czy stworzę nową, to one są takie same.

I nie pasuje mi to do paradygmatu obiektowego.

A to ci pasuje do paradygratu obiektowego:

class Pies(imie: String = "burek") {
  def szczekaj = println("wof, wof")
  def szczekajSwojeImie = println(s"wof, wof $imie")
}

new Pies().szczekaj
new Pies().szczekajSwojeImie

new Pies().szczekaj
new Pies().szczekajSwojeImie

new Pies("max").szczekaj
new Pies("max").szczekajSwojeImie

?

Różnica jest tylko w ostatnim szczekajSwojeImie. To by znaczyło że szczekaj jest nieobiektowe, a szczekajSwojeImie jest obiektowe?

1
KamilAdam napisał(a):
Riddle napisał(a):

Chodzi mi po prostu o to, że zadziałałyby tak samo. Nie ważne czy wywołam coś na instancji którą już mam, czy stworzę nową, to one są takie same.

I nie pasuje mi to do paradygmatu obiektowego.

A to ci pasuje do paradygratu obiektowego:

class Pies(imie: String = "burek") {
  def szczekaj = println("wof, wof")
  def szczekajSwojeImie = println(s"wof, wof $imie")
}

new Pies().szczekaj
new Pies().szczekajSwojeImie

new Pies().szczekaj
new Pies().szczekajSwojeImie

new Pies("max").szczekaj
new Pies("max").szczekajSwojeImie

?

Nie lubię implicit argumentów, ale tak.

To mi już pasuje, bo new Pies() to tak na prawdę new Pies("burek").

0
Riddle napisał(a):

Nie lubię implicit argumentów, ale tak.

To mi już pasuje, bo new Pies() to tak na prawdę new Pies("burek").

W Scali to jest Default Parameter Values. Implicit Parameter to by był:

class Pies(implicit val imie: String) {
  def szczekaj = println("wof, wof")
  def szczekajSwojeImie = println(s"wof, wof $imie")
}

implicit val imie = "burek"

new Pies().szczekaj
new Pies().szczekajSwojeImie

new Pies().szczekaj
new Pies().szczekajSwojeImie

new Pies("max").szczekaj
new Pies("max").szczekajSwojeImie

:P

0
KamilAdam napisał(a):

W Scali to jest Default Parameter Values. Implicit Parameter to by był:

Jejku.

Pisząc:

Riddle napisał(a):

Nie lubię implicit argumentów, ale tak.

Miałem na mysli "Nie lubię takich argumentów które można podać, ale jak się ich nie poda to wtedy to jest to samo co jakby się podało jakiś konkretny, ukryty argument".

@KamilAdam: No więc jaki jest Twój input? Strategia jest obiektowa czy nie?

0
Riddle napisał(a):

@KamilAdam: No więc jaki jest Twój input? Strategia jest obiektowa czy nie?

Ale ja już pisałem:

  • nie znam się na obiektowości i nawet nie chcę się znać bo swoją przyszłość widzę bardziej w programowaniu funkcyjnym
  • IMHO jeśli strategia nie jest wzorcem obiektowy to tym lepiej dla strategii. Pozostaje pytanie czym wzorcem jest strategia, bo PF jej odpowiednikiem jest Higher Order Functions (dla strategii z jedną metodą publiczną, dla strategii z większą ilością metod publicznych trzeba bardziej pokombinować)

BTW wydaje się że jakbyś oczekiwał że każdy obiekt w programowaniu obiektowym będzie enkapsulować, ale dlaczego nie wymagasz spełnienia trzech pozostałych punktów? Np że każdy obiekt będzie dziedziczyć. W Javie jest to oczywiście spełnione, bo każdy obiekt dziedziczy po klasie Object, ale np w C++ chyba można stworzyć klase/obiekt tkóry nie dziedziczy po niczym? Czy w takim razie to jest OOP skoro nie ma dziedziczenia?

Albo czy VO to OOP skoro nie enkapsulują, Albo Integer w Javie? Cały stan jest na wierzchu. Albo ArrayList/HashMap? Też cały stan jest na wierzchu?

3

Moim zdaniem uczepiłeś się trochę tej enkapsulacji i uważasz ją za warunek konieczny do uznania czegoś za OOP. Ale niech będzie.
Enkapsulacja to w skrócie tyle, że masz jakąś klasę z jakimś interface'm zewnętrznym, składającym się z iluś tam metod i definicja tego interface'u powinna być wszystkim co jest ci potrzebne do użycia go.
Jeżeli masz Strategię, to obiekt gospodarza dostaje obiekt z zewnątrz ze znanym interfejsem. Możesz tam mieć albo jakieś mega rozbudowane struktury, albo zwykłe return a+b. Nie ma znaczenia, tak długo jak patrząc z punktu widzenia gospodarza nie musisz wiedzieć co tam w środku się znajduje - algorytmy, dane, pola, AI, dzikie węże. Czyli z mojego punktu widzenia spełnia to warunki enkapsulacji. Jeżeli z twojego punktu widzenia, enkapsulacja jest wymagana do uznania czegoś za zgodne z paradygmatem obiektowym, to strategia jest z nim zgodna.

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