SOLID oraz zasady projektowania Flashcards

1
Q

Jakie są zasady SOLID ?

A

S - Single-responsiblity Principle
O - Open-closed Principle
L - Liskov Substitution Principle
I - Interface Segregation Principle
D - Dependency Inversion Principle

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Na czym polega Single Responsibility Principle ?

A

Klasa powinna podlegać zmianie tylko z jednego powodu.

Spróbuj uczynić każdą klasę odpowiedzialną za jedną tylko część funkcjonalności oferowanej przez oprogramowanie i niech ta odpowiedzialność będzie całkowicie hermetyzowana.

Głównym celem tej zasady jest redukcja złożoności. Nie trzeba wynajdywać skomplikowanego projektu dla programu któryskłada się tylko z 200 linii kodu. Wystarczy tuzin ładnie napisanych metod.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Przykład Solid Responsibility Principle

A
  • błędem jest że klasa pracownik może być zmodyfikowana z dwóch powodów:
  • zarządzanie danymi pracownika
  • drukowanie raportu ewidencji
  • w przypadku zmiany raportu ewidnecji musisz zmienic kod klasy Employee
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Open/Closed Principle

A

Klasy powinny być otwarte na rozszerzenie ale zamknięte na modyfikacje
- kluczem jest tworzenie abstrakcji, które są trwałe i rozszerzanie tych abstrakcji implementacjami

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Open/Closed Principle - kiedy klasa jest otwarta ?

A

Klasa jest otwarta kiedy bez wpływu na obecny kod:
* można dodawać pola
* można dodawać metody
* tworzyć podklasy

Gdy jakaś klasa jest już opracowana, przetestowana, opisana izawarta w jakimś frameworku lub w inny sposób w aplikacji, to zmiana jej kodu niesie ryzyko. Zamiast zmieniać kod klasy bezpośrednio, tworzy się podklasę i nadpisuje te elementy pierwotnej klasy, których zachowanie chce się zmienić.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Open/Closed Principle - Przykład

A
  • metoda getShippingCost() w klasie Order wymaga modyfikacji przy dodawaniu nowego sposobu przesyłki - klasa jest zamknięta
  • tworząc interfejs Shipping oraz konkretne klasy obliczające koszt dla poszczególnych typów nie musimy modyfikować obecnego kodu
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Liskov Substitution Principle

A

Rozszerzając klasę, trzeba pamiętać, aby było możliwe przekazywanie obiektów nowej podklasy w miejsce obiektów klasy bazowej bez psucia kodu klienta.

Nadpisując metodę, należy rozszerzać zachowanie klasy bazowej zamiast zamieniać je na coś zupełnie innego.
- relacje IS-A czasami jest za słaba i należy spojrzeć bardziej na zachowanie obiektów w przypadku dziedziczenia

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Przykład - Liskov Substitution Principle

A

W matematyce kwadrat jest prostokątem, jeśli założymy że Square extends Rectangle może dojść do nieprawidłowego działania

public void resizeRectangle(Rectangle rect, double width, double height) {
    rect.setWidth(width);
    rect.setHeight(height);
    System.out.println("Pole powierzchni: " + rect.area());
}
Rectangle square = new Square(5);
resizeRectangle(square, 10, 5); // Oczekujemy, że pole powierzchni będzie wynosić 50, ale faktyczny wynik to 100
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Interface Segregation Principle

A

Klientom nie powinno się narzucać zależności od nieużywanych metod.

Staraj się tworzyć interfejsy na tyle wąsko wyspecjalizowane,żeby klienci nie musieli implementować zachowań których nie potrzebują.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Interface Segregation Principle Przykład

A
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Dependency Inversion Principle

A
  • Wysokopoziomowe klasy nie powinny być zależne od niskopoziomowych
  • Obie grupy powinny być zależne od abstrakcji.
    Abstrakcje nie powinny być zależne od szczegółów.
    Szczegóły z kolei powinny zależeć od abstrakcji.
  • odseparowanie logiki binesowej od szegółów implementacyjnych
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Dependency Inversion Principle - przykład

A
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Zasady dobrego projektowania

A
  1. Hermetyzuj to co się różni - identyfikuj aspekty które ulegają zmianą i rodziel je od tego co stałę
  2. Programuj pod interfejs a nie implementację - opieraj się na abstrakcjach zamiast konkretnych klasach
  3. Preferuj kompozycje ponad dziedziczenie -
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Hermetyzacja na poziomie klasy

A
  • wyekstrachowanie dużej metody do osobnej klasy getTaxRate() -> TaxCalculator
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Hermetyzacja na poziomie metody

A
  • rozdzielenie rozbudowanej metody na kilka mniejszych
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Programowanie pod interfejs -
Jak uniezależnic jedną klasę od drugiej ?

A
  1. Określ czego konkretnie potrzebuje jeden obiekt od drugiego: którą metodę wywołuje?
  2. Opisz te metody w nowym interfejsie lub klasie abstrakcyjnej.
  3. Spraw, by klasa stanowiąca zależność implementowała powyższy interfejs.
  4. Uczyń drugą klasę zależną od tego interfejsu, a nie od konkretnej
    klasy. Może ona nadal współdziałać z obiektami pierwotnej klasy, ale połączenie jest teraz elastyczniejsze.
17
Q

Programowanie pod interfejs - przykład

A
  1. Początkowo, klasa Firma jest ściśle sprzęgnięta z konkretnymi
    klasami pracowników. Jednakże, mimo różnicy w ich implementacjach, możemy uogólnić pewne metody dotyczące pracy, a następnie wyekstrahować wspólny interfejs dla
    wszystkich klas pracowników.
  2. Klasa Firma pozostaje sprzęgnięta z klasami pracowników. To
    niedobrze, bo jeśli wprowadzimy nowe typy firm, współpracujące
    z innymi typami pracowników, będzie trzeba nadpisać
    większość klasy Firma zamiast wykorzystać jej kod ponownie.
  3. Po tej zmianie, klasa Firma stała się niezależna od różnorakich
    klas pracowników. Można teraz rozszerzyć tę klasę i wprowadzić
    nowe typy firm oraz pracowników, ponownie wykorzystując
    część kodu bazowej klasy firmy.
18
Q

Dlaczego kompozycja jest lepsza od dziedziczenia ?

A
  • ** Nadpisując metody trzeba mieć pewność że nowe zachowanie
    jest kompatybilne z tym w klasie bazowej** . Jest to istotne,
    gdyż obiekty podklas mogą zostać przekazane do jakiegokolwiek
    kodu który oczekuje obiektów klasy bazowej i nie chcemy
    tego kodu zepsuć.
  • Dziedziczenie psuje hermetyzację klasy bazowej ponieważ wewnętrzne
    szczegóły klasy-rodzica stają się dostępne dla podklasy
    .
  • Podklasy są ściśle sprzęgnięte z klasami bazowymi . Każda
    zmiana w klasie bazowej może zepsuć funkcjonalność podklas.
  • **Próba ponownego wykorzystania kodu poprzez dziedziczenie
    może doprowadzić do utworzenia równoległych hierarchii
    dziedziczenia. ** Dziedziczenie zazwyczaj odbywa się w jednym
    wymiarze. Gdy zaczyna odbywać się w kilku płaszczyznach,
    trzeba tworzyć mnóstwo kombinacji klas, rozbudowując ich
    hierarchię do absurdalnych rozmiarów.
19
Q

Dlaczego kompozycja jest lepsza od dziedziczenia ? - przykład

A
  • każdy dodatkowy parametr powoduje rozmnożenie
    liczby podklas. Jest też mnóstwo powtarzającego się kodu
    pomiędzy podklasami, ponieważ podklasa nie może dziedziczyć
    po dwóch klasach bazowych jednocześnie
  • Możesz rozwiązać ten problem stosując kompozycję. Obiektysamochody
    zamiast implementować zachowanie samodzielnie,
    mogą je delegować innym obiektom
20
Q

Zalety SRP

A
  • Łatwiejsza w utrzymaniu - jeśli klasa ma więcej niż jedną odpowiedzalność to w przypadku zmian wymaga więcej modyfikacji
  • zmniejszanie zależności - więszka odpowiedzialność == więcej zależności == trudność w testowaniu, mniejsza elastyczność
  • ułatwia wprowadzanie zmian
21
Q

zalety OCP

A
  • więszka reużywalność kodu
  • odporność na modyfikacji
22
Q
A