You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DDD架构下Player聚合地址修正的用例设计疑问

回答

Great question—this cuts straight to how DDD ties technical design to real business language and intent. Here's how to approach it:

1. Yes, create a dedicated AdjustPlayerAddress use case

DDD’s rule of using business-aligned use cases isn’t just about avoiding generic UpdateX methods—it’s about making each use case map to a specific, meaningful business action.

  • RelocatePlayerTo represents a deliberate business decision: the player is moving to a new location (think: they just moved apartments, changed cities, etc.).
  • AdjustPlayerAddress represents a distinct scenario: fixing a mistake in an existing address (typo in street name, wrong unit number). These are two different business events with different intent, even if they both modify the address.

If you tried to reuse RelocatePlayerTo for corrections, you’d blur the line between intentional moves and error fixes, making your domain model less expressive and harder to reason about later.

2. Yes, add a PlayerAddressHasBeenAdjusted domain event

Domain events should mirror the business actions they represent, just like use cases. Here’s why this matters:

  • Downstream systems might react differently to each event:
    • A PlayerRelocated event could trigger logistics updates (e.g., re-routing ongoing shipments).
    • A PlayerAddressHasBeenAdjusted event might trigger error logging, a notification to customer support to verify the correction, or a request to amend a previously sent shipment.
  • Tracking these events separately gives you auditability: you can easily see when a player moved vs. when an address was fixed, which is critical for compliance or business analytics.

Example implementation snippets

To make this concrete, here’s how you might structure the use case and event (using C#-style pseudocode):

AdjustPlayerAddress Use Case

public class AdjustPlayerAddressUseCase
{
    private readonly IPlayerRepository _playerRepo;
    private readonly IDomainEventPublisher _eventPublisher;

    public AdjustPlayerAddressUseCase(IPlayerRepository playerRepo, IDomainEventPublisher publisher)
    {
        _playerRepo = playerRepo;
        _eventPublisher = publisher;
    }

    public async Task Execute(Guid playerId, Address correctedAddress, string correctionReason = null)
    {
        var player = await _playerRepo.GetById(playerId);
        // Encapsulate business rules for address correction in the aggregate
        player.AdjustAddress(correctedAddress, correctionReason);
        await _playerRepo.Save(player);
        _eventPublisher.Publish(new PlayerAddressHasBeenAdjusted(playerId, correctedAddress, correctionReason));
    }
}

Player Aggregate Method

public class Player : AggregateRoot
{
    public Address CurrentAddress { get; private set; }
    private List<AddressCorrection> AddressCorrections { get; } = new();

    // ... other properties and methods ...

    public void AdjustAddress(Address correctedAddress, string correctionReason)
    {
        // Add business rules here: e.g., ensure correction is meaningful, validate new address format
        if (correctedAddress.Equals(CurrentAddress))
            throw new InvalidOperationException("Corrected address matches current address");
        
        CurrentAddress = correctedAddress;
        // Track correction history directly in the aggregate for auditability
        AddressCorrections.Add(new AddressCorrection(DateTime.UtcNow, correctionReason, correctedAddress));
    }
}

Domain Event

public record PlayerAddressHasBeenAdjusted(
    Guid PlayerId, 
    Address CorrectedAddress, 
    string? CorrectionReason) : IDomainEvent;

Edge case to consider

If your business truly doesn’t distinguish between intentional moves and error fixes (e.g., every address change is just a "update" with no separate business process), you could argue for reusing the existing use case—but this is rare. Most businesses care about why an address changed, and DDD’s strength is capturing those nuances.

Always align your design with the language your business team uses. If they say "fix the player’s address" instead of "relocate the player again," your use cases should reflect that.

内容的提问来源于stack exchange,提问作者DmitriBodiu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:20:36