长时间运行的有状态'services'适合 DDD 中的什么位置?



在更多与行业或自动化相关的应用程序中(这些应用程序大多严重依赖于它们必须管理的外部组件),您通常会发现域中包含的模型不仅是对实际问题的抽象,而且是对域外物理存在的事物的表示和指针。

例如,以表示网络设备的域实体为例:

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

应用程序可能需要基于域内的外部组件表示来管理外部组件,而不仅仅是存储或验证此类实体或对实体更改采取操作。现在,DDD是否适合这种情况?这些管理员是域服务吗?

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

一个简单的例子:应用程序需要监视网络配置的IP设备,以便向域内的其他应用程序通知状态事件。如果一个IP设备在应用程序中注册(例如存储在数据库中),"ping服务"就会收到通知并开始监视该设备。

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));
}
}
}

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

现在,这些组件是什么?起初我认为它们是域服务,因为它们服务于域的特定需求。然而,它们是有状态的,并且没有专门表示泛在语言(ping服务的任务是ping域实体并报告其状态,但是

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

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

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

我曾经实现过一个类似的函数,希望它能有所帮助:)

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

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

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());
}
}

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

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();
}

正如您可能看到的,应用程序服务和域服务现在都是无状态的。

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

最新更新