Initial commit: IHK Ausbildung materials
This commit is contained in:
@@ -0,0 +1,261 @@
|
||||
# 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)
|
||||
|
||||
```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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```python
|
||||
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)
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
1. **Analysieren**: Anforderungen verstehen, Datenmodelle ableiten
|
||||
2. **Planen**: Module und Schnittstellen entwerfen
|
||||
3. **Implementieren**: Komponenten entwickeln
|
||||
4. **Testen**: Tests durchführen, Qualität sichern
|
||||
5. **Optimieren**: Verbesserungen einarbeiten
|
||||
|
||||
---
|
||||
|
||||
## Prüfungsrelevanz
|
||||
|
||||
- Programmierkenntnisse für Teil 2
|
||||
- Wichtig für Abschlussprojekt
|
||||
|
||||
---
|
||||
|
||||
## Querverweise
|
||||
|
||||
- [[3-Ausbildungsjahr/LF10a-Benutzeroberflächen|Vorher: LF 10a]]
|
||||
- [[3-Ausbildungsjahr/LF12a-Kundenspezifische-Entwicklung|Nachher: LF 12a]]
|
||||
- [[Programmiersprachen/Python|OOP mit Python]]
|
||||
|
||||
---
|
||||
|
||||
*Stand: 2024 | Quelle: KMK Rahmenlehrplan 13.12.2019*
|
||||
Reference in New Issue
Block a user