5

在更多与行业或自动化相关的应用程序(主要依赖于他们必须管理的外部组件)中,您通常会遇到这样的情况,即域包含的模型不仅仅是对实际问题的抽象,还有表示of 和指向物理上存在于域之外的东西的指针。

例如,以这个代表网络设备的域实体为例:

public class NetworkDevice {
   public IPAddress IpAddress { get; set; }
}

应用程序可能需要根据外部组件在域内的表示来管理外部组件,而不是仅仅存储或验证此类实体或对实体更改采取行动。现在,DDD 甚至适用于这种情况吗?那些经理是域服务吗?

Eric Evans 在他著名的蓝皮书中描述了域服务需要是一个无状态 模型,实现从ubiquitos 语言中获取的方法,以完成实体或存储库无法自行处理的请求。但是如果服务需要有状态怎么办?

一个简单的例子:应用程序需要监视网络中配置的 IP 设备,以便通知域内的其他应用程序有关状态事件的信息。如果 IP 设备在应用程序中注册(例如存储在数据库中),“ping-service”会收到通知并开始监控设备。

public class PingMonitor : IDisposable,
   IHandle<DeviceRegisteredEvent>,
   IHandle<DeviceRemovedEvent> 
{

    public List<NetworkDevice> _devices = new List<NetworkDevice>();

    public void Handle(DeviceRegisteredEvent @event) {
        _devices.Add(@event.Device);
    }

    public void Handle(DeviceRemovedEvent @event) {
        _devices.Remove(@event.Device);
    }

    public void PingWorker() {
        foreach(var device in _devices) {
            var status = Ping(device.IpAddress);
            if(status != statusBefore)
                DomainEvents.Raise<DeviceStateEvent>(new DeviceStateEvent(device, status));
        }
    }

}

然后其他组件可以处理这些状态事件,例如,如果设备离线,则停止通过其他协议与设备对话。

现在,这些组件是什么?起初我认为它们是域服务,因为它们服务于域的某种需求。但是,它们是有状态的,并且不具体代表ubiquitos 语言ping 服务的任务是ping域实体并报告其状态,但是ping 服务没有实现客户端允许 ping 的方法一个装置)。

它们是应用服务吗?这些组件在 DDD 模式中的什么位置?

4

2 回答 2

2

在 DDD 中,一个长时间运行的进程称为Saga。它通常使用领域事件来实现。

以下是对该主题的一些介绍:http: //abdullin.com/journal/2010/9/26/theory-of-cqrs-command-handlers-sagas-ars-and-event-subscrip.html/

于 2014-03-07T13:31:03.310 回答
1

我曾经实现过类似的功能,希望对您有所帮助:)

我们的组织拥有一个在线支付处理应用程序。一旦客户完成支付,在线支付提供商就会向用户发送指示成功或失败的通知。有时会发生网络故障,通知可能永远不会到达我们的应用程序。因此,心怀不满的顾客来了。所以需要一个自动检查机制。

应用程序运行器负责保持检查运行:

public class CheckingBatch {
    private TransactionChecker transactionChecker;

    public void run() {
        List<Transaction> transactions = transactionsToBeChecked();
        for (Transaction transaction : transactions) {
                //publish events if the transaction needs check
                doCheck(transaction, now);                }
        } 
    }

    private List<Transaction> transactionsToBeChecked() {
         return transactionRepository.findBy(transactionChecker
            .aToBeCheckedSpec());
    }
}

另一个应用程序服务监听事件并进行实际检查:

public class CheckTransactionServiceImpl implements CheckTransactionService {
    private TransactionChecker transactionChecker;

    @Transactional
    public void check(final TransactionNo transactionNo) {
        Transaction transaction = transactionRepository.find(transactionNo);
        CheckResult result = transactionChecker.check(transaction);
        //handle check result
    }
}

TransactionCheck 是一个与在线支付解决方案无关的域服务:

public interface TransactionChecker {
/**
 * 
 * | data between online-payment provider and ours | txn STATUS | RESULT |<br>
 * | consistent | CLOSED | VALID |<br>
 * | inconsistent | CLOSED | INVALID |<br>
 * others omitted
 */
    CheckResult check(Transaction transaction);
/**
 * returns txn specification to filter to be checked ones.
 */
    ToBeCheckedSpecification aToBeCheckedSpec();
}

如您所见,应用程序服务和域服务现在都是无状态的。

恕我直言,Ping 是域服务(与 TxnChecker 相关),但监视器是一种应用程序服务(与 CheckingBatch 相关)。

于 2014-03-06T10:24:34.357 回答