假设我们有一个生命周期的集合,这样它就可以在生命周期中改变它的行为。在生命的第一部分,它可以做一些事情;在第二部分,它可以做其他事情。
我想听听关于我们应该如何限制聚合在每个阶段可以做什么的意见。
为了让它更具体一点,让我们以金融贸易为例。
-
交易者创建
贸易
通知合同及其价格。
-
风险经理验证交易,并给出理由。
-
后台可以将交易提交到分类帐,提供会计信息。
-
交易提交后,会计信息不可更改。
贸易显然有三个不同的阶段,我称之为
类型化的
,
已验证
和
提交
我的第一个想法是用
InvalidOperationExceptions
我真的不喜欢:
public class Trade
{
private enum State { Typed, Validated, Submited }
private State _state = State.Typed;
public Guid Id { get; }
public Contract Contract { get; }
public decimal Price { get; }
public Trade (Guid id, Contract contract, decimal price) { ... }
private string _validationReason = null;
private AccountingInformation _accInfo = null;
public void Validate(string reason) {
if (_state != State.Typed)
throw new InvalidOperationException (..)
...
_validationReason = reason;
_state = State.Validated;
}
public string GetValidationReason() {
if (_state == State.Typed)
throw new InvalidOperationException (..)
return _validationReason;
}
public void SubmitToLedger(AccountingInformation info) {
if ((_state != State.Validated))
throw new InvalidOperationException (..)
...
}
public AccountingInfo GetAccountingInfo() { .. }
}
我可以做像
Maybe pattern
,以避免
Get...
方法。但这对行为方法不起作用(
Validate
,
SubmitToLedger
等)
奇怪的是,如果我要研究一种功能性语言(如f),我可能会为每个状态创建不同的类型。
type TypedTrade = { Id : Guid; Contract: Contract; Price : decimal }
type ValidatedTrade = { Id : Guid;
Contract: Contract;
Price : decimal;
ValidationReason : string}
type SubmittedTrade = { Id : Guid;
Contract: Contract;
Price : decimal;
ValidationReason : string;
AccInfo : AccountingInfo }
// TypedTrade -> string -> ValidatedTrade
let validateTrade typedTrade reason =
...
{ Id = typedTrade.Id; Contract = typedTrade.Contract;
Price = typedTrade.Price; Reason = reason }
// ValidatedTrade -> AccountingInfo -> SubmittedTrade
let submitTrade validatedTrade accInfo =
...
{ Id = validatedTrade.Id;
Contract = validatedTrade.Contract;
Price = validatedTrade.Price;
Reason = validatedTrad.Reason;
AccInfo = accInfo }
这个问题会优雅地消失。但要在OO中做到这一点,我必须使聚合不可变,并可能创建某种O层次结构(在其中我必须隐藏基本方法!)?哎呀!).
我只是想知道你们在这些情况下做什么,如果有更好的方法的话。