6.5 KiB
6.5 KiB
LF 11a: Funktionalität in Anwendungen realisieren
3. Ausbildungsjahr | Zeitrichtwert: 80 Stunden
Kernkompetenz
Die Schülerinnen und Schüler verfügen über die Kompetenz, modulare Komponenten zur informationstechnischen Verarbeitung von Arbeitsabläufen und Geschäftsprozessen zu entwickeln und deren Qualität zu sichern.
Lernziele
Nach diesem Lernfeld kannst du:
- Datenstrukturen und Funktionalitäten aus Anforderungen ableiten
- Modulare Softwarekomponenten planen
- Objektorientierte Programmierung anwenden
- Schnittstellen dokumentieren
- Testfälle formulieren und automatisierte Tests durchführen
- Qualitätskriterien anwenden
Objektorientierte Programmierung (OOP)
Grundkonzepte
OOP-Prinzipien:
├── Kapselung (Encapsulation)
│ └── Daten und Methoden zusammenfassen
├── Vererbung (Inheritance)
│ └── Gemeinsame Eigenschaften vererben
├── Polymorphismus
│ └── Gleiches Verhalten, unterschiedliche Formen
└── Abstraktion
└── Komplexität reduzieren
Klassen-Beispiel (Python)
from abc import ABC, abstractmethod
from datetime import datetime
class Kunde(ABC):
"""Abstrakte Basisklasse für Kunden"""
def __init__(self, kundennummer: int, name: str):
self._kundennummer = kundennummer
self._name = name
self._erstellt_am = datetime.now()
@property
def kundennummer(self) -> int:
return self._kundennummer
@abstractmethod
def berechne_rabatt(self, betrag: float) -> float:
"""Berechnet den Rabatt für den Kunden"""
pass
def __str__(self) -> str:
return f"Kunde {self._kundennummer}: {self._name}"
class Privatkunde(Kunde):
"""Privatkunde mit Standard-Rabatt"""
def __init__(self, kundennummer: int, name: str):
super().__init__(kundennummer, name)
self._rabatt_stufe = 1
def berechne_rabatt(self, betrag: float) -> float:
return betrag * 0.05 * self._rabatt_stufe
class Firmenkunde(Kunde):
"""Firmenkunde mit erhöhtem Rabatt"""
def __init__(self, kundennummer: int, name: str, firmenname: str):
super().__init__(kundennummer, name)
self._firmenname = firmenname
self._rabatt_stufe = 2
def berechne_rabatt(self, betrag: float) -> float:
return betrag * 0.10 * self._rabatt_stufe
Entwurfsmuster (Design Patterns)
Singleton
class DatabaseConnection:
"""Singleton für Datenbankverbindung"""
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
cls._instance.connection = None
return cls._instance
def connect(self, connection_string: str):
if self.connection is None:
print(f"Verbinde mit: {connection_string}")
self.connection = "Datenbankverbindung hergestellt"
def disconnect(self):
if self.connection:
print("Trenne Verbindung")
self.connection = None
Factory Method
class KundeFactory:
"""Factory für Kunden-Erstellung"""
@staticmethod
def create_kunde(kundentyp: str, **kwargs) -> Kunde:
if kundentyp == "privat":
return Privatkunde(**kwargs)
elif kundentyp == "firma":
return Firmenkunde(**kwargs)
else:
raise ValueError(f"Unbekannter Kundentyp: {kundentyp}")
Schnittstellen
API-Design
from typing import List, Optional
from pydantic import BaseModel
class BestellPosition(BaseModel):
"""Datenmodell für Bestellposition"""
artikel_id: int
menge: int
einzelpreis: float
class Bestellung(BaseModel):
"""Datenmodell für Bestellung"""
bestell_id: Optional[int] = None
kundennummer: int
positionen: List[BestellPosition]
gesamtpreis: float
def berechne_gesamtsumme(self) -> float:
return sum(p.menge * p.einzelpreis for p in self.positionen)
REST-API mit FastAPI
from fastapi import FastAPI, HTTPException
from typing import List
app = FastAPI(title="Bestell-API")
bestellungen: List[Bestellung] = []
@app.post("/bestellungen", response_model=Bestellung)
async def create_bestellung(bestellung: Bestellung):
"""Neue Bestellung erstellen"""
bestellung.gesamtpreis = bestellung.berechne_gesamtsumme()
bestellung.bestell_id = len(bestellungen) + 1
bestellungen.append(bestellung)
return bestellung
@app.get("/bestellungen/{bestell_id}")
async def get_bestellung(bestell_id: int):
"""Bestellung abrufen"""
for b in bestellungen:
if b.bestell_id == bestell_id:
return b
raise HTTPException(status_code=404, detail="Nicht gefunden")
Qualitätssicherung
Testmethoden
Test-Pyramide:
╱╲
╱ ╲ E2E Tests
╱────╲
╱ ╲ Integrationstests
╱────────╲
╱ ╲ Unit-Tests
╱────────────╲
Unit-Tests (pytest)
import pytest
from bestellung import Bestellung, BestellPosition
class TestBestellung:
@pytest.fixture
def beispiel_bestellung(self):
positionen = [
BestellPosition(artikel_id=1, menge=2, einzelpreis=10.00),
BestellPosition(artikel_id=2, menge=1, einzelpreis=25.00)
]
return Bestellung(kundennummer=100, positionen=positionen)
def test_gesamtsumme_berechnung(self, beispiel_bestellung):
"""Test der Gesamtsummen-Berechnung"""
ergebnis = beispiel_bestellung.berechne_gesamtsumme()
# 2 × 10 + 1 × 25 = 45
assert ergebnis == 45.00
def test_leere_bestellung(self):
"""Test mit leerer Positionen-Liste"""
bestellung = Bestellung(kundennummer=100, positionen=[])
ergebnis = bestellung.berechne_gesamtsumme()
assert ergebnis == 0.00
Handlungsphasen
- Analysieren: Anforderungen verstehen, Datenmodelle ableiten
- Planen: Module und Schnittstellen entwerfen
- Implementieren: Komponenten entwickeln
- Testen: Tests durchführen, Qualität sichern
- Optimieren: Verbesserungen einarbeiten
Prüfungsrelevanz
- Programmierkenntnisse für Teil 2
- Wichtig für Abschlussprojekt
Querverweise
- 3-Ausbildungsjahr/LF10a-Benutzeroberflächen
- 3-Ausbildungsjahr/LF12a-Kundenspezifische-Entwicklung
- Programmiersprachen/Python
Stand: 2024 | Quelle: KMK Rahmenlehrplan 13.12.2019