0

我有一个名为 IRepository 的接口。该接口定义了一组通用方法,例如:

 IQueryable<T> Get<T>() where T : class;
 void Add<T>(T obj) where T : class;
 void Update<T>(T obj) where T : class;
 void SaveChanges();

然后我有一个实现这个接口的类。这个类实际上使用实体框架来实现这些方法。然而,方法更新是多余的,因为实体框架会跟踪对检索到的实体所做的更改,所以我只需获取我想要的实体,更新它然后调用 SaveChanges。但是,将来我可能想用其他东西替换 IRepository 的这个具体实现。这可能不会像实体框架那样跟踪变化。所以我想我想把更新方法留在接口中,但是在我这个接口的具体实现中,只是把方法留在里面,但什么也不做。例如

public void Update<T>(T obj) where T : class
{
}

这似乎符合 Liskov 替换原则,我可以用其他东西替换接口的实现。只是有些东西可能不需要实际实现接口上定义的所有方法。

这是一个好方法吗。我在想这没关系,甚至可能在 IRepository 的实现中将该方法标记为已过时,说明为什么它在此实现中已过时。

拥有一个什么都不做的更新方法并在整个应用程序中调用它似乎有点奇怪,即使它实际上并没有做任何事情。但是,如果我们将 IRepository 的实现更改为确实需要更新方法的实现,那么我们可以将其替换为不需要更改代码。

4

2 回答 2

2

恕我直言,在大多数情况下未实现的接口上有一个方法告诉我接口的范围太宽了。

您可以从基本存储库接口中删除更新方法,并将其单独添加到从基本接口继承的 IUpdatableRepository。然后,您需要更新的具体类可以实现 IUpdatableRepository 接口。

这可能不是您想要的,但您明白了……

于 2013-07-31T09:13:01.510 回答
1

如果我对您的理解正确,那么您有一个已包装在接口中的实现。LSP 并不是设计中唯一需要担心的事情:我认为KISSYAGNI更为基础,而 LSP 只是在面向对象设计中保持事情简单和可预测的一种方式。尝试为系统中任何可以想象的未来变化进行设计实际上会使您的系统由于复杂性增加而更难更改。您是否有可能用需要 Update 方法的替代实现替换您的存储库?然后无论如何,保留它。如果这只是一种可能,请立即将其删除(并且可能考虑直接使用 EF)。

毕竟,“你可以通过添加另一层抽象来解决所有问题,除了太多的抽象层。”

于 2013-07-31T09:19:47.760 回答