Skip to content

Commit 8a0ceed

Browse files
committed
Final version
1 parent c17e84a commit 8a0ceed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+4235
-801
lines changed

.github/workflows/labs.yml

Lines changed: 229 additions & 112 deletions
Large diffs are not rendered by default.

0_intro/01_hello/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# 👋 Intro - Prosty Kalkulator
22

3-
**Poziom**: bardzo łatwy
3+
**Poziom**: N/A
44
**Cel**: Weryfikacja środowiska
55

66
## 🎯 Zadanie
File renamed without changes.

1_principles/01_grasp/04_low_coupling/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# 🔗 GRASP Low Coupling - System Gry
22

3-
**Poziom**: łatwy
3+
**Poziom**: Łatwy
44
**Cel**: GRASP Low Coupling
55

66
## 🎯 Zadanie
@@ -44,12 +44,12 @@ class Game:
4444
**Dobrze** (luźne sprzężenie):
4545
```python
4646
class Game:
47-
def __init__(self, score_service): # Pośrednik
47+
def __init__(self, score_service): # 1. wstrzykujemy pośrednika
4848
self.score_service = score_service
4949

5050
def finish_game(self, player, score):
5151
self.score_service.save_score(player, score)
52-
# Game nie zna Database - luźne sprzężenie
52+
# 2. Game nie zna Database - luźne sprzężenie
5353

5454
# ScoreService izoluje Game od Database
5555
```

1_principles/01_grasp/04_low_coupling/starter.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,10 @@ class Game:
5353
# Game → ScoreService → Database (pośrednik)
5454
#
5555
# Korzyść: Zmiana Database nie wpływa na Game
56+
57+
58+
# Przykład użycia - odkomentuj gdy zaimplementujesz:
59+
# if __name__ == "__main__":
60+
# service = ScoreService()
61+
# game = Game(service)
62+
# print(game.finish_game("Alice", 150))

1_principles/01_grasp/04_low_coupling/violation.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def finish_game(self, player: str, score: int) -> str:
6060
# Nie mogę - Game tworzy Database bezpośrednio w finish_game() (ew. patch)
6161
#
6262
# ❌ Chcę zmienić Database na inną implementację?
63-
# Muszę EDYTOWAĆ Game.finish_game()
63+
# Muszę EDYTOWAĆ Game().finish_game()
6464
#
6565
# ❌ Chcę dodać cache między Game a Database?
6666
# Muszę EDYTOWAĆ Game - nie ma miejsca na pośrednika
@@ -90,7 +90,7 @@ def finish_game(self, player: str, score: int) -> str:
9090
- Game odpowiada za komunikację z bazą
9191
- Dwie odpowiedzialności w jednej klasie
9292
93-
5. ❌ Wysokie sprzężenie = niska "współużywalność"
93+
5. ❌ Silne sprzężenie = niska "współużywalność"
9494
- Game nie może działać bez Database
9595
- Nie można użyć Game z innym storage (file, API)
9696
@@ -100,3 +100,9 @@ def finish_game(self, player: str, score: int) -> str:
100100
3. ScoreService izoluje Game od Database
101101
4. Game nie zna szczegółów Database - tylko wywołuje score_service.save_score()
102102
"""
103+
104+
105+
# Przykład użycia
106+
if __name__ == "__main__":
107+
game = Game()
108+
print(game.finish_game("Alice", 150))

1_principles/02_solid/02_ocp/README.md

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,28 @@ class AreaCalculator:
4646

4747
**Dobrze** (rozszerzenie bez modyfikacji):
4848
```python
49-
from abc import ABC
49+
from abc import ABC, abstractmethod
5050

5151
class Shape(ABC):
52-
...
52+
@abstractmethod
53+
def calculate_area(self):
54+
pass
5355

5456
class Circle(Shape):
55-
...
57+
def __init__(self, radius):
58+
self.radius = radius
59+
60+
def calculate_area(self):
61+
return 3.14 * self.radius ** 2
5662

5763
# Nowy kształt = nowa klasa, zero zmian w AreaCalculator ✅
5864
class Rectangle(Shape):
59-
...
65+
def __init__(self, width, height):
66+
self.width = width
67+
self.height = height
68+
69+
def calculate_area(self):
70+
return self.width * self.height
6071
```
6172

6273
**Korzyść**: `AreaCalculator` nie zmienia się przy dodaniu Rectangle.

1_principles/02_solid/02_ocp/starter.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,10 @@ class AreaCalculator:
6666

6767
# OCP: Open for extension, Closed for modification
6868
# Nowy kształt = nowa klasa Shape, zero zmian w AreaCalculator
69+
70+
71+
# Przykład użycia - odkomentuj gdy zaimplementujesz:
72+
# if __name__ == "__main__":
73+
# shapes = [Circle(5), Square(4), Triangle(3, 4)]
74+
# calculator = AreaCalculator()
75+
# print(f"Total area: {calculator.total_area(shapes)}")

1_principles/02_solid/02_ocp/violation.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,4 +98,18 @@ def total_area(self, shapes: list) -> float:
9898
4. ❌ Naruszenie Single Responsibility
9999
- AreaCalculator musi ZNAĆ wszystkie typy kształtów
100100
- Zmiana w Circle może wymagać zmiany w AreaCalculator
101+
102+
Jak to naprawić?
103+
1. Stwórz abstrakcyjną klasę Shape (ABC) z metodą calculate_area()
104+
2. Każdy kształt (Circle, Square, Triangle) dziedziczy po Shape
105+
3. Każdy kształt implementuje własną calculate_area()
106+
4. AreaCalculator używa polimorfizmu - wywołuje shape.calculate_area() bez isinstance()
107+
5. Nowy kształt = nowa klasa dziedzicząca po Shape, zero zmian w AreaCalculator
101108
"""
109+
110+
111+
# Przykład użycia
112+
if __name__ == "__main__":
113+
shapes = [Circle(5), Square(4), Triangle(3, 4)]
114+
calculator = AreaCalculator()
115+
print(f"Total area: {calculator.total_area(shapes)}")

1_principles/02_solid/05_dip/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# 🔌 DIP - Abstrakcja Bazy Danych
22

3-
**Poziom**: łatwy
3+
**Poziom**: łatwy
44
**Cel**: Dependency Inversion Principle
55

66
## 🎯 Zadanie

0 commit comments

Comments
 (0)