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

Strategia w programowaniu obiektowym

0
Riddle napisał(a):

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.

No przecież napisałem.
Przejdźmy najpierw na przypadek analogiczny.

A - zbiór liczb {1;2;3;4;5;6}
B - zbiór liczb {5;6}
C - zbiór liczb ze zbioru A taki, że suma daje 4

I teraz to, że:

  1. C składa się z kilku elementów zbioru A
  2. B jest podzbiorem A
    Nie oznacza, że istnieje takie C, które składać się będzie tylko z elementów występujących w B

Tak samo jest w przypadku strategii i aplikacji.

  1. Jeśli A to zbiór wszystkich klas spełniających "modelowy" paradygmat obiektowy.
  2. B to zbiór wszystkich klas spełniających implementujących wzorzec strategii
  3. Zakładamy, że strategia wpisuje się w model obiektowy, więc B jest podzbiorem A
  4. C to aplikacja złożona z elementów ze zbioru A
    To nie oznacza jeszcze, że każdą aplikację złożoną z klas spełniających paradygmat obiektowy można napisać wyłącznie za pomocą strategii.
0
wartek01 napisał(a):
Riddle napisał(a):

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.

No przecież napisałem.
Przejdźmy najpierw na przypadek analogiczny.

A - zbiór liczb {1;2;3;4;5;6}
B - zbiór liczb {5;6}
C - zbiór liczb ze zbioru A taki, że suma daje 4

I teraz to, że:

  1. C składa się z kilku elementów zbioru A
  2. B jest podzbiorem A
    Nie oznacza, że istnieje takie C, które składać się będzie tylko z elementów występujących w B

Tak samo jest w przypadku strategii i aplikacji.

  1. Jeśli A to zbiór wszystkich klas spełniających "modelowy" paradygmat obiektowy.
  2. B to zbiór wszystkich klas spełniających implementujących wzorzec strategii
  3. Zakładamy, że strategia wpisuje się w model obiektowy, więc B jest podzbiorem A
  4. C to aplikacja złożona z elementów ze zbioru A
    To nie oznacza jeszcze, że każdą aplikację złożoną z klas spełniających paradygmat obiektowy można napisać wyłącznie za pomocą strategii.

Wykazałeś że nie koniecznie musi się dać, ale nie wykazałeś że sie nie da.

Thanks for playing.

2

@Riddle: dla mnie się strategia nie kłóci z OOP. Istotą częścią tego wzorca jest zmiana (zachowania) w runtime i niby w jaki sposób miałoby to naruszać OOP? W językach nieobiektowych rónież można podmieniać zachowanie w runtime (np. wskaźnik do funkcji w C). Koncept więc jest szerszy niż OOP.

Wygląda, że zapiąłeś się na jakiś konkretny przypadek, gdzie masz implementację algorytmu, która to implementacja:

  • nie jest stanowa,
  • nie jest parametryzowana via konstruktor
  • wypadałoby, żeby była jakoś parametryzowana (bo inaczej jaki byłby sens algorytmu, który ma zawsze ten sam input nie ma inputu?), pewnie przez argumenty podawane do metody

Czyli z poziomu wzorca, przechodzisz na poziom implementacji, która jest bezstanowa, i z faktu wybrania takiej implementacji wyciągasz wnioski, że strategia nie jest OOP?

Kolejna sprawa, tożsamość - różne instancje mają różną tożsamość, przez fakt, że tworzysz je w różnym czasie (przez to mają już różny cykl życia) i są rozróżnialne w aplikacji (przez fakt używania referencji) Możesz jednak uznać, że dla Ciebie nie są rozróżnialne, mimo, że są fizycznie różne.

p.s.

Stoi coś na przeszkodzie, żeby Builder tworzył strategię w oparciu o user input (tworzył, nie wybierał jedną z dostępnych i hardkodowanych w systemie)? Wówczas taka implementacja strategii, kłóci się z OOP czy nie?

0
yarel napisał(a):

@Riddle: dla mnie się strategia nie kłóci z OOP. Istotą częścią tego wzorca jest zmiana (zachowania) w runtime i niby w jaki sposób miałoby to naruszać OOP? W językach nieobiektowych rónież można podmieniać zachowanie w runtime (np. wskaźnik do funkcji w C). Koncept więc jest szerszy niż OOP.

Jezus maria, no przecież cały wątek jest o tym.

Dlatego narusza OOP, bo nie enkapsuluje żadnego stanu w sobie (nie dostaje nic przez parametry konstruktora), w efekcie nie różni się od lamdy/callbacka.

Wygląda, że zapiąłeś się na jakiś konkretny przypadek, gdzie masz implementację algorytmu, która to implementacja:

  • nie jest stanowa,
  • nie jest parametryzowana via konstruktor
  • wypadałoby, żeby była jakoś parametryzowana (bo inaczej jaki byłby sens algorytmu, który ma zawsze ten sam input nie ma inputu?), pewnie przez argumenty podawane do metody

Czyli z poziomu wzorca, przechodzisz na poziom implementacji, która jest bezstanowa, i z faktu wybrania takiej implementacji wyciągasz wnioski, że strategia nie jest OOP?

Pretty much. Przynajmniej taka bezstanowa.

Kolejna sprawa, tożsamość - różne instancje mają różną tożsamość, przez fakt, że tworzysz je w różnym czasie (przez to mają już różny cykl życia) i są rozróżnialne w aplikacji (przez fakt używania referencji) Możesz jednak uznać, że dla Ciebie nie są rozróżnialne, mimo, że są fizycznie różne.

Może i są różne, ale idea jest taka że nie ważne czy użyję za każdy razem nowego new Strategy(), czy czy go zapiszę w globalnym miejscu i re-użyję. Nie ma znaczenia. Wszystko jedno. To dla mnie oznacza że te obiekty są tożsame, skoro mogę używać jednego lub drugiego bez róznicy (tak, wiem że w niektórych językach == da false, ale co z tego. Wszystkie funkcje jakie na niej wywołasz dadzą ten sam rezultat).

Stoi coś na przeszkodzie, żeby Builder tworzył strategię w oparciu o user input (tworzył, nie wybierał jedną z dostępnych i hardkodowanych w systemie)? Wówczas taka implementacja strategii, kłóci się z OOP czy nie?

Jeśli nie przyjmuje niczego w parametrach konstruktora, to moim zdaniem chyba tak.

Chyba że masz jakiś argument, za tym czemu miałaby się nie kłócić.

1
Riddle napisał(a):

Piszę program funkcyjnie, wiec dodam sobie funkcje/callbacki i rozwiązałem problem.
Teraz piszę program w paradygmacie obiektowym, i zastanawiam się jak ugryść strategię.

Wziąć i zaimplementować. Jeżeli priorytetem jest utrzymanie programu w zgodności z paradygmantem obiektowym, to nie wiem co uważasz za ten paradygmat.

  1. Jestem zdania, że w obiektowym świecie (paradygmacie obiektowym), należy tworzyć obiekty które dostają jakiś parametr (np przez konstruktor) - nazywaj to jak chcesz, ja to nazwałem enkapsulacją, ale jeśli Ty masz inne określenie na enkapsulacje, to nie chce użyć tego słowa. Chodzi dokłądnie o to co napisałem: "ze instancje dostają coś przez parametr". To moim zdaniem jest potrzebne, żeby móc nazwać program napisany w paradygmacie obiektowym (nie ważne w jakim języku piszesz).

No i w końcu jasno napisałeś coś z czym mogę się jasno nie zgodzić. Dostawanie (mniejsza o sposób) jakiegoś parametru przez obiekt w czasie jego tworzenia (a również po utworzeniu), nie jest warunkiem niezbędnym, żeby coś nazwać OOP, lub nie OOP.

Nie mam ochoty gadać o tym czym według Ciebie jest enkapsulacja, albo czym według Ciebie jest programowanie obiektowe, nie mam ochoty na dywagacje o nazewnictwo. Chodzi tylko o to, czy strategia wpisuje się w paradygmat obiektowy czy nie. A jeśli tak, to czy to oznacza że funkcje globalne też wpisują się w ten paradgymat.

Ale cały ten wątek i twój problem to spór o nazewnictwo. Zastanawiasz się właśnie, czy jeżeli użyjesz funkcji globalnej, to wciąż będzie można nazwać twój program obiektowym. W poście gdzieś wyżej ubolewasz, że w części języków ~obiektowych klasy i struktury mają taką samą nazwę.

Według mojej wiedzy, nie ma aktualnie żadnego popularnego języka, który jest w 100% obiektowy. Co dla przykładu robią w Javie metody statyczne, pola statyczne, typy prymitywne itd? Czy funkcje z kotlina można wcisnąć w nazwę "object oriented programing"? Jeden rabin powie tak, drugi powie, że nie. Jeżeli sobie popatrzysz na taką funkcję okiem ortodoksa, to absolutnie nie. Ale liberał powie ci, ze taka funkcja to trochę jak implementacja interface'u funkcyjnego, tylko dzięki code sugars z kotlina nie trzeba nigdzie pisać "interface" i nazwy metody, to to się rozumie samo przez siebie. Albo czy tak modne "immutable objects" to obiekty? Bo przecież ideą u podstaw OOP było połączenie danych i logiki, która na nich operuje (w tym zmienia) w jeden byt, np.:

public class Counter{
private int clicks = 0;
public void click(){
  clicks++;
}
public int getClicks() return clicks;
}

No i jeżeli nie można, to jak to jest, że język niby czysto obiektowy, a można pisać nieobiektowo. O pakiecie Math, gdzie ani obiektów, ani metod, a właściwie same funkcje statyczne zapakowane bo trzeba w jedną klasę i typy prymitywne nawet nie warto wspominać.

A w temacie - strategia to dla mnie wzorzec w pełni obiektowy, ponieważ w moim rozumieniu wypełnia całkowicie założenia paradygmatu OOP. Pisze o klasycznych, wzorcowych metodach implementacji.

0
piotrpo napisał(a):

No i w końcu jasno napisałeś coś z czym mogę się jasno nie zgodzić. Dostawanie (mniejsza o sposób) jakiegoś parametru przez obiekt w czasie jego tworzenia (a również po utworzeniu), nie jest warunkiem niezbędnym, żeby coś nazwać OOP, lub nie OOP.

Okej, ale wtedy taki pojedynczy obiekt nie różni się specjalnie od funkcji prawda? Czemu miałbym nie przekazać po prostu callbacka/lamdy zamiast takiego obiektu?

Nie mam ochoty gadać o tym czym według Ciebie jest enkapsulacja, albo czym według Ciebie jest programowanie obiektowe, nie mam ochoty na dywagacje o nazewnictwo. Chodzi tylko o to, czy strategia wpisuje się w paradygmat obiektowy czy nie. A jeśli tak, to czy to oznacza że funkcje globalne też wpisują się w ten paradgymat.

Ale cały ten wątek i twój problem to spór o nazewnictwo. Zastanawiasz się właśnie, czy jeżeli użyjesz funkcji globalnej, to wciąż będzie można nazwać twój program obiektowym. W poście gdzieś wyżej ubolewasz, że w części języków ~obiektowych klasy i struktury mają taką samą nazwę.

Nie mówię o tym czy będzie można go nazwać obiektowym, tylko czy będzie obiektowy.

Według mojej wiedzy, nie ma aktualnie żadnego popularnego języka, który jest w 100% obiektowy. Co dla przykładu robią w Javie metody statyczne, pola statyczne, typy prymitywne itd? Czy funkcje z kotlina można wcisnąć w nazwę "object oriented programing"?

Moim zdaniem nie.

Jeden rabin powie tak, drugi powie, że nie.

Rabin który powie tak, moim zdaniem nie wie co to jest OOP.

Jeżeli sobie popatrzysz na taką funkcję okiem ortodoksa, to absolutnie nie. Ale liberał powie ci, ze taka funkcja to trochę jak implementacja interface'u funkcyjnego, tylko dzięki code sugars z kotlina nie trzeba nigdzie pisać "interface" i nazwy metody, to to się rozumie samo przez siebie.

Tak, ale to nie znaczy że jest obiektowe.

No i jeżeli nie można, to jak to jest, że język niby czysto obiektowy, a można pisać nieobiektowo. O pakiecie Math, gdzie ani obiektów, ani metod, a właściwie same funkcje statyczne zapakowane bo trzeba w jedną klasę i typy prymitywne nawet nie warto wspominać.

No i Math na pewno nie jest obiektowe.

A w temacie - strategia to dla mnie wzorzec w pełni obiektowy, ponieważ w moim rozumieniu wypełnia całkowicie założenia paradygmatu OOP. Pisze o klasycznych, wzorcowych metodach implementacji.

Argument jakiś za tym? Mówiłeś już 10 razy że spełnia, ale nie podajesz żadnego argumentu za tym. Daj mi powód.

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

Piszę program funkcyjnie, wiec dodam sobie funkcje/callbacki i rozwiązałem problem.
Teraz piszę program w paradygmacie obiektowym, i zastanawiam się jak ugryść strategię.

Wziąć i zaimplementować. Jeżeli priorytetem jest utrzymanie programu w zgodności z paradygmantem obiektowym, to nie wiem co uważasz za ten paradygmat.

No dobra, wziąłem i zaimplementowałem.

Czy to jest obiektowe czy nie?

Nie jest żadnym priorytetem, po prostu zastanawiam się (Piszę to pytanie chyba 100 raz dzisiaj) czy ten napisany kod jest w paradygmacie obiektowym czy nie.

0

Bardzo irytujące są odpowiedzi ludzi tutaj.

Wyobraźmy sobie, że zadałem pytanie "Czy funkcja sum() jest napisana w paradygmacie funkcynmym?". (np taka function sum(a,b) { return a+b; } myślę że wszyscy ludzie zgodziliby się że tak, jednoznacznie taka funkcja jest napisana w paradygmacie funkcjnym.

Ale na pytanie zadane w sposób "Czy strategia sortowania jest napisana w paradygmacie obiektowym?" dostaję odpowiedzi które wjeżdżają na nazewnictwo, zarzucają rozmowy o to czym i czym enkapsulacja nie jest, i odciągają pytania na poboczne tory.


Czemu pytania o pasowanie do paradygmatu funkcyjnego mają taką prostą odpowiedź na tym forum, ale zwykłe pytanie "Czy strategia wpisuje się w paradygmat obiektowy" robi taki szum i zamieszanie?

0
Riddle napisał(a):

Czemu pytania o pasowanie do paradygmatu funkcyjnego mają taką prostą odpowiedź na tym forum, ale zwykłe pytanie "Czy strategia wpisuje się w paradygmat obiektowy" robi taki szum i zamieszanie?

Bo paradygmat obiektowy jest zdefiniowany o wiele bardziej mgliście niż paradygmat funkcyjny. Niby OOP ma o wiele lepszą definicję niż FP, ale o wiele trudniej ją zastosować

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

No i w końcu jasno napisałeś coś z czym mogę się jasno nie zgodzić. Dostawanie (mniejsza o sposób) jakiegoś parametru przez obiekt w czasie jego tworzenia (a również po utworzeniu), nie jest warunkiem niezbędnym, żeby coś nazwać OOP, lub nie OOP.

Okej, ale wtedy taki pojedynczy obiekt nie różni się specjalnie od funkcji prawda? Czemu miałbym nie przekazać po prostu callbacka/lamdy zamiast takiego obiektu?

No nie różni się. Przecież ta lamda/callback, to wyłącznie inny sposób zapisu nowej klasy implementującej jakiś interface funkcyjny. Możesz dokładnie tą samą logikę zapisać jako lambdę, klasę anonimową, albo utworzyć sobie klasę, której instancje będą przyjmowane w miejsce tej lambdy soLid jak w mordę strzelił. Czy jak coś jest zgodne z SOLID, to jest też zgodne z OOP?

Według mojej wiedzy, nie ma aktualnie żadnego popularnego języka, który jest w 100% obiektowy. Co dla przykładu robią w Javie metody statyczne, pola statyczne, typy prymitywne itd? Czy funkcje z kotlina można wcisnąć w nazwę "object oriented programing"?

Moim zdaniem nie.

OK, twoim zdaniem, bo to kwestia opinii, a nie faktów. Ja nie wiem - nie natknąłem się jeszcze na przypadek, kiedy musiałbym wyrobić sobie zdanie

No i Math na pewno nie jest obiektowe.

O, i w końcu się w czymś zgadzamy :)

A w temacie - strategia to dla mnie wzorzec w pełni obiektowy, ponieważ w moim rozumieniu wypełnia całkowicie założenia paradygmatu OOP. Pisze o klasycznych, wzorcowych metodach implementacji.

Argument jakiś za tym? Mówiłeś już 10 razy że spełnia, ale nie podajesz żadnego argumentu za tym. Daj mi powód.

Klasa gospodarza jest (albo powinna być) zgodna z OOP, bo nic nie stoi na przeszkodzie, żeby wewnątrz łączyła dane, logikę, która te dane zmienia. Może też korzystać z innych obiektów, takich jak ta wstrzykiwana strategia. Strategia też może i powinna realizować postulaty SOLID, jest obiektem (w językach "czysto" obiektowych), enkapsuluje w sobie wiedzę jak coś zrobić.

Pytanie, które nie daje mi spokoju - rozumiem dyskusje o rzeczach pozbawionych znaczenia, ale właściwie o co chodzi? Wstąpiłeś do jakiegoś kościoła, w którym można jeść mięso w piątek, ale za pisanie nie-OOP idzie się do piekła?

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