Maison >interface Web >js tutoriel >TypeScript pour la conception basée sur le domaine (DDD)
Domain-Driven Design (DDD) est une approche puissante pour aborder les systèmes logiciels complexes en se concentrant sur le domaine métier principal et sa logique associée. TypeScript, avec sa frappe puissante et ses fonctionnalités modernes, est un excellent outil pour mettre en œuvre efficacement les concepts DDD. Cet article explore la synergie entre TypeScript et DDD, offrant des informations pratiques, des stratégies et des exemples pour combler le fossé entre la conception et le code.
Concepts de base
1. Langue omniprésente
Collaboration entre développeurs et experts du domaine utilisant un langage partagé pour réduire les problèmes de communication.
2. Contextes délimités
Séparation claire des différentes parties du domaine, garantissant autonomie et clarté dans des contextes spécifiques.
3. Entités et objets de valeur
4. Granulats
Clusters d'objets de domaine traités comme une seule unité pour les modifications de données.
5. Dépôts
Résume la logique de persistance, donnant accès aux agrégats.
6. Événements de domaine
Signaux émis lorsque des actions significatives se produisent au sein du domaine.
7. Services applicatifs
Encapsulez les flux de travail métier et la logique d'orchestration.
1. Typage statique : Une vérification de type forte permet de modéliser explicitement la logique du domaine.
2. Interfaces : Appliquer les contrats entre les composants.
3. Classes : Représentent naturellement les entités, les objets de valeur et les agrégats.
4. Type Guards : Assurer la sécurité du type au moment de l'exécution.
5. Types d'utilitaires : Activez des transformations de type puissantes pour les domaines dynamiques.
1. Entités de modélisation
Les entités ont des identités uniques et encapsulent le comportement.
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. Créer des objets de valeur
Les objets de valeur sont immuables et comparés par valeur.
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. Définir des agrégats
Les agrégats garantissent la cohérence des données au sein d'une limite.
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. Implémentation de référentiels
Accès aux données abstraites des référentiels.
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. Utilisation des événements de domaine
Les événements de domaine informent le système des changements d'état.
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. Services applicatifs
Les services d'application coordonnent les flux de travail et appliquent les cas d'utilisation.
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 } }
Exploitez les capacités modulaires de TypeScript pour isoler les contextes délimités.
Exemple de structure :
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 }; } }
Types conditionnels pour une modélisation flexible
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); } }
Types de littéraux de modèles pour la validation
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; } }
Mon site personnel : https://shafayet.zya.me
Eh bien, cela montre à quel point vous êtes actif dans Git-toilet...
L'image de couverture a été réalisée à l'aide d'OgImagemaker par
@eddyvinck .Merci mec de nous avoir offert cet outil ???...
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!