Skip to content

Commit ed1e94f

Browse files
committed
facade
1 parent 605963c commit ed1e94f

File tree

4 files changed

+185
-174
lines changed

4 files changed

+185
-174
lines changed

3_structural/05_facade/README.md

Lines changed: 52 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,79 @@
11
# 🏠 Facade - SmartHome System
22

3-
**Difficulty**: easy
4-
**Time**: 10 minutes
5-
**Focus**: Facade pattern - simplifying complex subsystems
3+
**Poziom**: łatwy
4+
**Cel**: Facade - uproszczenie interfejsu do złożonych podsystemów
65

76
## 🎯 Zadanie
8-
Zaimplementuj `SmartHomeFacade` - upraszcza sterowanie wieloma urządzeniami.
7+
Zaimplementuj wzorzec Facade dla systemu inteligentnego domu. `SmartHomeFacade` upraszcza sterowanie wieloma urządzeniami poprzez wystawienie prostych metod wysokiego poziomu.
98

109
## 📋 Wymagania
11-
- [ ] `SmartHomeFacade.__init__()` - tworzy Light, Thermostat, Security, TV
12-
- [ ] `evening_mode()` - dim(50), temp(22), disarm, TV on
13-
- [ ] `leaving_home()` - light off, temp(18), arm, TV off
10+
- [ ] Przechodzą doctesty
11+
- [ ] Przechodzą testy jednostkowe (pytest)
12+
- [ ] `SmartHomeFacade` tworzy wszystkie podsystemy w konstruktorze
13+
- [ ] Metoda `evening_mode()` koordynuje wszystkie podsystemy
14+
- [ ] Metoda `leaving_home()` koordynuje wszystkie podsystemy
1415

1516
## 🚀 Jak zacząć
16-
```bash
17-
cd day2_structural/05_facade
18-
pytest test_facade.py -v
19-
```
17+
1. Otwórz `starter.py`
18+
2. Uruchom testy (powinny failować):
19+
- Doctests: `python -m doctest starter.py -v`
20+
- Pytest: `pytest` (lub `pytest -v` dla bardziej szczegółowego outputu)
21+
3. Podsystemy (`Light`, `Thermostat`, `SecuritySystem`, `TV`) są już gotowe
22+
4. Zaimplementuj klasę `SmartHomeFacade`:
23+
- Konstruktor tworzy instancje wszystkich podsystemów
24+
- Metoda `evening_mode()` - wywołuje odpowiednie metody podsystemów
25+
- Metoda `leaving_home()` - wywołuje odpowiednie metody podsystemów
26+
5. Uruchom testy ponownie (teraz powinny przejść)
27+
6. Gdy wszystkie testy przechodzą:
28+
```bash
29+
git add .
30+
git commit -m "Complete Facade pattern"
31+
git push
32+
```
33+
7. Sprawdź wynik w GitHub Actions
2034

2135
## 💡 Facade w pigułce
2236

23-
**Upraszcza interfejs do złożonego podsystemu**
37+
**Facade deleguje pracę do wielu podsystemów i upraszcza interfejs**
38+
39+
### Jak to działa:
40+
1. Facade tworzy instancje wszystkich podsystemów w konstruktorze
41+
2. Klient wywołuje jedną metodę Facade (np. `evening_mode()`)
42+
3. Facade koordynuje wywołania do wielu podsystemów w odpowiedniej kolejności
43+
44+
### Kluczowy moment:
45+
```python
46+
def evening_mode(self) -> str:
47+
# Facade wywołuje wiele podsystemów
48+
result1 = self.light.dim(50)
49+
result2 = self.thermostat.set_temperature(22)
50+
# ... itd
51+
```
52+
53+
Klient nie musi znać `Light`, `Thermostat`, `SecuritySystem`, `TV` - tylko `SmartHomeFacade`.
54+
55+
---
2456

25-
**Źle** (klient zna wszystkie podsystemy):
57+
### ❌ Bez wzorca:
2658
```python
27-
# Klient wywołuje 4 klasy ❌
59+
# Klient zarządza wszystkim
2860
light = Light()
2961
thermostat = Thermostat()
3062
security = SecuritySystem()
3163
tv = TV()
3264

33-
# Klient musi pamiętać sekwencję
65+
# Musi pamiętać sekwencję
3466
light.dim(50)
3567
thermostat.set_temperature(22)
3668
security.disarm()
3769
tv.turn_on()
3870
```
3971

40-
**Dobrze** (Facade ukrywa złożoność):
72+
### ✅ Z wzorcem (Facade):
4173
```python
42-
home = SmartHomeFacade() # Jedna klasa ✅
43-
home.evening_mode() # Jedna metoda ✅
44-
45-
# Facade wywoła wszystkie 4 podsystemy w odpowiedniej kolejności
74+
home = SmartHomeFacade()
75+
home.evening_mode()
76+
# Facade zarządza wszystkim wewnętrznie
4677
```
4778

48-
**Korzyść**: Klient nie zna Light/Thermostat/Security/TV - tylko Facade.
49-
50-
**Kiedy stosować**:
51-
- Uproszczenie złożonego API
52-
- Ukrycie legacy code
53-
- Jeden punkt wejścia do wielu systemów
54-
55-
Sprawdź `solution_facade.py` po wykonaniu.
79+
**Korzyść**: Klient wywołuje jedną metodę zamiast czterech, bez znajomości implementacji podsystemów.

3_structural/05_facade/problem.py

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
"""
2+
❌ PROBLEM: Klient bezpośrednio zarządza wieloma podsystemami
3+
4+
Rozwiązanie bez wzorca Facade:
5+
- Klient musi znać wszystkie klasy podsystemów (Light, Thermostat, Security, TV)
6+
- Klient musi pamiętać sekwencję wywołań dla każdej akcji
7+
- Duplikacja logiki w wielu miejscach kodu klienta
8+
"""
9+
10+
11+
class Light:
12+
"""Podsystem - oświetlenie"""
13+
14+
def turn_on(self) -> str:
15+
return "Light turned ON"
16+
17+
def turn_off(self) -> str:
18+
return "Light turned OFF"
19+
20+
def dim(self, level: int) -> str:
21+
return f"Light dimmed to {level}%"
22+
23+
24+
class Thermostat:
25+
"""Podsystem - termostat"""
26+
27+
def set_temperature(self, temp: int) -> str:
28+
return f"Thermostat set to {temp}°C"
29+
30+
31+
class SecuritySystem:
32+
"""Podsystem - alarm"""
33+
34+
def arm(self) -> str:
35+
return "Security system ARMED"
36+
37+
def disarm(self) -> str:
38+
return "Security system DISARMED"
39+
40+
41+
class TV:
42+
"""Podsystem - telewizor"""
43+
44+
def turn_on(self) -> str:
45+
return "TV turned ON"
46+
47+
def turn_off(self) -> str:
48+
return "TV turned OFF"
49+
50+
51+
# ❌ Przykład użycia - klient zarządza wszystkim
52+
if __name__ == "__main__":
53+
# ❌ PROBLEM: Klient musi stworzyć wszystkie podsystemy
54+
light = Light()
55+
thermostat = Thermostat()
56+
security = SecuritySystem()
57+
tv = TV()
58+
59+
# ❌ PROBLEM: Klient musi pamiętać sekwencję dla "trybu wieczornego"
60+
print("=== Evening Mode ===")
61+
print(light.dim(50))
62+
print(thermostat.set_temperature(22))
63+
print(security.disarm())
64+
print(tv.turn_on())
65+
66+
# ❌ PROBLEM: Klient musi pamiętać inną sekwencję dla "wychodzenia"
67+
print("\n=== Leaving Home ===")
68+
print(light.turn_off())
69+
print(thermostat.set_temperature(18))
70+
print(security.arm())
71+
print(tv.turn_off())
72+
73+
# ❌ Każde miejsce w kodzie, które potrzebuje "evening mode"
74+
# musi powtarzać te 4 linie
75+
#
76+
# ❌ Zmiana sekwencji wymaga edycji w wielu miejscach
77+
#
78+
# ❌ Nowy programista musi znać wszystkie 4 klasy podsystemów
79+
80+
81+
"""
82+
Jakie problemy rozwiązuje Facade?
83+
84+
1. ❌ Zbyt wiele zależności
85+
- Klient zależy od Light, Thermostat, SecuritySystem, TV
86+
- Dodanie nowego podsystemu wymaga zmian w kliencie
87+
- Wysokie sprzężenie (tight coupling)
88+
89+
2. ❌ Duplikacja logiki
90+
- "Evening mode" może być używany w 10 miejscach
91+
- Każde miejsce powtarza te same 4 wywołania
92+
- Zmiana sekwencji = edycja 10 miejsc
93+
94+
3. ❌ Trudne utrzymanie
95+
- Klient musi znać szczegóły implementacji podsystemów
96+
- Klient musi pamiętać prawidłową kolejność wywołań
97+
- Łatwo o błąd (zapomnienie jednego kroku)
98+
99+
4. ❌ Brak abstrakcji
100+
- Klient operuje na niskim poziomie (dim, set_temperature)
101+
- Brak operacji wysokiego poziomu (evening_mode, leaving_home)
102+
- Kod trudny do zrozumienia
103+
104+
5. ❌ Trudne testowanie
105+
- Testowanie klienta wymaga mockowania 4 klas
106+
- Każdy test musi setupować wszystkie podsystemy
107+
- Duża liczba zależności
108+
109+
Jak Facade to rozwiązuje?
110+
1. SmartHomeFacade ukrywa wszystkie podsystemy
111+
2. Klient wywołuje home.evening_mode() zamiast 4 metod
112+
3. Logika sekwencji w jednym miejscu (Facade)
113+
4. Łatwe testowanie - mockujemy tylko Facade
114+
"""

3_structural/05_facade/solution_facade.py

Lines changed: 0 additions & 92 deletions
This file was deleted.

0 commit comments

Comments
 (0)