3.2 ארכיטקטורת שכבות תרגול
ארגון מחדש¶
תרגיל 1 - זיהוי הפרות שכבות¶
הקוד הבא מפר את עקרון הפרדת השכבות. לכל הפרה - זהו אותה וציינו לאיזו שכבה הקוד שייך ולאיזו הוא "דלף":
# routes/tasks.py
from fastapi import APIRouter
import sqlite3
router = APIRouter()
@router.post("/tasks")
def create_task(title: str, owner_id: int):
# בדיקה 1: משתמש קיים
db = sqlite3.connect("taskflow.db")
user = db.execute("SELECT * FROM users WHERE id=?", (owner_id,)).fetchone()
if not user:
return {"error": "משתמש לא קיים"}
# בדיקה 2: לא יותר מ-50 משימות פתוחות
open_tasks = db.execute(
"SELECT count(*) FROM tasks WHERE owner_id=? AND status != 'done'",
(owner_id,)
).fetchone()[0]
if open_tasks >= 50:
return {"error": "יותר מדי משימות פתוחות"}
# שמירה
cursor = db.execute(
"INSERT INTO tasks (title, status, owner_id) VALUES (?, 'todo', ?)",
(title, owner_id)
)
db.commit()
# שליחת מייל
import smtplib
server = smtplib.SMTP("smtp.gmail.com")
server.sendmail("system@app.com", user[2], f"משימה חדשה: {title}")
return {"id": cursor.lastrowid, "title": title}
תרגיל 2 - ארגון מחדש¶
קחו את הקוד מתרגיל 1 ארגנו אותו מחדש בשלוש שכבות נפרדות:
- routes/tasks.py - רק HTTP handling
- services/task_service.py - לוגיקה עסקית
- repositories/task_repository.py - גישה למסד הנתונים
תרגיל 3 - הוספת פיצ'ר¶
אחרי שארגנתם את הקוד, הוסיפו endpoint חדש:
GET /tasks/overdue - מחזיר את כל המשימות שעבר תאריך היעד שלהן ועדיין לא הושלמו.
ממשו אותו בשלוש השכבות:
1. route שמחזיר רשימת TaskResponse
2. task_service.get_overdue_tasks(owner_id: int) - לוגיקה
3. task_repository.find_overdue(owner_id: int) - שאילתת SQL