Pat*_*ski 9 c# oop design-patterns return messages
对于多个消息和成功/失败,是否有通知模式的替代方案?
我有一个类OperationResult,我用它来返回一个Success布尔值和一个"错误"消息列表.这些消息有时是意外错误,但更常见的是经常发生的普通情况.有时我们返回单个错误消息,但有时我们返回几个.我希望找到一个更好的方法.
这似乎或多或少是福勒倡导的通知模式.然后,消费者对成功状态和错误做一些合理的事情,通常向用户显示错误,但有时在非致命错误的情况下继续.
因此,我有很多服务方法(不是Web服务方法),看起来像这样:
private ThingRepository _repository;
public OperationResult Update(MyThing thing)
{
var result = new OperationResult() { Success = true };
if (thing.Id == null) {
result.AddError("Could not find ID of the thing update.");
return result;
}
OtherThing original = _repository.GetOtherThing(thing.Id);
if (original == null) return result;
if (AnyPropertyDiffers(thing, original))
{
result.Merge(UpdateThing(thing, original));
}
if (result.Success) result.Merge(UpdateThingChildren(thing));
if (!result.HasChanges) return result;
OperationResult recalcResult = _repository.Recalculate(thing);
if (recalcResult.Success) return result;
result.AddErrors(recalcResult.Errors);
return result;
}
private OperationResult UpdateThing(MyThing ) {...}
private OperationResult UpdateThingChildren(MyThing) {...}
private bool AnyPropertyDiffers(MyThing, OtherThing) {...}
Run Code Online (Sandbox Code Playgroud)
你可以想像,UpdateThing,UpdateThingChildren,并且ThingRepository.Recalculate都具有相似的OperationResult交错与业务逻辑合并/操纵代码.
是否有替代这么多代码在我的返回对象周围?我希望我的代码只关注业务逻辑,而不必特别关注操作OperationResult.
我希望代之以类似下面的代码,更好地表达其业务逻辑,减少消息处理的内容:
public ??? Update(MyThing thing, ???)
{
if (thing.Id == null) return ???;
OtherThing original = _repository.GetOtherThing(thing.originalId);
if (original == null) return ???;
if (AnyPropertyDiffers(thing, original))
{
UpdateThing(thing, original));
}
UpdateThingChildren(thing);
_repository.Recalculate(thing);
return ???;
}
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
注意:抛出异常在这里并不合适,因为消息并不例外.
我认为你的服务没有做一件事。它负责验证输入,然后如果验证成功则更新内容。是的,我同意用户需要尽可能多的有关错误的信息(违规、未提供名称、详细描述、日期开始之前的日期结束等),因为您可以根据单个请求提供尽可能多的信息,并且例外情况不是可行的方法。
在我的项目中,我倾向于将验证和更新的关注点分开,因此执行更新的服务几乎没有失败的机会。另外,我喜欢同时进行验证和更新的策略模式 - 用户请求更改,通用服务接受验证/更新请求,调用特定的验证器/更新器,而验证器/更新器又调用通用服务来验证/更新某些依赖项。通用服务将合并结果并决定操作的成功或失败。明显的好处是,违规消息合并在某个通用类中完成一次,并且特定的验证器/更新器可以专注于单个实体。另一方面,您可能想要验证某些数据库的唯一性或数据库上对象的存在性,这会暴露两个问题:对数据库的额外查询(用于Exist最小化输出的轻型查询,但它是对数据库的访问)以及验证和验证之间的延迟。更新(此时数据库可能会发生变化,并且您的唯一性或存在验证可能会发生变化(这个时间相对较小,但它可能会发生)。这种模式还可以最大限度地减少重复UpdateThingChildren- 当您具有简单的多对多关系时,可以从任一关系更新子级连接实体之一。