Heim >Web-Frontend >js-Tutorial >TypeScript für Domain-Driven Design (DDD)
Domain-Driven Design (DDD) ist ein leistungsstarker Ansatz zur Bewältigung komplexer Softwaresysteme, der sich auf die Kerngeschäftsdomäne und die damit verbundene Logik konzentriert. TypeScript ist mit seiner starken Typisierung und seinen modernen Funktionen ein hervorragendes Werkzeug, um DDD-Konzepte effektiv umzusetzen. Dieser Artikel untersucht die Synergie zwischen TypeScript und DDD und bietet praktische Einblicke, Strategien und Beispiele, um die Lücke zwischen Design und Code zu schließen.
Kernkonzepte
1. Allgegenwärtige Sprache
Zusammenarbeit zwischen Entwicklern und Domänenexperten unter Verwendung einer gemeinsamen Sprache, um Missverständnisse zu reduzieren.
2. Begrenzte Kontexte
Klare Trennung verschiedener Teile der Domäne, um Autonomie und Klarheit innerhalb spezifischer Kontexte zu gewährleisten.
3. Entitäten und Wertobjekte
4. Aggregate
Cluster von Domänenobjekten, die bei Datenänderungen als eine Einheit behandelt werden.
5. Repositorys
Abstrahiert die Persistenzlogik und bietet Zugriff auf Aggregate.
6. Domain-Ereignisse
Signale, die ausgegeben werden, wenn bedeutende Aktionen innerhalb der Domain stattfinden.
7. Anwendungsdienste
Kapseln Sie Geschäftsabläufe und Orchestrierungslogik.
1. Statische Typisierung: Eine starke Typprüfung hilft dabei, die Domänenlogik explizit zu modellieren.
2. Schnittstellen:Verträge zwischen Komponenten durchsetzen.
3. Klassen: Stellen Entitäten, Wertobjekte und Aggregate auf natürliche Weise dar.
4. Typschutz:Gewährleisten Sie die Typsicherheit zur Laufzeit.
5. Dienstprogrammtypen: Aktivieren Sie leistungsstarke Typtransformationen für dynamische Domänen.
1. Modellierungseinheiten
Entitäten haben eindeutige Identitäten und kapseln ihr Verhalten.
class Product { constructor( private readonly id: string, private name: string, private price: number ) {} changePrice(newPrice: number): void { if (newPrice <= 0) { throw new Error("Price must be greater than zero."); } this.price = newPrice; } getDetails() { return { id: this.id, name: this.name, price: this.price }; } }
2. Wertobjekte schaffen
Wertobjekte sind unveränderlich und werden nach Wert verglichen.
class Money { constructor(private readonly amount: number, private readonly currency: string) { if (amount < 0) { throw new Error("Amount cannot be negative."); } } add(other: Money): Money { if (this.currency !== other.currency) { throw new Error("Currency mismatch."); } return new Money(this.amount + other.amount, this.currency); } }
3. Aggregate definieren
Aggregate stellen die Datenkonsistenz innerhalb einer Grenze sicher.
class Order { private items: OrderItem[] = []; constructor(private readonly id: string) {} addItem(product: Product, quantity: number): void { const orderItem = new OrderItem(product, quantity); this.items.push(orderItem); } calculateTotal(): number { return this.items.reduce((total, item) => total + item.getTotalPrice(), 0); } } class OrderItem { constructor(private product: Product, private quantity: number) {} getTotalPrice(): number { return this.product.getDetails().price * this.quantity; } }
4. Repositories implementieren
Repositorys abstrahieren den Datenzugriff.
interface ProductRepository { findById(id: string): Product | null; save(product: Product): void; } class InMemoryProductRepository implements ProductRepository { private products: Map<string, Product> = new Map(); findById(id: string): Product | null { return this.products.get(id) || null; } save(product: Product): void { this.products.set(product.getDetails().id, product); } }
5. Verwenden von Domänenereignissen
Domänenereignisse benachrichtigen das System über Statusänderungen.
class DomainEvent { constructor(public readonly name: string, public readonly occurredOn: Date) {} } class OrderPlaced extends DomainEvent { constructor(public readonly orderId: string) { super("OrderPlaced", new Date()); } } // Event Handler Example function onOrderPlaced(event: OrderPlaced): void { console.log(`Order with ID ${event.orderId} was placed.`); }
6. Anwendungsdienste
Anwendungsdienste koordinieren Arbeitsabläufe und erzwingen Anwendungsfälle.
class OrderService { constructor(private orderRepo: OrderRepository) {} placeOrder(order: Order): void { this.orderRepo.save(order); const event = new OrderPlaced(order.id); publishEvent(event); // Simulated event publishing } }
Nutzen Sie die modularen Funktionen von TypeScript, um begrenzte Kontexte zu isolieren.
Beispielstruktur:
class Product { constructor( private readonly id: string, private name: string, private price: number ) {} changePrice(newPrice: number): void { if (newPrice <= 0) { throw new Error("Price must be greater than zero."); } this.price = newPrice; } getDetails() { return { id: this.id, name: this.name, price: this.price }; } }
Bedingte Typen für flexible Modellierung
class Money { constructor(private readonly amount: number, private readonly currency: string) { if (amount < 0) { throw new Error("Amount cannot be negative."); } } add(other: Money): Money { if (this.currency !== other.currency) { throw new Error("Currency mismatch."); } return new Money(this.amount + other.amount, this.currency); } }
Vorlagenliteraltypen für die Validierung
class Order { private items: OrderItem[] = []; constructor(private readonly id: string) {} addItem(product: Product, quantity: number): void { const orderItem = new OrderItem(product, quantity); this.items.push(orderItem); } calculateTotal(): number { return this.items.reduce((total, item) => total + item.getTotalPrice(), 0); } } class OrderItem { constructor(private product: Product, private quantity: number) {} getTotalPrice(): number { return this.product.getDetails().price * this.quantity; } }
Meine persönliche Website: https://shafayet.zya.me
Nun, es zeigt, wie aktiv Sie in Git-Toilette sind...
Das Titelbild wurde mit OgImagemaker von
erstellt
@eddyvinck .Danke Mann, dass du uns dieses Werkzeug geschenkt hast???...
Das obige ist der detaillierte Inhalt vonTypeScript für Domain-Driven Design (DDD). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!