Architekturpatterns mit Python

Book description

Pythons Popularität wächst und mit Python werden inzwischen komplexe Projekte realisiert. Viele Python-Entwicklerinnen und -Entwickler interessieren sich deshalb für High-Level-Design-Patterns wie hexagonale Architektur, Event-gesteuerte Architektur und die strategischen Patterns, die durch das Domain-Driven Design vorgegeben sind. Das Übertragen dieser Patterns nach Python ist allerdings nicht immer einfach.

In diesem Praxisbuch stellen Harry Percival und Bob Gregory von MADE.com erprobte Architekturpatterns vor, die Python-Entwickler dabei unterstützen, die Komplexität von Anwendungen im Griff zu behalten – und den größtmöglichen Nutzen aus den Testsuiten zu ziehen. Jedes Pattern wird durch Beispiele in schönem, idiomatischem Python illustriert; dabei wird die Weitschweifigkeit der Java- oder C#-Syntax vermieden.

Table of contents

  1. Cover
  2. Titel
  3. Impressum
  4. Inhalt
  5. Vorwort
  6. Einleitung
  7. Teil I Eine Architektur aufbauen, die Domänenmodellierung unterstützt
    1. 1 Domänenmodellierung
    2. Was ist ein Domänenmodell?
    3. Die Domänensprache untersuchen
    4. Unit Testing für Domänenmodelle
    5. Dataclasses sind großartig für Value Objects
    6. Value Objects und Entitäten
    7. Nicht alles muss ein Objekt sein: eine Domänenservice-Funktion
    8. Pythons magische Methoden lassen uns unsere Modelle mit idiomatischem Python nutzen
    9. Auch Exceptions können Domänenkonzepte ausdrücken
    10. 2 Repository-Pattern
    11. Unser Domänenmodell persistieren
    12. Etwas Pseudocode: Was werden wir brauchen?
    13. DIP auf den Datenzugriff anwenden
    14. Erinnerung: unser Modell
    15. Der »normale« ORM-Weg: Das Modell hängt vom ORM ab
    16. Die Abhängigkeit umkehren: ORM hängt vom Modell ab
    17. Das Repository-Pattern
    18. Das Repository im Abstrakten
    19. Vor- und Nachteile
    20. Es ist nicht einfach, ein Fake-Repository für Tests zu erstellen!
    21. Was ist in Python ein Port und was ein Adapter?
    22. Zusammenfassung
    23. 3 Ein kleiner Exkurs zu Kopplung und Abstraktionen
    24. Das Abstrahieren eines Status verbessert die Testbarkeit
    25. Die richtige(n) Abstraktion(en) wählen
    26. Unsere gewählten Abstraktionen implementieren
    27. Edge-to-Edge-Tests mit Fakes und Dependency Injection
    28. Warum nicht einfach herauspatchen?
    29. Zusammenfassung
    30. 4 Unser erster Use Case: Flask-API und Serviceschicht
    31. Unsere Anwendung mit der echten Welt verbinden
    32. Ein erster End-to-End-Test
    33. Die direkte Implementierung
    34. Fehlerbedingungen, die Datenbank-Checks erfordern
    35. Einführen eines Service Layer und Einsatz von FakeRepository für die Unit Tests
    36. Eine typische Servicefunktion
    37. Warum wird alles als Service bezeichnet?
    38. Dinge in Ordnern ablegen, um zu sehen, wohin sie gehören
    39. Zusammenfassung
    40. Das DIP in Aktion
    41. 5 TDD hoch- und niedertourig
    42. Wie sieht unsere Testpyramide aus?
    43. Sollten Tests der Domänenschicht in den Service Layer verschoben werden?
    44. Entscheiden, was für Tests wir schreiben
    45. Hoch- und niedertourig
    46. Tests für den Service Layer vollständig von der Domäne entkoppeln
    47. Linderung: alle Domänenabhängigkeiten in Fixture-Funktionen unterbringen
    48. Einen fehlenden Service hinzufügen
    49. Die Verbesserung in die E2E-Tests bringen
    50. Zusammenfassung
    51. 6 Unit-of-Work-Pattern
    52. Die Unit of Work arbeitet mit dem Repository zusammen
    53. Eine UoW über Integrationstests voranbringen
    54. Unit of Work und ihr Context Manager
    55. Die echte Unit of Work nutzt SQLAlchemy-Sessions
    56. Fake Unit of Work zum Testen
    57. Die UoW im Service Layer einsetzen
    58. Explizite Tests für das Commit/Rollback-Verhalten
    59. Explizite versus implizite Commits
    60. Beispiele: mit UoW mehrere Operationen in einer atomaren Einheit gruppieren
    61. Beispiel 1: Neuzuteilung von Aufträgen
    62. Beispiel 2: Chargengröße ändern
    63. Die Integrationstests aufräumen
    64. Zusammenfassung
    65. 7 Aggregate und Konsistenzgrenzen
    66. Warum nehmen wir nicht einfach eine Tabellenkalkulation?
    67. Invarianten, Constraints und Konsistenz
    68. Invarianten, Concurrency und Sperren
    69. Was ist ein Aggregat?
    70. Ein Aggregat wählen
    71. Ein Aggregat = ein Repository
    72. Und was ist mit der Performance?
    73. Optimistische Concurrency mit Versionsnummern
    74. Optionen für Versionsnummern implementieren
    75. Unsere Regeln zur Datenintegrität testen
    76. Concurrency-Regeln durch den Einsatz von Isolation Level für Datenbanktransaktionen sicherstellen
    77. Beispiel zur pessimistischen Concurrency-Steuerung: SELECT FOR UPDATE
    78. Zusammenfassung
    79. Teil I – Zusammenfassung
  8. Teil II Eventgesteuerte Architektur
    1. 8 Events und der Message Bus
    2. Vermeiden Sie ein Chaos
    3. Zuerst einmal vermeiden wir ein Chaos in unseren Webcontrollern
    4. Unser Modell soll auch nicht chaotisch werden
    5. Vielleicht im Service Layer?
    6. Single Responsibility Principle
    7. Alles einsteigen in den Message Bus!
    8. Das Modell zeichnet Events auf
    9. Events sind einfache Dataclasses
    10. Das Modell wirft Events
    11. Der Message Bus bildet Events auf Handler ab
    12. Option 1: Der Service Layer übernimmt Events aus dem Modell und gibt sie an den Message Bus weiter
    13. Option 2: Der Service Layer wirft seine eigenen Events
    14. Option 3: Die UoW gibt Events an den Message Bus
    15. Zusammenfassung
    16. 9 Ab ins Getümmel mit dem Message Bus
    17. Eine neue Anforderung bringt uns zu einer neuen Architektur
    18. Stellen wir uns eine Architekturänderung vor: Alles wird ein Event-Handler sein
    19. Servicefunktionen in Message-Handler refaktorieren
    20. Der Message Bus sammelt jetzt Events von der UoW ein
    21. Die Tests sind ebenfalls alle anhand von Events geschrieben
    22. Ein vorübergehender hässlicher Hack: Der Message Bus muss Ergebnisse zurückgeben
    23. Unsere API für die Arbeit mit Events anpassen
    24. Unsere neue Anforderung implementieren
    25. Unser neues Event
    26. Test-Drive für einen neuen Handler
    27. Implementierung
    28. Eine neue Methode im Domänenmodell
    29. Optional: isolierte Unit Tests für Event-Handler mit einem Fake-Message-Bus
    30. Zusammenfassung
    31. Was haben wir erreicht?
    32. Warum haben wir das erreicht?
    33. 10 Befehle und Befehls-Handler
    34. Befehle und Events
    35. Unterschiede beim Exception Handling
    36. Events, Befehle und Fehlerbehandlung
    37. Synchrones Wiederherstellen aus Fehlersituationen
    38. Zusammenfassung
    39. 11 Eventgesteuerte Architektur: Events zum Integrieren von Microservices
    40. Distributed Ball of Mud und Denken in Nomen
    41. Fehlerbehandlung in verteilten Systemen
    42. Die Alternative: temporales Entkoppeln durch asynchrone Nachrichten
    43. Einen Redis Pub/Sub Channel zur Integration verwenden
    44. Mit einem End-to-End-Test alles überprüfen
    45. Redis ist ein weiterer schlanker Adapter für unseren Message Bus
    46. Unser neues Event in die Außenwelt
    47. Interne und externe Events
    48. Zusammenfassung
    49. 12 Command-Query Responsibility Segregation (CQRS)
    50. Domänenmodelle sind zum Schreiben da
    51. Die meisten Kundinnen und Kunden werden Ihre Möbel nicht kaufen
    52. Post/Redirect/Get und CQS
    53. Ruhe bewahren!
    54. CQRS-Views testen
    55. »Offensichtliche« Alternative 1: Das bestehende Repository verwenden
    56. Ihr Domänenmodell ist nicht für Leseoperationen optimiert
    57. »Offensichtliche« Alternative 2: Verwenden des ORM
    58. SELECT N+1 und andere Performanceüberlegungen
    59. Ziehen wir die Reißleine
    60. Eine Tabelle im Lesemodell mit einem Event-Handler aktualisieren
    61. Es ist einfach, die Implementierung unseres Lesemodells zu verändern
    62. Zusammenfassung
    63. 13 Dependency Injection (und Bootstrapping)
    64. Implizite und explizite Abhängigkeiten
    65. Sind explizite Abhängigkeiten nicht total schräg und javaesk?
    66. Handler vorbereiten: manuelles DI mit Closures und Partials
    67. Eine Alternative mit Klassen
    68. Ein Bootstrap-Skript
    69. Der Message Bus bekommt die Handler zur Laufzeit
    70. Bootstrap in unseren Einstiegspunkten verwenden
    71. DI in unseren Tests initialisieren
    72. Einen Adapter »sauber« bauen: ein größeres Beispiel
    73. Abstrakte und konkrete Implementierungen definieren
    74. Eine Fake-Version für die Tests erstellen
    75. Wie führen wir einen Integrationstest durch?
    76. Zusammenfassung
  9. Epilog
  10. Anhang A Übersichtsdiagramm und -tabelle
  11. Anhang B Eine Template-Projektstruktur
  12. Anhang C Austauschen der Infrastruktur: alles mit CSVs
  13. Anhang D Repository- und Unit-of-Work-Pattern mit Django
  14. Anhang E Validierung
  15. Fußnoten
  16. Index
  17. Über die Autoren
  18. Kolophon

Product information

  • Title: Architekturpatterns mit Python
  • Author(s): Harry J. W. Percival, Bob Gregory
  • Release date: August 2021
  • Publisher(s): dpunkt
  • ISBN: 9783960091653