Implementowanie Czystej Architektury w Pythonie - Helion
Autor: Sebastian Buczyński
ISBN: 978-83-283-8686-0
okładka: miękka
Księgarnia: Helion
ISBN: 978-83-283-8686-0
okładka: miękka
Księgarnia: Helion
Książka będzie dostępna od września 2021
Zobacz także:
- Windows Media Center. Domowe centrum rozrywki 66,67 zł, (8,00 zł -88%)
- Ruby on Rails. Ćwiczenia 18,75 zł, (3,00 zł -84%)
- Przywództwo w świecie VUCA. Jak być skutecznym liderem w niepewnym środowisku 58,64 zł, (12,90 zł -78%)
- Scrum. O zwinnym zarządzaniu projektami. Wydanie II rozszerzone 58,64 zł, (12,90 zł -78%)
- Od hierarchii do turkusu, czyli jak zarządzać w XXI wieku 58,64 zł, (12,90 zł -78%)
Spis treści
Implementowanie Czystej Architektury w Pythonie -- spis treści
1. WPROWADZENIE
- 1.1. Era narzędzi
- 1.2. Dla kogo jest ta książka?
- 1.3. Co znajdziesz w książce?
2. PODSTAWY CZYSTEJ ARCHITEKTURY
- 2.1. Po co to wszystko?
- 2.2. System płytki kontra system głęboki
- 2.2.1. CRUD, czyli system płytki
- 2.2.2. System głęboki
- 2.3. Założenia czystej architektury
- 2.3.1. Niezależność od frameworków
- 2.3.2. Wysoka testowalność
- 2.3.3. Niezależność od API i interfejsu użytkownika
- 2.3.4. Niezależność od bazy danych
- 2.3.5. Niezależność od firm trzecich
- 2.3.6. Elastyczność
- 2.3.7. Rozszerzalność
- 2.4. Warstwy, czyli horyzontalna organizacja kodu
- 2.4.1. Świat zewnętrzny
- 2.4.2. Infrastruktura
- 2.4.3. Aplikacja
- 2.4.4. Domena
- 2.4.5. Zasada zależności
- 2.4.6. Granice
- 2.5. Podsumowanie
3. WZORCOWA IMPLEMENTACJA
- 3.1. Oznajmienie
- 3.2. Przepływ sterowania w czystej architekturze
- 3.3. Wymagania biznesowe
- 3.4. Implementacja
- 3.4.1. Diagram sekwencji
- 3.4.2. Granica wejściowa (input boundary)
- 3.4.3. Granica wyjściowa (output boundary)
- 3.4.4. Prezenter (presenter)
- 3.4.5. Model widoku (view model)
- 3.4.6. Przypadek użycia (use case)
- 3.4.7. Interfejs dostępu do danych (data access interface)
- 3.4.8. Dostęp do danych (data access)
- 3.4.9. Encja oferty (bid)
- 3.4.10. Encja aukcji (auction)
- 3.5. Podsumowanie
4. MODYFIKACJE CZYSTEJ ARCHITEKTURY
- 4.1. Dylemat prezentera
- 4.2. Pozbywamy się granicy wejściowej
- 4.3. Alternatywne podejścia do projektowania przypadków użycia
- 4.3.1. Fasada
- 4.3.2. Mediator pomiędzy wejściowym DTO a przypadkiem użycia
- 4.4. Użycie modeli bazodanowych jako encji
- 4.5. Podsumowanie
5. WSTRZYKIWANIE ZALEŻNOŚCI
- 5.1. Czym są zależności?
- 5.2. Wszędobylskie abstrakcje i klasy
- 5.3. Abstrakcje w czystej architekturze
- 5.4. Odwrócenie sterowania a zależności
- 5.5. Kontener IoC kontra service locator
- 5.6. Wstrzykiwanie zależności kontra konfiguracja
- 5.7. Podsumowanie
6. CQRS
- 6.1. Wstęp
- 6.2. Co to ma wspólnego z czystą architekturą?
- 6.3. Osobny stos odczytu - dlaczego?
- 6.4. Osobny stos odczytu - jak?
- 6.4.1. Zapytanie jako DTO
- 6.4.2. Zapytania jako osobne klasy
- 6.4.3. Fasada modelu do odczytu
- 6.5. CQRS kontra REST API
- 6.6. CQRS kontra GraphQL
- 6.7. Podsumowanie
7. OSTRE GRANICE
- 7.1. Słowo o złożoności
- 7.2. Dwa światy
- 7.3. Granica pomiędzy warstwą aplikacji a światem zewnętrznym
- 7.4. Pisanie wejściowego DTO
- 7.5. Value objects
- 7.6. Podsumowanie
8. STUDIUM PRZYPADKU - PLATFORMA AUKCYJNA
- 8.1. Jak pracujemy?
- 8.2. Jak zacząć, czyli chodzący szkielet
- 8.3. Nasz chodzący szkielet
- 8.4. Przypadek użycia dla składania oferty na aukcji
- 8.4.1. Nazewnictwo
- 8.4.2. Argumenty
- 8.4.3. Wyjście
- 8.4.4. Testy
- 8.5. Encje aukcji i oferty
- 8.5.1. Nazewnictwo
- 8.5.2. Value objects jako identyfikatory
- 8.5.3. Implementacja
- 8.5.4. Testy jednostkowe
- 8.5.5. Implementacja - ciąg dalszy
- 8.6. Abstrakcyjne repozytorium
- 8.6.1. Nazewnictwo
- 8.6.2. Implementacja
- 8.7. Repozytorium
- 8.7.1. Nazewnictwo
- 8.7.2. Implementacja działająca w pamięci
- 8.7.3. Rozwijanie implementacji pod osłoną TDD
- 8.8. Kończymy przypadek użycia - składanie oferty
- 8.8.1. Wstrzykiwanie zależności
- 8.8.2. Sprawiamy, że pierwszy sensowny test przechodzi
- 8.8.3. Refaktoryzacja
- 8.9. Organizacja kodu
- 8.9.1. Jak można ułożyć kod w Pythonie?
- 8.9.2. Organizujemy kod projektu
- 8.9.3. Organizujemy kod warstwy infrastruktury
- 8.9.4. Łączymy wszystko razem w komponencie main
- 8.9.5. Wystawiamy API
- 8.10. Finalizujemy aukcję w kolejnym przypadku użycia
- 8.10.1. Zarys przypadku użycia i wejściowe DTO
- 8.10.2. Rozszerzamy encję, by spełnić nowe wymagania
- 8.10.3. Skoro encje nie powinny mieć żadnych zależności, to czy mogą pytać o czas?
- 8.10.4. Wprowadzamy port dla płatności
- 8.10.5. Implementujemy adapter
- 8.10.6. Obsługa błędów kontra zasada zależności
- 8.10.7. A co, gdybyśmy chcieli dodać zapamiętywanie karty płatniczej?
- 8.10.8. Jak żyć, gdy adapter rośnie?
- 8.10.9. Bramka płatności ma już SDK. Nie możemy go po prostu użyć?
- 8.11. Przypadek użycia - rozpoczynanie nowej aukcji
- 8.11.1. Skąd się biorą nowe aukcje?
- 8.11.2. Encja aukcji i jej opis w jednym obiekcie - za i przeciw
- 8.11.3. Wprowadzamy deskryptor
- 8.11.4. Repozytorium z interfejsem kolekcji
- 8.11.5. Które repozytorium wybrać?
- 8.12. Operacje odczytu danych
- 8.12.1. Podejście z przypadkami użycia
- 8.12.2. CQRS na ratunek
- 8.12.3. Zapytania jako klasa
- 8.12.4. Model do odczytu
- 8.12.5. Podsumowanie operacji odczytujących dane
- 8.13. Odwracamy kontrolę za pomocą zdarzeń
- 8.13.1. Przykład - wysyłka e-maili
- 8.13.2. Techniki odwracania kontroli
- 8.13.3. Implementacja zdarzeń
- 8.13.4. Skąd wziąć szynę zdarzeń?
- 8.13.5. Jak wydostać zdarzenia z encji?
- 8.13.6. Encja gromadzi zdarzenia, które potem publikuje repozytorium
- 8.13.7. Encja zwraca zdarzenia z metod, które zmieniają jej stan
- 8.13.8 Testowanie encji, które zwracają zdarzenia
- 8.13.9. Subskrybowanie się na zdarzenia
- 8.13.10. Zdarzenia kontra transakcje kontra efekty uboczne
- 8.13.11. Niezawodne publikowanie zdarzeń - outbox pattern
- 8.13.12. Wprowadzamy jednostkę pracy
- 8.13.13. Czas życia jednostki pracy
- 8.13.14. Relacja pomiędzy jednostką pracy a szyną zdarzeń
- 8.14. Radzimy sobie z innymi przekrojowymi zagadnieniami
- 8.14.1. Konfiguracja
- 8.14.2. Walidacja
- 8.14.3. Synchronizacja
- 8.15. Podsumowanie
9. MODULARNOŚĆ
- 9.1. Ciężar sukcesu - rozrost i ciągłe zmiany
- 9.2. Komponenty i kohezja
- 9.3. Organizacja kodu według komponentu
- 9.4. Komponenty i swoboda architektoniczna
- 9.5. Komponenty kontra mikroserwisy
- 9.6. Komponenty a użytkownik
- 9.7. Komponenty a bounded context
- 9.8. Komponenty - implementacja
- 9.9. Zależności między komponentami
- 9.9.1. Oddzielne drogi
- 9.9.2. Bezpośrednia zależność - oba komponenty implementują czystą architekturę
- 9.9.3. Niebezpośrednia zależność - oba komponenty implementują czystą architekturę
- 9.9.4. Zależność, gdy jeden z komponentów nie implementuje czystej architektury
- 9.9.5. Odmiany integracji za pomocą zdarzeń
- 9.9.6. Zależności między komponentami - podsumowanie
- 9.10. Studium przypadku - platforma aukcyjna
- 9.10.1. Odkrywamy komponenty
- 9.10.2. Komponenty platformy aukcyjnej
- 9.10.3. Co komponent wystawia na zewnątrz?
- 9.10.4. Tam, gdzie wszystko składa się w całość - komponent main
- 9.10.5. Korzystamy z komponentu main do uruchomienia aplikacji
- 9.10.6. Jedna architektura dla wszystkich komponentów - czy to możliwe?
- 9.10.7. Zależności pomiędzy komponentami
- 9.10.8. Integrowanie komponentów za pomocą zdarzeń
- 9.10.9. Wewnętrzna obsługa zdarzeń w tym samym komponencie
- 9.10.10. Integracja różnych komponentów za pomocą zdarzeń - prosty przypadek
- 9.10.11. Integracja różnych komponentów za pomocą zdarzeń - złożony przypadek
- 9.10.12. Inne ciekawe zastosowania menadżera procesu
- 9.10.13. Menadżer procesu kontra wyścigi
- 9.11. Podsumowanie
10. TESTOWANIE
- 10.1. Strategia testowania i odmiany funkcji
- 10.1.1. Piramida testów - mit czy jedyna słuszna droga?
- 10.1.2. Rodzaje testów
- 10.1.3. Jak przetestować przeglądarkę do bazy danych?
- 10.1.4. Jak przetestować proxy?
- 10.1.5. Jak przetestować system głęboki?
- 10.2. Odkrywamy testowanie jednostkowe na nowo
- 10.2.1. Ile musi wiedzieć test?
- 10.3. Testowanie stanu kontra testowanie interakcji
- 10.3.1. Rodzaje weryfikacji
- 10.3.2. Niebezpieczeństwa związane z inspekcją stanu
- 10.3.3. Niebezpieczeństwa związane ze sprawdzaniem interakcji
- 10.3.4. Stuby kontra mocki
- 10.3.5. Rodzaje obiektów dublerów
- 10.4. Testujemy cały komponent jednostkowo
- 10.4.1. Ustawiamy komponent w pożądanym stanie
- 10.4.2. Wywołujemy akcję na komponencie
- 10.4.3. Weryfikujemy rezultat akcji na poziomie komponentu
- 10.4.4. Radzimy sobie z zależnościami w postaci portów i repozytoriów
- 10.5. Podsumowanie
11. ZAKOŃCZENIE
- 11.1. Co dalej?
12. SUPLEMENT A: MIGRACJA Z PROJEKTU ODZIEDZICZONEGO
- 12.1. Czy powinno się to robić?
- 12.2. Jak to zrobić?
- 12.3. "Nie mogę przestać dostarczać nowych funkcji!"
13. SUPLEMENT B: WPROWADZENIE DO EVENT SOURCING
- 13.1. Co to jest event sourcing?
- 13.2. Agregat z event sourcing kontra agregat z domain-driven design
- 13.3. Prosty przykład agregatu
- 13.3.1. Zamówienie jako encja
- 13.3.2. Istotne zmiany zamówienia w formie zdarzeń
- 13.3.3. Uwaga na te zdarzenia!
- 13.3.4. Zamówienie jako agregat
- 13.3.5. Testowanie agregatów
- 13.4. Persystencja
- 13.4.1. Nowe zdarzenia są dołączane na koniec strumienia zdarzeń
- 13.4.2. Pobieranie strumienia zdarzeń
- 13.4.3. Dopisywanie nowych zdarzeń do strumienia
- 13.4.4. Wybór bazy danych - podsumowanie wymagań
- 13.4.5. Przykładowa implementacja z użyciem PostgreSQL
- 13.4.6. Użycie event store
- 13.4.7. Co robić, gdy wykryjemy wyścig?
- 13.4.8. Użycie repozytorium do ukrycia event store
- 13.4.9. Migawki stanu agregatu
- 13.5. Projekcje
- 13.6. Event sourcing w aplikacji składającej się z komponentów
- 13.6.1. Event sourcing to szczegół implementacyjny komponentu
- 13.6.2. Stosuj zdarzenia domenowe na potrzeby integracji
- 13.7. Podsumowanie
BIBLIOGRAFIA