Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

LISKOV and SOLID

26 views
Skip to first unread message

Przemek Biernat

unread,
Jan 20, 2024, 12:35:34 PMJan 20
to
Cześć grupa,

Czy nie uważacie że obecnie stosowanie LISKOV i SOLID to już przeszłość. Czekam na opinie

Przemek

heby

unread,
Jan 20, 2024, 2:58:53 PMJan 20
to
On 20/01/2024 18:35, Przemek Biernat wrote:
> Czy nie uważacie że obecnie stosowanie LISKOV i SOLID to już przeszłość. Czekam na opinie

Opinie do przypadkowego stwierdzenia? Nie.

Uzasadnij co uważasz za błedne w tych podejściach, powiedz jakie masz
obserwacje pokazujące spadajacą użyteczność, przedstaw jakie rozwiązania
zastępują ich miejsce.

Wtedy będzie można mieć jakies opinie.

Przemek Biernat

unread,
Jan 21, 2024, 11:19:03 AMJan 21
to
1. Pojedyncza odpowiedzialność. Według mnie klasy wymyślono po to aby grupować i zamykać funkcjonalność. Czy chodzi o to aby klasy miały po jednej metodzie?
2. Otwarte zamknięte. Przykład: wzorzec fabryka, jak ci dochodzi kolejna klasa to i tak musisz zmienić kod fabryki i dodać generowanie klasy.
3. Liskov. To już jest czysty idealizm. Często nie udaje się aby wszystkie klasy potomne implementowały funkcje wszystkie funkcje klasy bazowej. Wyjściem są wiszące metody lub rzutowanie, osobiście preferuje static_cast z kontrolą typu.
4. Interfejsy podobnie jak wyżej patrz 1 i 3
5. Zależność od interfejsów a nie od konkretnych typów - to wydaje się być sensowne

A co powiecie gdyby iteratory były przekażywane przez wskaźnik i taki iterator był zwracany na zewnątrz klasy w celu wykonania algorytmu poza klasą ale na kontenerze klasy.

Zapraszam do dyskusji.

Przemek

heby

unread,
Jan 21, 2024, 12:58:57 PMJan 21
to
On 21/01/2024 17:19, Przemek Biernat wrote:
> 1. Pojedyncza odpowiedzialność. Według mnie klasy wymyślono po to aby grupować i zamykać funkcjonalność. Czy chodzi o to aby klasy miały po jednej metodzie?

Klasa o jednej metodzie jest praktycznie bezużyteczna.

Wiec na pewno nikt nie wpadłby na tak głupi pomysł.

Są rózne koncpecje co to jest klasa, od podobnych do Java bean po good
object. Wszystkei znajdziesz w żywym kodzie i znajdziesz też wielu
zwolenników pisania na oba sposoby. Obserwacja: i tak będziesz pisał
tak, jak kod zastany.

> 2. Otwarte zamknięte. Przykład: wzorzec fabryka, jak ci dochodzi kolejna klasa to i tak musisz zmienić kod fabryki i dodać generowanie klasy.

Nikoniecznie, może istnieć inna fabryka produkująca inne typy, o typie
bazowym takim samym jak ta pierwsza. Innymi słowy *niektóre* fabryki nic
nie muszą wiedzieć o nowych implementacjach zwarcanej przez nie abstrakcji.

Ba, zaryzykuję stwierdzenie, że w prawidłowo skonstruowanej abstrakcji,
taki rodzaj multi-fabryk jest często spotykanym wzorcem. Implementacja
produkuje klasy o okreslonym interfejsie z puli tych, które zna jako
swoją implementację. Nie musi nic wiedzieć o innej implementacji tego
samego interfejsu.

> 3. Liskov. To już jest czysty idealizm. Często nie udaje się aby wszystkie klasy potomne implementowały funkcje wszystkie funkcje klasy bazowej. Wyjściem są wiszące metody lub rzutowanie, osobiście preferuje static_cast z kontrolą typu.

Jesli potomne klasy mają "wiszące" metody to coś spieprzyłeś. Bardzo
łatwo jest to spieprzyć czytając wszelkie poradniki z okolic "class Ryba
: publi Zwierze". To zazwyczaj stek bzdur pisany przez ignorantów. Pełno
tego w ksiażkach, autorzy najwyraźniej nigdy nie wyszli poza ten poziom
komplikacji.

Zainteresuj się rozwiązaniem tego problem, na przykład za pomocą
doprecyzowania interfejsu wizytacją, czy jakąkolwiek inną metodą tego typu.

> A co powiecie gdyby iteratory były przekażywane przez wskaźnik i taki iterator był zwracany na zewnątrz klasy w celu wykonania algorytmu poza klasą ale na kontenerze klasy.

Powiedziałbym, że to normalna praktyka od początku istnienia koncepcji
iteratorów. Przykładowo, całkiem naturalne jest zwracanie iteratora
java-like własnie przez [smart]pointer. Nie ma w tym nic dziwnego. Robię
tak od dziesięcioleci.

Iteratory STL maja inną koncepcję działania, są kopiowalne.

Używasz obu konstrukcji, głównie dlatego, że Java-like łatwiej jest
zrobić abstrakcyjny, a stl lepiej się optymalizuje.

heby

unread,
Jan 21, 2024, 4:26:49 PMJan 21
to
On 21/01/2024 18:58, heby wrote:
> good
> object.

god.

Przemek Biernat

unread,
Jan 22, 2024, 10:53:56 AMJan 22
to
> > 1. Pojedyncza odpowiedzialność. Według mnie klasy wymyślono po to aby grupować i zamykać funkcjonalność. Czy chodzi o to aby klasy miały po jednej metodzie?
> Klasa o jednej metodzie jest praktycznie bezużyteczna.
>
> Wiec na pewno nikt nie wpadłby na tak głupi pomysł.

Właśnie ostatnio czytałem tutorial o SOLID i tam ktoś wpadł na taki pomysł. Stąd moje pytanie.

>
> Są rózne koncpecje co to jest klasa, od podobnych do Java bean po good
> object. Wszystkei znajdziesz w żywym kodzie i znajdziesz też wielu
> zwolenników pisania na oba sposoby. Obserwacja: i tak będziesz pisał
> tak, jak kod zastany.

Zwykle robię interfejs/klasę bazową poniżej template i później klasy potomne te moje ulubione pyłki. Do tego fabrykę. To jest moja podstawa. Później jakieś klasy wykonujące algorytmy czy jak tam, w zależności od potrzeby.

> > 2. Otwarte zamknięte. Przykład: wzorzec fabryka, jak ci dochodzi kolejna klasa to i tak musisz zmienić kod fabryki i dodać generowanie klasy.
> Nikoniecznie, może istnieć inna fabryka produkująca inne typy, o typie
> bazowym takim samym jak ta pierwsza. Innymi słowy *niektóre* fabryki nic
> nie muszą wiedzieć o nowych implementacjach zwarcanej przez nie abstrakcji.

Tak jak wyżej typowany polimorfizm statyczny, typowany bo dla każdego pyłku mam wartość enum przekazywaną w konstruktorze. W fabryce tablica wskaźników na funkcję create<>.

> Ba, zaryzykuję stwierdzenie, że w prawidłowo skonstruowanej abstrakcji,
> taki rodzaj multi-fabryk jest często spotykanym wzorcem. Implementacja
> produkuje klasy o okreslonym interfejsie z puli tych, które zna jako
> swoją implementację. Nie musi nic wiedzieć o innej implementacji tego
> samego interfejsu.

No wiem można zrobić abstrakcyjną fabrykę i generować z puli dla fabryki konkretnej to mi trochę przypomina most

> > 3. Liskov. To już jest czysty idealizm. Często nie udaje się aby wszystkie klasy potomne implementowały funkcje wszystkie funkcje klasy bazowej. Wyjściem są wiszące metody lub rzutowanie, osobiście preferuje static_cast z kontrolą typu.
> Jesli potomne klasy mają "wiszące" metody to coś spieprzyłeś. Bardzo
> łatwo jest to spieprzyć czytając wszelkie poradniki z okolic "class Ryba
> : publi Zwierze". To zazwyczaj stek bzdur pisany przez ignorantów. Pełno
> tego w ksiażkach, autorzy najwyraźniej nigdy nie wyszli poza ten poziom
> komplikacji.

Podobnie jak wyżej statyczny polimorfizm

>
> Zainteresuj się rozwiązaniem tego problem, na przykład za pomocą
> doprecyzowania interfejsu wizytacją, czy jakąkolwiek inną metodą tego typu.

wizytacji nie czaje i chyba nigdy nie zrozumiem - słabo opisana lub nie zrozumiale dla mnie w pozycji bandy czterech

> > A co powiecie gdyby iteratory były przekażywane przez wskaźnik i taki iterator był zwracany na zewnątrz klasy w celu wykonania algorytmu poza klasą ale na kontenerze klasy.
> Powiedziałbym, że to normalna praktyka od początku istnienia koncepcji
> iteratorów. Przykładowo, całkiem naturalne jest zwracanie iteratora
> java-like własnie przez [smart]pointer. Nie ma w tym nic dziwnego. Robię
> tak od dziesięcioleci.
>
> Iteratory STL maja inną koncepcję działania, są kopiowalne.
>

To dobrze wiedzieć że nie jestem sam pod względem zwracania iteratorów. Tak w STL jest to trochę słabe ale pewnie da się.

> Używasz obu konstrukcji, głównie dlatego, że Java-like łatwiej jest
> zrobić abstrakcyjny, a stl lepiej się optymalizuje.

Programowałem we własnej bibliotece standardowej i tam był poprostu wskaźnik na iterator, który to trzeba było na zewnątrz usunąć
0 new messages