gpt4 book ai didi

design-patterns - 存储库模式和集合错误处理

转载 作者:行者123 更新时间:2023-12-01 10:03:41 24 4
gpt4 key购买 nike

假设我有存储库:

interface IRepo
{
Foo Get(int id);
void Add(Foo f);
}

现在,要求我只能拥有一个 Foo给定的属性,比如说... Id .显然,如果我实现 IRepo带有一些 SQL 后端并将映射 Foo.Id到主键,我免费得到这样的东西 - 我可能会得到它的某种 PKViolationException .但这正在成为特定于实现的,所以无论我在哪里使用它 IRepo实现并开始捕获这些异常,我正在失去松散耦合的好处。

现在,我将如何解决这个问题?我是否应该添加某种服务层,首先检查对象是否存在,然后抛出一些独立于存储库的异常?
class Service
{
IRepo repo;

public void AddFoo(Foo foo)
{
if(repo.Get(foo.Id) != null)
repo.Add(foo);
else
throw new FooAlreadyExistsException(foo.Id);
}
}

这个解决方案似乎很糟糕,因为 repo.Add(foo)仍然可以抛出一些异常,尤其是在检查之后(通过其他事件)添加了具有给定 ID 的对象时,所以我只是向我的基础架构添加了一个额外的调用,而几乎没有好处。

看来我应该小心并实现 IRepo考虑到这样的异常(在示例 SQL 实现中可以捕获 PKViolationException 并将其转换为 FooAlreadyExistsException),但是要确保每个 IRepo实现遵循这样的规范?

您一般如何解决这些问题?

最佳答案

“看来我应该小心并在考虑到这种异常的情况下实现 IRepo(可以捕获 PKViolationException 并将其转换为 FooAlreadyExistsException 在示例 SQL 实现中)”

你在这个钱上是对的。抛出的异常成为接口(interface)契约的一部分,实现必须遵守这个契约。编译器不会为您强制执行此操作,因此您必须绝对清楚预期。

“但是如何确保每个 IRepo 实现都遵循这样的规范呢?”

作为接口(interface)编写者,您不能对实现它的类负责。如果其他类有缺陷并暴露了泄漏的抽象,那就是它们的缺陷。您所能做的就是绝对清楚您正在定义的契约(Contract)。

存储库的目的是抽象出数据库的实现细节,包括其异常(exception) .因此,您还应该抽象出实现特定的异常......

interface IRepo
{
/// <exception cref="FooAlreadyExistsException">Thrown if the specified Foo object already exists in the database.</exception>
void Add(Foo f);
}

class ConcreteRepo
{
public void Add(Foo f)
{
try
{
// Database stuff...
}
catch (PKViolationException e)
{
throw new FooAlreadyExistsException(e);
}
}
}

关于design-patterns - 存储库模式和集合错误处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13108564/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com