Pokazać współdziałanie dziedziczenia, polimorfizmu i wzorca Strategy w mini-architekturze systemu uczelnianego.
System oceniania musi wspierać różne metody obliczania wyniku końcowego.
Zamiast używać serii if/elif, delegujemy algorytm do osobnego obiektu — strategii.
Klasa Course:
- nie wie, jak liczyć wynik,
- zna tylko interfejs
GradePolicy.final_score.
Dzięki temu:
- zmiana polityki oceniania nie wymaga modyfikacji
Course, - każdą politykę można testować niezależnie,
- nowa polityka to nowa klasa, nie nowa gałąź
if.
Diagram: diagrams/topic_10.png
class GradePolicy:
def final_score(self, points: list[float]) -> float:
raise NotImplementedError
class MeanPolicy(GradePolicy):
def final_score(self, points: list[float]) -> float:
return sum(points) / len(points)
class BestOfTwoPolicy(GradePolicy):
def final_score(self, points: list[float]) -> float:
top = sorted(points, reverse=True)[:2]
return sum(top) / len(top)
class Course:
def __init__(self, name: str, policy: GradePolicy) -> None:
self.name = name
self.policy = policy
def evaluate(self, points: list[float]) -> float:
return self.policy.final_score(points)Plik: examples/grading_system.py
course_mean = Course("Analiza", MeanPolicy())
course_best = Course("Algebra", BestOfTwoPolicy())
print(course_mean.evaluate([3.0, 4.0, 5.0])) # 4.0
print(course_best.evaluate([3.0, 4.0, 5.0])) # 4.5# BEZ wzorca — trudne do rozszerzenia
def evaluate(policy_name: str, points: list[float]) -> float:
if policy_name == "mean":
return sum(points) / len(points)
elif policy_name == "best_of_two":
... # kolejny elif przy każdej nowej polityce
# Z wzorcem — Open/Closed
def evaluate(policy: GradePolicy, points: list[float]) -> float:
return policy.final_score(points)- Uruchom
examples/grading_system.py. - Dodaj
WeightedPolicy(w1, w2)obliczającą:points[0]*w1 + points[1]*w2. - Napisz test porównujący 3 strategie na tych samych danych.
- Przeanalizuj, które klasy spełniają SRP, a które nie.
- Dodaj walidację: polityki nie powinny akceptować pustych list.
- Student rozumie, jak strategia oddziela algorytm od kontekstu.
- Student potrafi zaprojektować małą architekturę z testowalną logiką domenową.
- szablon:
exercises/tasks.py - przykładowe rozwiązanie:
exercises/solutions_10.py - testy:
exercises/test_solutions.py
Zadanie: napisz klasę WeightedPolicy(w1, w2) z metodą final_score(points).
- Dlaczego wzorzec Strategy poprawia rozszerzalność systemu?
- Jak oddzielić logikę domenową od prezentacji wyników?
- Które elementy tego przykładu są polimorficzne?
- Jak dodać nową politykę bez modyfikacji klasy
Course? - Jak zaprojektować testy dla wielu strategii jednocześnie?
- E. Gamma i in., Design Patterns, wzorzec Strategy.
- https://docs.python.org/3/tutorial/classes.html
