Principy vývoje SW
Owner: Daniel Vítek Tags: designpatterns
1. DRY (Don't Repeat Yourself)
Význam: Tento princip říká, že byste se měli vyvarovat opakování stejného kódu na více místech. Když opakujete stejné bloky kódu, je těžší je spravovat, aktualizovat nebo opravovat.
Špatný kód:
def calculate_tax(price):
return price * 0.15
def calculate_total(price):
return price + (price * 0.15)
Zde máme dvě funkce, které obě používají stejné výpočty pro daň. Pokud by se změnil způsob výpočtu daně, museli bychom změnit kód na dvou místech.
Dobrý kód:
def calculate_tax(price):
return price * 0.15
def calculate_total(price):
return price + calculate_tax(price)
V tomto případě se výpočet daně centralizuje v jedné funkci, což je efektivní a snadno spravovatelné.
2. CoC (Convention over Configuration)
Význam: Tento princip znamená, že byste měli používat standardní konvence a nastavení, pokud není potřeba specifikovat jiná nastavení. To zjednodušuje konfiguraci a zrychluje vývoj.
Špatný kód:
Když je nutné specifikovat mnoho konfiguračních parametrů, místo použití běžných konvencí.
db_connection = connect(host="localhost", port=5432, username="admin", password="password")
Dobrý kód:
Použití výchozích hodnot a konvencí.
db_connection = connect() # Použije výchozí hodnoty pro host, port, atd.
3. SOLID Principles
Význam: SOLID je soubor pěti zásad pro objektově orientované programování, které pomáhají psát udržitelný, rozšiřitelný a flexibilní kód.
a) Single Responsibility Principle (SRP)
Význam: Tato zásada říká, že třída by měla mít pouze jednu odpovědnost, tedy jednu úlohu. Pokud třída vykonává více než jednu věc, je těžší ji udržovat a testovat.
Špatný kód:
class Order:
def __init__(self, items):
self.items = items
def calculate_total(self):
total = 0
for item in self.items:
total += item.price
return total
def save_to_db(self):
# Kód pro uložení objednávky do databáze
pass
Dobrý kód:
class Order:
def __init__(self, items):
self.items = items
def calculate_total(self):
total = 0
for item in self.items:
total += item.price
return total
class OrderRepository:
def save(self, order):
# Kód pro uložení objednávky do databáze
pass
b) Open/Closed Principle (OCP)
Význam: Třídy by měly být otevřeny pro rozšíření, ale uzavřeny pro modifikace. To znamená, že můžete přidávat nové funkce do existující třídy bez jejího změnění.
Špatný kód:
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
class AreaCalculator:
def calculate_area(self, rectangle):
if isinstance(rectangle, Rectangle):
return rectangle.area()
# Možná přidání dalších tvarů v budoucnu by vedlo k úpravám této třídy.
Dobrý kód:
class Shape(ABC):
@abstractmethod
def area(self):
pass
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius * self.radius
class AreaCalculator:
def calculate_area(self, shape: Shape):
return shape.area()
c) Liskov Substitution Principle (LSP)
Význam: Funkce, která pracuje s objekty nadtřídy, by měla správně fungovat i s objekty podtříd. Tedy podtřídy by měly být záměnné za své nadtřídy.
Špatný kód:
class Bird:
def fly(self):
pass
class Ostrich(Bird):
def fly(self):
raise NotImplementedError # Pštros není schopen létat
Dobrý kód:
class Bird(ABC):
@abstractmethod
def move(self):
pass
class Sparrow(Bird):
def move(self):
return "Flying"
class Ostrich(Bird):
def move(self):
return "Running"
d) Interface Segregation Principle (ISP)
Význam: Měli byste se vyvarovat vytváření velkých a složitých rozhraní. Místo toho rozdělte rozhraní na menší, specifičtější části, které budou lépe odpovídat potřebám uživatelů.
Špatný kód:
class Worker:
def work(self):
pass
def eat(self):
pass
Dobrý kód:
class Workable:
def work(self):
pass
class Eatable:
def eat(self):
pass
class Worker(Workable, Eatable):
def work(self):
pass
def eat(self):
pass
e) Dependency Inversion Principle (DIP)
Význam: Moduly vyšší úrovně by neměly záviset na modulech nižší úrovně, ale na abstrakcích (rozhraních). Detaily by měly záviset na abstrakcích, ne na konkrétních implementacích.
Špatný kód:
class FileManager:
def save(self, data):
with open('file.txt', 'w') as f:
f.write(data)
Dobrý kód:
class DataSaver(ABC):
@abstractmethod
def save(self, data):
pass
class FileManager(DataSaver):
def save(self, data):
with open('file.txt', 'w') as f:
f.write(data)
class DatabaseSaver(DataSaver):
def save(self, data):
# Kód pro uložení do databáze
pass
4. KISS (Keep It Simple, Stupid)
Význam: Tento princip říká, že systém by měl být co nejjednodušší a přímočarý. Nepřidávejte složitost tam, kde není nezbytná.
Špatný kód:
Kód, který je zbytečně složitý a těžko pochopitelný.
def process_order(order):
if order.status == 'new':
if order.item_type == 'premium':
# Složitý kód pro zpracování prémiového zboží
pass
else:
# Jiný složitý kód pro běžné zboží
pass
Dobrý kód:
Kód, který je přehledný a jednoduchý na pochopení.
def process_order(order):
if order.is_premium():
# Kód pro zpracování prémiového zboží
pass
else:
# Kód pro zpracování běžného zboží
pass
5. YAGNI (You Aren't Gonna Need It)
Význam: Nepřidávejte funkcionalitu, dokud ji skutečně nebudete potřebovat. Pokud něco není okamžitě nutné, neimplementujte to.
Špatný kód:
Předvídání potřeb a implementace funkcí, které zatím nebudete používat.
class Order:
def calculate_discount(self):
# Předpokládaný mechanismus pro slevy, který není aktuálně potřebný
pass
Dobrý kód:
Implementace pouze toho, co je opravdu potřebné.
class Order:
def calculate_total(self):
total = 0
for item in self.items:
total += item.price
return total
6. CQRS (Command Query Responsibility Segregation)
Význam: Tento princip rozděluje operace na dva typy: příkazy (Commands), které mění stav systému, a dotazy (Queries), které pouze vrací data, aniž by měnily stav.
Špatný kód:
Kombinování příkazů a dotazů do jedné metody.
class Order:
def update_status(self, status):
self.status = status
return self.status # Vrací hodnotu i mění stav
Dobrý kód:
Oddělení příkazů a dotazů.
class Order:
def update_status(self, status):
self.status = status
def get_status(self):
return self.status
7. SoC (Separation of Concerns)
Význam: Rozdělení kódu do různých vrstev, kde každá vrstva se stará pouze o jeden aspekt aplikace. To usnadňuje údržbu a testování.
Špatný kód:
Kód, který míchá různé aspekty (například logiku aplikace a rozhraní).
class User:
def save_to_db(self):
pass
def send_email(self):
pass
Dobrý kód:
Oddělení odpovědností do různých tříd.
class User:
def save(self):
pass
class EmailService:
def send_welcome_email(self, user):
pass
Tento dokument shrnuje klíčové principy vývoje softwaru, které vedou k lepší udržovatelnosti, čitelnosti a efektivitě kódu.