Liskov替换原则和冗余方法

时间:2013-07-31 09:01:24

标签: c# design-patterns solid-principles liskov-substitution-principle

我有一个名为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();

然后我有一个实现此接口的类。该类实际上使用Entity Framework来实现这些方法。然而,方法更新是多余的,因为实体框架跟踪对检索到的实体所做的更改,因此我只获得我想要的实体,更新它然后调用SaveChanges。但是在将来,我可能想用其他东西替换IRepository的这个具体实现。这可能不会像Entity框架那样跟踪更改。所以我想我想在接口中保留更新方法,但是在我对这个接口的具体实现中,只需保留方法但什么都不做。 e.g。

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

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

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

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

2 个答案:

答案 0 :(得分:2)

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

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

这可能不是你想要的,但你明白了......

答案 1 :(得分:1)

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

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

相关问题