Zasady SOLID - niezbędnik programisty

  Рет қаралды 18,645

Fullstack Developer

Fullstack Developer

Күн бұрын

Aktualne kupony zniżkowe na moje kursy:
fullstackdeveloper.tech/kursy
Zapraszam na serwer Discord:
/ discord
00:00 Wstęp
00:38 Solid - wprowadzenie
03:35 Single Responsibility Principle
12:56 Open-Close Principle
25:13 Liskov Substitution Principle
35:30 Interface Segregation Principle
43:19 Dependency Inversion Principle
Fb: / fullstack-developer-10...
#csharp #dotnet #programowanie #kurs #poradnik #solid

Пікірлер: 58
@FullstackDeveloperPL
@FullstackDeveloperPL 2 жыл бұрын
Aktualne kupony zniżkowe na moje kursy: fullstackdeveloper.tech/kursy Zapraszam na serwer Discord: discord.gg/UDHXQxhM4r
@technics6215
@technics6215 Жыл бұрын
Jestem programistą z "nastoletnim" doświadczeniem i muszę przyznać, że to jest pierwszy polski kanał na jaki trafiłem, w którym pokazuje się jak na prawdę wygląda praca programisty. Większość materiałów na te tematy to "prezentacje instrukcji obsługi" na poziomie przedszkolnym, często całkowicie oderwane od rzeczywistości w jakiej funkcjonują prawdziwi programiści. Wyglądają one tak, jakby ktoś przeczytał lub obejrzał jakiś kurs 2 dni temu i już robi własny kurs na podstawie tej wiedzy.
@marcin5984
@marcin5984 2 жыл бұрын
Super nagranie! Podobało mi się zwłaszcza tempo nagrania jak i dobrze dobrane problemy jakie zostały rozwiązane przez zastosowanie wzorców. W tle cytowanie teorii, którą i tak wciąż cofałem, aby sobie utrwalić - mówienie w ten sposób to gwarant, że dobrze wypadnie się na rozmowie rekrutacyjnej ;)
@sebastiansobik7845
@sebastiansobik7845 Жыл бұрын
Super film, wreszcie to rozumiem. Dzięki!
@dadasss69
@dadasss69 2 жыл бұрын
Super robota!
@praktycznewskazowki6733
@praktycznewskazowki6733 2 жыл бұрын
dzięki bardzo dobre przypomnienie :)
@robydj5289
@robydj5289 2 жыл бұрын
Jak zawsze świetny materiał i przejrzyste tłumaczenie!
@FullstackDeveloperPL
@FullstackDeveloperPL 2 жыл бұрын
Dzięki za komentarz 😀
@skandaliczniegrubawiewiork318
@skandaliczniegrubawiewiork318 6 ай бұрын
Super nagranie! Po obejrzeniu filmiku mam dwa pytania. Co do pierwszej zasady: Jak defniujemy odpowiedzialności? Np. Mamy logikę biznesową do rozliczania wpływów i wydatków w budżecie. Czy całość rozliczania mam rozumiec jaka jedyna odpowiedzialnosc? Czy może rozliczanie wpływu i rozliczanie wydatku mamy rozbic? Oraz pytanie do 3 zasady: Jak nie przedobrzyć z rozbijaniem interfejsów?
@blackshadow5800
@blackshadow5800 Жыл бұрын
27:36 klasa Duck ma 2 odpowiedzialności, Duck oraz Swim. Czy to nie jest naruszenie S?
@igbt6
@igbt6 3 жыл бұрын
Dobra robota! I pytanie, w przykładzie z kaczkami przy Liskov Substitution Principle w sumie pokazałeś identyczny anty-przykład gdzie RubberDuck nie jest w stanie zaimplementować metody Fly() jak w przypadku Interface Segregation Principle gdzie mamy to samo z drukarką Canon i jej Scan() metodą. Czy to jest tak że zawsze jakieś naruszenie ISP powduje naruszenie LSP ?
@FullstackDeveloperPL
@FullstackDeveloperPL 3 жыл бұрын
dzięki za komentarz ;p co do pytania, to ogólnie rzecz biorąc to mimo, że zasady SOLID mają w teorii osobne definicję, to w praktyce ich granice, w wielu przypadkach się 'zacierają'. Także jeśli potraktujemy interface po prostu jako abstrakcyjną klasę bazową, to naruszająć ISP naruszy LSP, jak tylko pojawi się konkretna klasa, która nie potrafi zaimplementować jakiejś metody. Ale z drugiej strony nie każde naruszenie LSP musi być spowodowane naruszeniem ISP
@parsifal8232
@parsifal8232 10 ай бұрын
34:50 no nie jesteśmy w stanie służyć sie kwadratem tak aby reprezentował dowolny czworokąt. tak samo jak kaczka górska nie reprezentuje dowolnej kaczki ... tylko górską :) więc o co chodzi nie wiadomo dalej. Chyba żę ... nie możemy modyfikować w sposób sztuczny np properties z klasy bazowej tylko po to żeby interfejs pasował. ???
@tomaszfilipek5834
@tomaszfilipek5834 2 жыл бұрын
Mam pytanie odnośnie przykładu do Open-Close Principle. Po co w ogóle tworzyć klasę InvoicePersistence? Za jej pomocą można wyłącznie zapisać dokument w danym formacie, a czy tego samego nie można zrobić wykorzystując konkretny saver? Co zyskujemy dzięki tej klasie?
@skajlet9045
@skajlet9045 2 жыл бұрын
W przypadku przedstawionym na filmiku klasy 'Saver' odpowiadają za logikę zapisu do odpowiedniego formatu. A klasa 'Persistence' odpowiada jedynie za wywołanie tej logiki, więc zamiast wywoływać każdą klasę 'Saver' osobno zależnie od formatu do jakiego chcesz zapisać to używasz klasy 'Persistence', podajesz odpowiednie argumenty i na podstawie tych danych zostanie wywołana odpowiednia klasa 'Saver', która zapisze plik do odpowiedniego formatu.
@piotrjednorowski3122
@piotrjednorowski3122 2 жыл бұрын
Bardzo dobry materiał, dużo się dowiedziałem z Twoich filmów ale jako że wracam do programowania po latach (bardziej hobbistycznie na razie) mam pytanie do DI. Wszystkie te zasady SOLID w głównej mierze opierają się na Interfejsach. Czy nie lepiej do konstruktorów, metod itd. wstrzykiwać nie metodę zrzutowaną na interfejs a delegata zawierającego taki rzut? Tak, jesteśmy ograniczeni do jednej metody, a w przypadku delegata z metodami rzutowanymi na interfejs moglibyśmy dynamicznie zmieniać ile i jakie metody chcemy w danym momencie użyć. Przepraszam za ewentualne błędy w nazewnictwie ale wdrażam się dopiero w obiektowe programowanie. Pozdrawiam
@FullstackDeveloperPL
@FullstackDeveloperPL 2 жыл бұрын
dla sporej części przypadków efekt byłby dosyć podobny, ale interface nei musi się ograniczać do implementacji jednej metody A poza tym jako że C# to język obiektowy, to raczej preferuje się operowanie na obiektach niżbezpośrednio na funkcjach/metodach
@velmrok1660
@velmrok1660 10 ай бұрын
35:20 nie rozumiem tej zasady. Dlatego kwadrat dziedziczy po czworokącie a nie czworokąt po kwadracie. Bo kwadrat jest czworokątem ale czworokąt nie musi być w kwadratem?
@blackshadow5800
@blackshadow5800 Жыл бұрын
42:22 Jak sobie poradzic w Javie? tam możemy imprelentować tylko 1 interfejs
@hipekk
@hipekk 2 жыл бұрын
A czy klasa HpLaserJet w finalnej postaci (pokazanej w 43:08) nie narusza zasady pojedynczej odpowiedzialności?
@dantom7405
@dantom7405 2 жыл бұрын
Trzeba pamiętać że SOLID to ZALECENIA a nie obowiązek - zapewne będą przypadki gdzie bardziej będzie się opłacało złamać tę zasadę choć nie jestem jeszcze takim kozakiem aby o tym wyrokować, mówię co mi się wydaje ;-)
@pawefalkowski8794
@pawefalkowski8794 2 жыл бұрын
Kurczę, Robert C. Martin miał rację, że zasada SRP jest faktycznie najsłabiej rozumiana. Z książki Czysta architektura: "Spośród wszystkich reguł SOLID to reguła jednej odpowiedzialności (SRP) jest chyba najsłabiej zrozumiała. Prawdopodobnie wynika to z tego, że ma trochę niewłaściwą nazwę. Programiści, słysząc tę nazwę, od razu zakładają, że każdy z modułów (m. in. klas) powinien wykonywać tylko jedno zadanie. Polecam tę książkę. A zgodnie z SRP, ta klasa może mieć kilka funkcjonalności. Pytanie tylko, które grupy aktorów są powodami do zmian tych funkcjonalności - jeżeli jest ich więcej niż 1, to wtedy SRP jest zlamane.
@marakondes
@marakondes Жыл бұрын
Dokładnie , według wyjaśnienia w tym filmiku zasada SRP narzuca jedną odpowiedzialność dla każdej klasy , tak to zrozumiałem i się zastanawiam co ta zasada tak interpretowana ma polepszać. Ilość klas jakie trzeba by utworzyć dla każdej odpowiedzialności nie przyczynia się do czytelności projektu.
@jotes2188
@jotes2188 Жыл бұрын
powiedziałbym prędzej, że ta zasada jest źle nazwana, a nie źle rozumiana ;)
@plrc4593
@plrc4593 2 жыл бұрын
19:21 - bardzo ciekawe, tylko, że w efekcie, żeby zapisać fakturę do np. pdf musimy utworzyć osobny obiekt klasy InvoicePersistence, który będzie zawierał odpowiedni obiekt invoiceSaver. Trochę to kuriozalne :D Naprawdę takie postępowanie jest standardowe? W końcu gdzieś chyba i tak będziesz musiał zaimplementować osobny metody do tego, ew. metodę, która przyjmuje jakiś argument, co nie?
@jakubdudek4133
@jakubdudek4133 2 жыл бұрын
Nie, nie będzie musiał. Zwróć uwagę, że pole 'private IInoivceSaver' w klasie InvoicePersistance reprezentuje abstrakcję, tutaj interface. Dzięki temu klasa ta nie podlega już koniecznym modyfikacjom. Konstruktor klasy InvoicePersistance przyjmuje jako argumenty a) jakąś fakturę, b) jakąś klasę reprezentującą owy interface (czyli w tym prostym przykładzie defacto klasę zajmującą się zapisem faktury do konkretnego pliku/rozszerzenia). W rezultacie tworzysz sobie instancję(obiekt) klasy InvoicePersistance -> new InvoicePersistance(myInvoice, InvoicePDFSaver); InvoicePDFSaver wygląda tak: public class InvoicePDFSaver implements IInvoiceSaver { //implementujemy interface jako Naszą abstrakcję void save(Invoice invoice) { //metoda biznesowa zapisująca fakturę do PDFa } I cyk, to tyle. Domyślnie metoda save() w klasie InvoicePersistance nie ma pojęcia o tym, co robi metoda save() w klasie InvoicePDFSaver. Nie potrzebuje tego wiedzieć, jest niezależna. Dzięki takiemu podejściu możesz tworzyć kolejne wariacje klas, które wykorzystują metodę save() z interface do zapisywania w różnych innych formatach Naszej faktury. Dzięki temu uwalniasz się również od problemu "mój wysokopoziomowy kod jest zależny od niskopoziomowego kodu!" -> ostatnia zasada DIP. Mam nadzieję, że coś tam pomogłem rozjaśnić. :)
@newraze
@newraze 2 жыл бұрын
Czyli wedle SRP posiadanie klasy takiej jak np. TransactionsService gdzie implementujemy metody uzywane przez kontrolery API to nie jest najczystsze wyjscie? Lepiej wtedy utworzyc kilka klas - po jednej dla kazdej metody Get, GetById, Create etc? Czy taki przypadek jest wyjatkiem i tutaj jest cicha zgoda na to, aby trzymac serwisy w jednej klasie? Pozdrawiam
@FullstackDeveloperPL
@FullstackDeveloperPL 2 жыл бұрын
Patrząc pod kątem samego SRP to tak masz rację, ale jak sam wspomniałeś nie zawsze do każdej klasy stosujemy tą zasadę np do klas utility
@bobek8030
@bobek8030 3 жыл бұрын
Jak wygląda wstrzykiwanie przez właściwości i metody, czy mozesz pokazać przykład? Czy w przykładzie z drukarka nie naruszamy zasady single responsibility?
@FullstackDeveloperPL
@FullstackDeveloperPL 3 жыл бұрын
wstrzykiwanie przez właściwości/metody, to po prostu przekazanie do właściwości/metody jakąś referencję, która następnie będzie przypisana do pola prywatnego w klasie, po konkretny przykład (zamiast wklejać kod w komentarz) odsyłam do: www.plukasiewicz.net/Artykuly/DIP_IoC_DI A co do drukarki, to tutaj żeby zdefiniować odpowiedzialność klasy Canon/HpLaserJet trzeba odpowiedzieć na pytanie 'za co jest odpowiedzialna ta klasa' I w tym przypadku odpowiedzią byłoby 'za obsługę drukarki z funkcją skanera...' i mimo, że ta konkretna klasa implementuje/ma kilka publicznych metod, to są one w obrębie jednej odpowiedzialności. Naruszeniem byłoby tu tutaj np stwierdzenie, że klasa jest odpowiedzialna za 'za obsługę drukarki z funkcją skanera i zapisanie informacji o wydruku na dysku' Także mimo tego że jakaś klasa ma kilka publicznych metod, to jeżeli pełnią one jedną funkcjonalność to nie jest to naruszenie SRP, ale z tego co zauważyłem to sporo osób właśnie rozumie SRP jako maksymalnie jedną publiczną metodę, przez co później w kodzie powstaje wiele klas z pojedynczymi metodami (co oczywiście jest lepsze niż posiadanie jednej wielkiej klasy z dziesiątkami metod ;p, ale takie programowanie bardziej przypomina programowanie funkcyjne niż obiektowe)
@bobek8030
@bobek8030 3 жыл бұрын
@@FullstackDeveloperPL Jak zawsze rozwiałeś wszystkie wątpliwość, dziekuje bardzo za odpowiedź! Super robota
@Mar-yo4vu
@Mar-yo4vu 2 жыл бұрын
Hermetyzacja i bezpieczeństwo - Pytanie mam, jak się ma to do bezpieczeństwa że pola prywatne robimy publiczne? jasne zawsze można zrobić get'era, ale wartość pola i tak jest dostępna na zewnątrz. Próbuję to zrozumieć.
@AerialMakudo
@AerialMakudo 2 жыл бұрын
Klasyczny przykład to konto bankowe. Masz saldo jako public. Możesz się wtedy podpiąć dowolnym klientem i ustawić sobie saldo 1 mln euro. I jesteś milionerem:) W przypadku private - nie zrobisz tak. Możesz się wpiąć klientem tylko w metodę setStanKonta a tam już będzie blok ifów który sprawdzi czy jesteś klientem banku, czy masz uprawnienia do rachunku, sprawdzi skąd kasa wpływa, wyliczy prowizję od przelewu itd.
@sebon11
@sebon11 2 жыл бұрын
Odnośnie single responsibility principle - nie jest przypadkiem tak, że przez tą regułę będziemy mieli zawsze klasę z tylko jedną metodą? :D nie licząc setterów i getterów. No bo np możemy mieć klasę samochód i przydałby się metody na ruszenie, hamowanie i inne takie, ale z tego trochę wynika to, że powinniśmy na każdą akcję tworzyć inną klasę :D jak jest?
@sebon11
@sebon11 2 жыл бұрын
Ej, ja ciągle czekam na odpowiedź jakby co, wchodzę tu czasami zobaczyć czy jest, więc jak ktoś wie to proszę o odpowiedź xD
@jakubdudek4133
@jakubdudek4133 2 жыл бұрын
Imo wydaje mi się, że to co wymieniłeś, jak np. ruszanie i hamowanie mogłoby jak najbardziej być w jednej klasie, np. CarProcessor (czy cokolwiek). Głównie dlatego, że metody te odpowiadałyby za jedną funkcjonalność. Za pewną dynamikę pojazdu. Natomiast gdybyś do tej samej klasy dodał metodę, która sprawdza Ci, czy auto przeszło przegląd, czy ma sprawne jakieś czujniki lub metodę porównującą parametry tego auto do parametrów innego auto, to w tym momencie łamiesz zasadę SRP. Jak to zauważysz to podejmujesz decyzję, że pozostałe funkcjonalności (nie związane z "ruchem samochodu") należy przenieść do innych klas, które będą miały swoją konkretną odpowiedzialność.
@sebon11
@sebon11 Жыл бұрын
@@jakubdudek4133 rozumiem, dzięki :)
@pmro
@pmro 9 ай бұрын
Mnie zastanawia inna rzeczy -> w klasie Invoice przy Single Responsibility, mamy metodę CalculateTotal a w filmiku powiedziane jest, że klasa Invoice w takim kształcie ma jedną odpowiedzialność -> przechowywanie danych o Invoice... a dla mnie to tak nie wygląda przez metodę Calculate, gdyż ona przelicza (sumuje) zakupione rzeczy a więc klasa Invoice ma dwie odpowiedzialności: #1 Wyznacza strukturę danych i je przechowuje (czyli taki model) dla Invoice oraz #2 Wylicza wartość Total dla Invoice. Czy nie powinno być tak, że dla Total wartość jest wyliczana ale przez inną klasę, której odpowiedzialnością byłoby wyliczanie wartości potrzebnych dla Invoice? chodzi o to aby implementacja CalculateTotal nie była w Invoice a w innej klasie np. InvoiceCalculation. Wtedy w Invoice tylko "wywołujemy" metodę przeliczającą poprzez klasę InvoiceCalculation. Wyobraźmy sobie sytuację, gdy logika wyliczania wartości Total będzie się od czasu do czasu zmieniać np przez zmiany w prawie związane z podatkiem od grupy usług / towarów. Sama struktura przetrzymywanych danych w Invoice się nie zmieni ALE sposób wyliczania Total już tak co prowadzi mnie do wniosku, że klasa Invoice w przedstawionym kształcie na początku filmiku ma dwie odpowiedzialności. Gdybyśmy mieli drugą klasę czyli InvoiceCalculation, której odpowiedzialnością byłoby wyliczanie rzeczy dla Invoice mielibyśmy jeden powód do zmiany Invoice (czyli zmiana struktury danych, np. więcej pól) oraz jeden powód do zmiany InvoiceCalculation (czyli zmiana sposobu wyliczania wartości dla Invoice).
@michagauza93
@michagauza93 2 жыл бұрын
Czy dodając do kasy shape funkcji draw nie łamiemy w ten sposób pierwszej zasady SOLID?
@FullstackDeveloperPL
@FullstackDeveloperPL 2 жыл бұрын
mógłbyś wskazać o który moment w materiale Ci chodzi? ;p nie moge znależć metody Draw (patrze po repo)
@michagauza93
@michagauza93 2 жыл бұрын
@@FullstackDeveloperPL 23:40 :D sorrki na początku to było draw i zmieniłeś na render już w Shape. :D
@michagauza93
@michagauza93 2 жыл бұрын
Chodzi mi o to, że z invoice wyrzuciliśmy metody które robiły coś z obiektem (zapisywanie do pdf itp) a w shape dodaliśmy taką metodę (render). Nie daje mi to spokoju :D.
@FullstackDeveloperPL
@FullstackDeveloperPL 2 жыл бұрын
@@michagauza93 jeżeli metody i właściwości klasy są ze sobą powiązne i wspólnie dostarczają jedną funkcjonalność (odpowiedzialność), to nie jest to złamanie SRP, złamanie tej zasady jest w tedy kiedy w jednej klasie mamy rzeczy nie powiązane ze sobą robiące dwie różne funkcjonalności
@FullstackDeveloperPL
@FullstackDeveloperPL 2 жыл бұрын
@@michagauza93 także czasem teżsię może zdażyć że obiekt ma więcej niż jedną metode publiczną, a to nie będzie oznaczać że ma wiele odpowiedzialności ;p
@technics6215
@technics6215 Жыл бұрын
Suma faktury jako float? A nie powinno być decimal?
@FullstackDeveloperPL
@FullstackDeveloperPL Жыл бұрын
Mógłby też być decimal 😀
@technics6215
@technics6215 Жыл бұрын
@@FullstackDeveloperPL Radzę poczytać na temat "never use floats for money".
@FullstackDeveloperPL
@FullstackDeveloperPL Жыл бұрын
@@technics6215 w C# raczej nie ma takich problemów, masz może konkretny przykład który by się nie sprawdził?, sprawdziłbym z ciekawości ;p
@technics6215
@technics6215 Жыл бұрын
@@FullstackDeveloperPL ChatGPT wypluł mi taki przykład: using System; namespace MonetaryValuesExample { class Program { static void Main(string[] args) { float floatAmount = 100.0f; float floatTaxRate = 0.23f; float floatTotal = floatAmount * (1 + floatTaxRate); decimal decimalAmount = 100.0m; decimal decimalTaxRate = 0.23m; decimal decimalTotal = decimalAmount * (1 + decimalTaxRate); Console.WriteLine("Float calculation: {0}", floatTotal); Console.WriteLine("Decimal calculation: {0}", decimalTotal); Console.WriteLine("Difference: {0}", decimalTotal - floatTotal); } } } W jakiejś porządnej aplikacji do bankowości czy księgowości taki kod nie przeszedł by testów jednostkowych. Oczywiście ludzie posiłkują się zaokrągleniami, żeby rozjazdy się z czasem nie zakumulowały do znacznej wartości, ale nie tak powinno się to robić (wydajność).
@FullstackDeveloperPL
@FullstackDeveloperPL Жыл бұрын
@@technics6215 dzięki za przykład, z ciekawości odpaliłem go w programie konsolowym i wyszly w porządku wyniki: Float calculation: 123 Decimal calculation: 123.000 Difference: 0 ogólnie wiem że ten problem istnieje, ale nie spotkałem się jeszcze z teog typu błędami w c# (może w nowysz wersjach to poprawili)
OOP i Wzorce projektowe - niezbędnik programisty
1:46:10
Fullstack Developer
Рет қаралды 22 М.
SOLID Principles: Do You Really Understand Them?
7:04
Alex Hyett
Рет қаралды 147 М.
Clowns abuse children#Short #Officer Rabbit #angel
00:51
兔子警官
Рет қаралды 77 МЛН
Каха заблудился в горах
00:57
К-Media
Рет қаралды 3,4 МЛН
Mom's Unique Approach to Teaching Kids Hygiene #shorts
00:16
Fabiosa Stories
Рет қаралды 31 МЛН
Czym jest SOLID? - Standardowe Pytania Rekrutacyjne
15:31
Kajetan Duszyński - Szkoła Dotneta
Рет қаралды 20 М.
Jak skutecznie szukać pracy w 2024 roku? II Paul Pachowicz x Adam Maciejek
50:38
C# Od podstaw - Klient HTTP
27:26
Fullstack Developer
Рет қаралды 5 М.
80 Year Olds Share Advice for Younger Self
12:22
Sprouht
Рет қаралды 1,5 МЛН
Dlaczego nie znajdziesz pracy w IT
7:04
Fullstack Developer
Рет қаралды 15 М.
What is Liskov Substitution Principle ?
7:38
Interview Happy
Рет қаралды 40 М.
Refleksja i atrybuty w C# (.NET)
36:26
Fullstack Developer
Рет қаралды 6 М.
Uncle Bob’s SOLID Principles Made Easy 🍀 - In Python!
19:09
ArjanCodes
Рет қаралды 289 М.
SOLID - co się za nim kryje?
11:33
DevEnv
Рет қаралды 11 М.
Clowns abuse children#Short #Officer Rabbit #angel
00:51
兔子警官
Рет қаралды 77 МЛН